-
Notifications
You must be signed in to change notification settings - Fork 24.3k
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
[Android] Fail to render a large image #10470
Comments
Hi, |
Yes. From looking at the source code, RN uses fresco to not load large images in memory for Image components' resizeMode. In this case, I assume that's not enough because the initial image is so big and I should resize it myself before trying to render it. I would appreciate any advice/suggestion! |
I mean, at some point this is expected, right? - there's only so large of an image that you will be able to display before running out of memory. I think you just have to plan to display a thumbnail rather than a whole image if the image is large enough. That's how the underlying Image class in Android works so I think you would have this same problem even if you were not using React Native. |
I'm running into this too, and the images aren't crazy large at all, about 1000x1300. The main issue is that it works on some devices but not others (and always works on iOS), but the onError handler is never invoked when it fails to render, just a blank box remains. This means that we cannot have a graceful fallback to load a less detailed image - a thumbnail in my case is not sufficient since the entire purpose of the app is to display large images. Can at least the onError be made work properly? |
Making |
Unlikely to happen soon - I'm on Parental Leave until Jan, and my knowledge of Android is basically nil :-) But this is what we have an awesome team in MPK for, I'm sure someone like Tim Yung could knock this out in ten minutes ;-) |
I've looked into this a bit, and it appears to be a widespread issue in the Android community. The most promising doc I found is https://developer.android.com/training/displaying-bitmaps/load-bitmap.html , which suggests using the "inSampleSize" options when using the BitmapFactory to load an image. Unfortunately it looks like RN uses FBs own Fresco library to load it, which doesn't appear to use BitmapFactory, as best as I can quickly see. Any thoughts on how to proceed? This is really a bad problem, any app that wants to show a gallery of non blurry, downsampled images is basically impossible. |
I'm excited that you are investigating this during your parental leave ;-) Maybe @mkonicek has an idea for how to proceed here. |
My guess is that it's related to these lines It only decided to do a resize if it's a local image (ReactImageView.shouldResize()). Android docs mention that if you do a resize before display, it uses less memory, but RN doesn't. Thoughts? |
@lacker @shaneosullivan Hey! OP here. I found that Like in @shaneosullivan's comment, I assumed this happens because FB's fresco tries to load big images into memory before resizing and rendering it. So I wrote a simple native module that resizes large images before rendering them. It uses Also, I'd be happy to help resolve this issue! I can start with a small PR that makes |
@woniesong92 Hey that is awesome that you can help resolve this! Making |
@lacker , getting onError to work is a good first step. However this is a fundamental failing in React Native, that it cannot display reasonable sized images on Android when other similar code can do it just fine. Is there a way to escalate this internally? If we were using RN for our photo viewer this would be a UBN.... |
@shaneosullivan The internal consensus is that you should fix it 😜 |
@lacker , surprising that :-) I'll happily swap you some fun Ads front end tasks that totally rewrite some of the logic core to everything we use to make money. Let's see which of us breaks the most stuff fastest :-) (hint: probably me) |
Has there been any progress on this? |
android:largeHeap="true" fixed the problem for our use cases (per #13600) |
Hi there! This issue is being closed because it has been inactive for a while. Maybe the issue has been fixed in a recent release, or perhaps it is not affecting a lot of people. Either way, we're automatically closing issues after a period of inactivity. Please do not take it personally! If you think this issue should definitely remain open, please let us know. The following information is helpful when it comes to determining if the issue should be re-opened:
If you would like to work on a patch to fix the issue, contributions are very welcome! Read through the contribution guide, and feel free to hop into #react-native if you need help planning your contribution. |
This issue still needs fixing in RN 0.46.4. It fails with images not that big (< 1600px on one side) |
Summary: The Android ImageEditingManager is inefficient and slow when cropping images. It loads the full resolution image into memory and then crops it. This leads to slow performance and occasional OutOfMemory Exceptions. [BitmapRegionDecoder](https://developer.android.com/reference/android/graphics/BitmapRegionDecoder.html) can be used to crop without needing to load the full resolution image into memory. Using it is much more efficient and much faster. Relevant issue: #10470 Attempt to crop a very large image (2000x2000) on Android. With this change, the crop should happen almost instantly. On the master branch, it should take 2-3 seconds (and might run out of memory). Please let me know if there's anything else I can provide. Closes #15439 Differential Revision: D5628223 Pulled By: shergin fbshipit-source-id: bf314e76134cd015380968ec4533225e724c4b26
Genymotion Google Galaxy Nexus (API Level 16) - remote image not loading, works fine on iOS; resizeMethod={'resize'} doesn't work. |
Issue Description
When I try to render a big image (5312 x 2988), the image container just shows an empty box. If the image is reasonably sized (~1024x1024) or comes directly from device instead from a remote url, it renders fine. Not sure if it's a memory or networking issue. There's another open issue(#7408) that seems to discuss a similar topic.
Steps to Reproduce / Code Snippets
Render a large image in a ListView. In a dev mode, the app will crash in a few seconds. In a production mode, the app just shows a white background in place of an image.
Inside a
ListView
I render an image like below:Expected Results
Image is rendered successfully.
Additional Information
Update
Unfortunately, trying to resize a large picture using
ImageEditor
also fails because of anOutOfMemory
exception. I used the photos that are captured by device's built-in camera.References:
The text was updated successfully, but these errors were encountered: