fresco icon indicating copy to clipboard operation
fresco copied to clipboard

[Android][react-native] incorrect image width and height - CloseableImage getWidth/getHeight

Open Fsarmento opened this issue 5 years ago • 8 comments

Description

On react native, Image.getSize() uses Fresco (here) to return the width and height of a given image.

As explaned in this react-native issue (https://github.com/facebook/react-native/issues/22145), the returned width and height are inconsistent in Android. The ratio between width and height is correct, but the values of width and height are not.

Reproduction

See example in https://github.com/facebook/react-native/issues/22145

Additional Information

react: 16.5.0 => 16.5.0 react-native: 0.57.1 => 0.57.1

  • Fresco version: com.facebook.fresco:fresco-1.10.0
  • Platform version: Android 6.0.1 (One plus One); Android 7.0 (Huawei MediaPad T3 10);

Fsarmento avatar Nov 06 '18 12:11 Fsarmento

Hi @Fsarmento

Thanks for reporting this. @oprisnik - do you have any idea what might be behind this issue?

erikandre avatar Nov 07 '18 15:11 erikandre

My best guess would be that your RN setup is using downsampling to downsample images. Fresco reports the size of the decoded bitmap, which in this case would be the downsampled image. In your case, it looks like a downsampling factor of 2 was applied. IMO, this is the correct thing to return here.

@Fsarmento, can you check if downsampling is indeed enabled for your app (see https://frescolib.org/docs/resizing.html)? Disabling it should give you the correct dimensions.

oprisnik avatar Nov 07 '18 15:11 oprisnik

Hi @oprisnik. According to your link, downsampling is enabled with .setDownsampleEnabled(true).

I looked in my whole app and in react-native repository and this method is only called in one place, here, and is set to false.

I know that Image component in react-native have the option to select the resize method. From what I looked, downsampling is set by calling setResizeOptions. This is only used in ReactImageView.java , which is not used by Image.getSize.

Fsarmento avatar Nov 07 '18 17:11 Fsarmento

Does this only happen for huge images? If so, we are automatically downsampling huge images (I think right now > 2048 px). However, this is configurable since ed5c07595678010570a03d0118ecd80850c68d61 and can be adjusted to whatever you like.

You can raise the limit (and it might crash on some devices that can't handle huge bitmaps).

Otherwise, you can get the EncodedImage, which should give you the original image dimensions (which could be different to the decoded bitmap dimensions as you've noticed).

oprisnik avatar Nov 14 '18 15:11 oprisnik

@oprisnik I think you can close this issue, as the downsampling seems to be the cause and the downsampled value is more useful for layout concerns. People are ending up on facebook/react-native#22145 because they want to use Image.getSize for image processing after taking an image from a camera. The reason this is even used by people is this bug on the react-native-camera repo which returns the captured image size, but with a delay: https://github.com/react-native-community/react-native-camera/issues/768

In short IMO, won't fix on React Native and not a bug for Fresco. Thanks for your help.

bartolkaruza avatar Dec 29 '18 06:12 bartolkaruza

Did something change in 0.57 related to this. Seems like a regression / huge change not mentioned in release notes? See https://github.com/facebook/react-native/issues/22145#issuecomment-451117711

leighman avatar Jan 03 '19 11:01 leighman

If you are using Expo, then you can use ImageManipulator.manipulateAsync to flip the image and get the REAL image size. https://docs.expo.io/versions/v36.0.0/sdk/imagemanipulator/

AInoob avatar Feb 04 '20 07:02 AInoob

That's a very old issue but it's still happening (see https://github.com/laurent22/joplin/issues/8856). Specifically, a user gave us this image, which is 4348 × 3251 pixels but incorrectly detected as 1087 x 813 pixels:

20230909_190715.jpg.zip

Is there any plan to fix this?

laurent22 avatar Sep 25 '23 14:09 laurent22