-
Notifications
You must be signed in to change notification settings - Fork 24.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RN 0.57.x Bundled large images have low quality when viewing using <Image/> component with 1:1 AR on Android #21301
Comments
After converting the PNG image to JPG, it renders just fine in full quality. Digging a little bit further, and reading about resizing mode at http://frescolib.org/docs/resizing.html, I read that resizing method has a limitation:
I don't know if this is related with PNG, but it works using PNG images in RN 0.56.0. |
@clytras I have same issue with remote images. /CC: @DylanVann |
@mnlbox did you find any fix for this issue? I am still stuck with RN 0.56 for now just because of this issue. The sad thing is that noone replies which makes me think this might be a missconfiguration or something related. I also have opened a SO question about this issue with irrelevant answears unfortunately. EDIT |
I can confirm this change happen on my app as well, when updated to 0.57.8 and that it happen on 3rd part library like react-native-photo-view |
same issue |
I'm also seeing this issue in an application I'm working on. Using the RN This bug does not occur on iOS. On Android, when I downgrade the app to React Native v.0.56, this bug also does not occur. |
same issue with RN 0.57.1 on Android |
Any plan to fix this? It's really annoying 😞 |
This bug still exists in RN 0.59.0 and of course in the previous versions RN 0.58.x. |
also in 0.59.1 |
@callcter there are some workarounds to this one like using a WebView or FastImage component or to replace the PNG image with an other format like JPG. This is a bug/issue started with RN 0.57.0 when then added a new metro bundler version/features. Best guess is that the bundler fetches a smaller/compressed/resized version of the image which is related to Fesco lib, the library that RN uses to handle images for Android. |
FastImage is related to Glide and with error: |
also in 0.59.3 |
@cpojer Any plan to fix this? |
react-native-fast-image v4.0.14 works fine but since v5.x it is broken. |
react-native 0.59.5 encounter the same issue with local and remote .jpg images too 😂 |
react-native-fast-image v5.3.0 works for me 😂 |
@glacjay FastImage does not support local bundled images: DylanVann/react-native-fast-image#248 |
@clytras fortunately (or unfortunately) our projects doesn't use local bundled images 😂 so react-native-fast-image should be enough for me ... except that I need to change A LOT OF Images by FastImages 😂 |
Hey, this is Daniel from the Fresco team. From the initial issue description it seems that the behaviour changed between 0.56.0 (June 2018) and 0.57.1 (Sep 2018). During this time the dependency of Fresco wasn't upgraded in For debugging, it would suggest to enable logging to logcat here: react-native/ReactAndroid/src/main/java/com/facebook/react/modules/fresco/FrescoModule.java Lines 96 to 114 in 8d5ac8d
You can follow https://frescolib.org/docs/listening-to-events.html under RequestListener on how to register the |
@valery-lavrik Hello, did you manage to find a solution to your problem? I'm having the same problem as you, trying to render an image with a large height, but it doesn't get the right size. |
@tarcisioandrade |
@valery-lavrik Does this code cut the large image into pieces? That's the kind of image I'm trying to render. |
@tarcisioandrade There are a lot of very large images in this comic book reader. I often have to cut them into pieces |
@valery-lavrik |
@tarcisioandrade The option with rendering in webview does not suit me because I need to specify headers to upload images. |
How is this STILL a problem???? I can't convert to jpg because I need the alpha channel |
This is a result of using the Fresco image library under the hood, and I tried to provide some customization for this in #44803. Lemmie try to dive in and provide some context. Some backgroundThere are two problems afoot that have been smashed into one here: one is the result of aliasing issues (as is the case in the example provided here) and the other is the general blurriness that people see when using a particular prop React Native has a prop on Android,
Let me place emphasis on this part: if the image is more than 2 times bigger than the view (in total number of pixels, i.e. width*height), you should resize it There are three When you apply the There's a technique of resizing that Fresco can apply called downsampling. Rather than taking a power of 2, it can take a multiple of 2. This technique is only applied to JPG images, hence you see slightly better results from JPG in examples like this. Calling back to our previous example, our source dimensions of 1000x1000 can be scaled down 6x to 167x167 (Fresco rounds up). Rather than using 250x250, the resultant dimensions of 167x167 are much closer to the desired 150x150. Finding a(n imperfect) solutionI've tried to remain concise on what React Native is doing, but you're probably more interested in how to fix this. Fresco isn't a perfect solution here. It applies really basic mechanisms for resizing and scaling images on the client that aren't perfect for every use case. First and foremost, I highly recommend producing images as close as possible to the destination sizing. If you can convert your 1000x1000 image to 150x150 ahead of time, this is less work for every client. It's important to recognize that different devices have different pixel densities, so on higher-end devices that 150x150 is actually 300x300 or 450x450. This is why React Native supports the If you're going to render images served from the network, try fetching them in your desired destination resolution too. You can determine the "true" resolution of an image using React Native's If you still want the device to do resizing for you, but your resultant images are blurry, you can tweak the quality of the image with a bit more Fresco customization. Apply a combination of Every use-case is different, every solution is different. It's important to find the best solution for your needs. Resizing on the client every time is computationally expensive, but resizing once ahead of build-time is quick. Hope this helps a bit! |
@Abbondanzo there are so many use cases that people want to use the original and actual size of the image, like when creating an interactive map (without messing with tiles hell etc.), zooming images without loosing quality, game and parallax backgrounds and the list can get bigger. IMO it's not a good thing for a library or a framework to enforece such optimizations without giving the option to the devs to eliminate such configurations and behaviours.
I'd argue that, I believe Fresco is a very good image processing library for Android and it does a good job, IMO it's that it should allow people to customize using options when using optimizations and opinionated techniques. |
Downsampling should have been a new
Fresco is a great image processing library but not one-size-fits-all in every case. It does a decent job at rendering images provided a dimension but isn't designed to service some of the use cases you've provided, particularly in conjunction with the limitations set by ReactImageView. There's a higher incentive to craft assets fitted to exact uses, across multiple dimensions (and part of the reason why the I'd love to open it up for further customization, and I'm all ears for ideas. The |
Exactly, and that's why it can't work using
You are missing the point of consistency. The behaviour on iOS is different. This issue does not happen on iOS when using the RN stock The assets and images may be bundled inside the app, and I agree with you that large image sizes should be avoided, but if the use cases need such assets, then the platform must easily allow the developers to use such big assets, which wasn't the case here.
Unfortunately that is not the case for image downsabling. We cannot alter that configuration using
I think you are wrong here. RN does have dozens of platform specific component properties (to name some |
iOS does its own downsampling too (source), so I believe that the intention was to bring Android's performance and approach to image rasterization inline with iOS here. It's just that downsampling isn't working as initially intended. Being prescriptive of optimizations or enhancements clearly didn't work in this case, so until that gap can be closed, it's best to disable the behavior and make it opt-in.
The 3.2.0 version of Fresco has a new flag to disable downsampling outright, thanks to @sunnylqm's work. It can be manually configured if you wanted to set up your own pipeline config in the application, in the same spot you'd normally build the auto-generated
Yep, and those are all useful for their various purposes, but the pipeline config is created while the React Native Host is being spun up. It's not something that can be tweaked on a per-image basis, that's where the |
I don't doubt that it does, but the images don't get any visual transformation at all, so here relies the issue with Android and iOS inconsistency. What you see in my OP of this issue does not happen on iOS.
Yes, after almost 6 years, in 3.2.0 after @sunnylqm fixed it; providing custom configuration for the ImagePipeline might work, but we didn't have had that back then when this issue appeared, we could not bypass this behavior easily just using configuration, that's my point. - if (downsampleEnabled || !statusHasFlag(status, IS_RESIZING_DONE)) {
I know that and I already have agreed with you but still you seem to ignore this:
Look @Abbondanzo, you discovered this issue recently and I appreciate the fact that you are eager to help as we all want that issue to be resolved, but keep in mind that we were here "fighting" for this 6 years ago and along those years passed we've done some progress. This was an issue. Meta closed this issue back in 2019 because they said it was Fresco's issue regarding not handling the props #21301 (comment). Fresco team kept the issue opened until @sunnylqm commited some fixes that are based on some proposals like this facebook/fresco#2500 (comment). This means that they recognize this was indeed an issue and we now have better and easier ways to overcome this behavior. |
Unbelievable to see multi billion sh** company unable to handle a 6 years old bug affecting millions of users. So easy to transfer respo to third party as usual... |
Summary: ## Summary Adds a new `resizeMethod` called `never`. It disables downsampling on the image request and disregards the global image pipeline default. This has been a pain point raised when rendering large images on Android in issues like [this one](facebook#21301) and [this one](facebook/fresco#2397). ## Changelog [Android][Added] - Adds a new `resizeMethod`, `never`, which disables downsampling for an image Differential Revision: D62393211
…book#46866) Summary: ## Summary Adds a new `resizeMethod` called `none`. It disables downsampling on the image request and disregards the global image pipeline default. This has been a pain point raised when rendering large images on Android in issues like [this one](facebook#21301) and [this one](facebook/fresco#2397). ## Changelog [Android][Added] - Adds a new `resizeMethod`, `none`, which disables downsampling for an image Reviewed By: yungsters Differential Revision: D62393211
Summary: Pull Request resolved: #46866 ## Summary Adds a new `resizeMethod` called `none`. It disables downsampling on the image request and disregards the global image pipeline default. This has been a pain point raised when rendering large images on Android in issues like [this one](#21301) and [this one](facebook/fresco#2397). ## Changelog [Android][Added] - Adds a new `resizeMethod`, `none`, which disables downsampling for an image Reviewed By: yungsters Differential Revision: D62393211 fbshipit-source-id: d85e3ed098ad502c8edbdfa817c841271ee9e914
x-posting my update from #45078
|
Thank you @Abbondanzo for diving into this issue and providing such a nice solution 🔥 |
You can't imagine how long I've been waiting for this! how much shit code did I have to write because of this)))) |
WOOW, Now I don't have to cut my images to pieces anymore 😂 |
Just found that the day @clytras raised the issue was exactly the day my second girl was born. no kidding she is in primary 1 now 🤣 |
Environment
React Native Environment Info:
System:
OS: macOS High Sierra 10.13.6
CPU: x64 Intel(R) Core(TM) i7 CPU 920 @ 2.67GHz
Memory: 111.21 MB / 12.00 GB
Shell: 3.2.57 - /bin/bash
Binaries:
Node: 10.9.0 - /usr/local/bin/node
Yarn: 1.9.2 - /usr/local/bin/yarn
npm: 6.2.0 - /usr/local/bin/npm
Watchman: 4.9.0 - /usr/local/bin/watchman
SDKs:
iOS SDK:
Platforms: iOS 11.4, macOS 10.13, tvOS 11.4, watchOS 4.3
IDEs:
Android Studio: 3.1 AI-173.4907809
Xcode: 9.4.1/9F2000 - /usr/bin/xcodebuild
npmPackages:
react: 16.5.0 => 16.5.0
react-native: 0.57.1 => 0.57.1
Description
There is really low quality when loading large bundled images even when using
resizeMethod="resize"
. This happens only on Android, not on any iOS simulator/device. Have tested it on Android 8.1 emulator and LG G6 with Android 8.0. Please see the screenshots bellow.At the left screenshot we see the exact same code running with RN 0.56.0 and at the right screenshot we see RN 0.57.1. The code is just a simple image
<Image source={require('./assets/ELHall1.png')} resizeMethod="resize" />
and the image size is2111 x 4645 pixels
. Both projects are fresh installed usingreact-native init RN057ImageTest
andreact-native init --version="0.56.0" RN056ImageTest
Reproducible Demo
It's the initial
App.js
with the<Text/>
components commented and an<Image/>
component added.The text was updated successfully, but these errors were encountered: