React Native - How to get image size (width and height) from device storage? - react-native

I have a react native project built on expo.
I need to view an image on screen with a style that is based on the width and height of that image.
How can I get the width and height of that image?
let's say the image uri is file:///storage/emulated/0/WhatsApp/Media/WhatsApp%20Images/IMG-20200117-WA0019.jpg
A solution with a code sample is highly appreciated..

React Native Image provide getSize() to get the size of remote images.
Image.getSize('uri', (width, height) => {
this.setState({ width, height });
});
For local images you can use resolveAssetSource()
Image.resolveAssetSource(source).width
Image.resolveAssetSource(source).height
Hope this helps you. Feel free for doubts.

Related

React native zoomable scale not work in ios?

I am using react-native-photo-view-ex library to zoom in and out the images. After zooming the image I am getting scale size from onScale callback function.After than I saved this picture and when I want to open saved image again for re-edit with same scale size as I saved the image displayed very small.I adjust minZoom = 0.5 and maxZoom = 10.
This code works perfectly in android and when open images for re-edit in android image displayed on accurate position with given scale. Also I have implemented this feature with gesture handler and ScrollView Zoomable but get same results. Can anyone help me?
<PhotoView
source={{uri: selectedData.url}}
scale={imageScale}
minimumZoomScale={0.5}
maximumZoomScale={10}
onScale={e => {
setImage(e.nativeEvent.scale);
}}
onLoad={() => setImageScale(selectedData.scale, false)}
style={
styles.resizeImageWrapper
}
/>

React Native: Get current height and width of Image in 'ImageBackground' after resize mode ''contain" is applied

I am selecting an image from gallery and loading it into ImageBackground(which have fixed height and width) in react native and resizeMode "Contain" is applied on that,
I would like to able to know the current height and width of the image when resizeMode is applied .
Thanks

React Native view scaling

So I'm developing a cross platform React Native app, the app is using allot of images as buttons as per design requirements that need to be given an initial height and width so that their aspect ratios are correct. From there I've built components that use these image buttons and then placed those components on the main screen. I can get things to look perfect on one screen by using tops and lefts/ rights to get the components positioned according to the design requirements that I've been given.
The problem I'm running into is now scaling this main screen for different screen sizes. I'm basically scaling the x and y via the transform property on the parent most view as such. transform: [{ scaleX: .8 }, { scaleY: .8 }] After writing a scaling function that accounts for a base height and current height this approach works for the actual size of things but my positioning is all screwy.
I know I'm going about this wrong and am starting to think that i need to rethink my approach but am stumped on how to get these components positioned correctly on each screen without having to hard code it.
Is there any way to position a view using tops and lefts/rights, lock that in place, then scale it more like an image?
First of all, try using flex as far as you can. Then when you need extra scaling for inner parts for example, you can use scale functions. I have been using a scale function based on the screen size and the pixel density, and works almost flawless so far.
import { Dimensions } from "react-native";
const { width, height } = Dimensions.get("window");
//Guideline sizes are based on standard ~5" screen mobile device
const guidelineBaseWidth = 350;
const guidelineBaseHeight = 680;
const screenSize = Math.sqrt(width * height) / 100;
const scale = size => (width / guidelineBaseWidth) * size;
const verticalScale = size => (height / guidelineBaseHeight) * size;
const moderateScale = (size, factor = 0.5) =>
size + (scale(size) - size) * factor;
export { scale, verticalScale, moderateScale, screenSize };
Then you can import these and use in your components. There are different types of scales, you can try and see the best one for your components.Hope that helps.
I ended up going through each view and converting everything that was using a hard coded height and width pixel to setting the width and then using the property aspectRatio and giving that the hard coded height and widths. That along with implementing a scaling function that gave me a fraction of the largest view, so say .9, and then scaling the main view using transform. People arent kidding when they say this responsive ui stuff is tough.
2022 update -
I resolved this problem on my next app by using flex everywhere & a function called rem that I use everywhere that needs a fixed pixel count. With this I can set the width on an image and define an aspect ratio based on the images original dimensions and get an image that scales to the screen size, it's been super reliable.
static width = Dimensions.get("window").width;
static height = Dimensions.get("window").height;
static orientation = 'PORTRAIT';
static maxWidth = 428;
static rem = size => {
let divisor = window.lockedToPortrait || Styles.orientation === 'PORTRAIT' ? Styles.width : Styles.height;
return Math.floor(size * (divisor / Styles.maxWidth))
};
The maxWidth is a predefined value from the largest device I could find to simulate which was probably an iPhone max.

Can't get the size of a local image

I'm trying to get the height of a local image to scale it on React-Native. I tried the following code but I get Failed to get size for image: ../../images/body.png error.
scaleImg(h) {
Image.getSize('../../images/body.png', (width, height) => {
const scaleFactor = height / h
const imageWidth = width / scaleFactor
this.setState({imgWidth: imageWidth, imgHeight: h})
})
}
I'm late to the party, but there's still no answer. For local assets you gotta use Image.resolveAssetSource(require('./path')); instead.
As per the documentation, you can't use Image.getSize on static image resources, which is what your path seems to link to.
static getSize(uri: string, success: function, failure?: function):
Retrieve the width and height (in pixels) of an image prior to
displaying it. This method can fail if the image cannot be found, or
fails to download.
In order to retrieve the image dimensions, the image may first need to
be loaded or downloaded, after which it will be cached. This means
that in principle you could use this method to preload images, however
it is not optimized for that purpose, and may in future be implemented
in a way that does not fully load/download the image data. A proper,
supported way to preload images will be provided as a separate API.
Does not work for static image resources.

How to make React-Native "scrollTo" behave identically on Android than on iOS when ScrollView is small

Consider this simple ScrollView.
On iOS, clicking on the text will but the text to the top because scrollTo({ y: 250 }) scrolls even if end of scrollView is reached.
On Android, the text doesn't move.
How to get on Android the same behavior we have on iOS?
You can work around this by adding padding to the contentContainerStyle of the ScrollView. A good starting point would be to add padding equal to the height of the device's screen.
import { Dimensions } from 'react-native';
const ANDROID_SCREEN_HEIGHT_PADDING = Dimensions.get('window').height;
then, when rendering:
<ScrollView
contentContainerStyle={{paddingBottom: ANDROID_SCREEN_HEIGHT_PADDING}}>
...
</ScrollView>
You could use this for necessary extra Android padding in every direction. If you are using horizontal={true}, for example, you could add padding equal to the width of the screen and add it to the paddingLeft style property to get the intended scrolling behavior on Android.
This behavior is due to the underlying implementation of ScrollView on Android in React-Native. See also:
React native Android ScrollView scrollTo not working