Android: Refining zoomable Picture - android

I've been struggling for a long time with large images that are able to zoom. I am loading some picture from the network that can have very variable size: it might go from 0.5MP up to 10MP. Simply loading one to a bitmap can produce application crash because of OOM exception. But details are very important so I want the user to be able to zoom on them such that full quality is maintained (so the picture should refine itself during zooming). I don't find a proper way to do this. I've used the TouchImageView library, but it doesn't manage large pictures at all. If I first down sample my picture with the inSampleSize parameter of the BitmapFactory, I lose the quality definitively. I don't want to code a whole new zooming tool, as it is already implemented on every android phone in the default Gallery app. There has to be a way to use this kind of tool, and simply display a large image that is able to zoom, right?

Have you tried PhotoView?
You could also do it with loadUrl(String) of standard WebView which should handle big images too. WebView has built-in zoom controls.

BitmapRegionDecoder(added in 2.3.3) may work. But I've not tried it.
It seems that the implementation in Gallery is OpenGL, there is no way to use it simply.

Related

Android Image Gallery Memory Use Theory

So, I've been researching on bitmap scaling using the bitmap factory.
http://developer.android.com/training/displaying-bitmaps/load-bitmap.html
I'm doing so because the application I'm working on requires a gallery that allows users to submit their photos to be added to the gallery. These photos will then be read from a URL.
My theoretical problem is this: Considering the android devices can have as low as 16MB of memory, even scaling down the images is only delaying the inevitable unless only handling a single image. Whereas in my case, the amount of images that will be loaded could be hundreds. Meaning that even if they're scaled down, eventually one will reach that limit.
My only idea thus far are to load one image at a time, which is not preferable since users will have to wait between photo transitions.
That being said, is there anyone who has experience developing applications on android that handle 100's of images? If so, is there any theory you could share on handling all these images fluidly? It can obviously be done, as there are gallery applications available. I am just unsure how they accomplished it given the restraints.
Please note this is not a request on how to use the bitmap factory to scale images, as that question has been answered many times.
Rather a request on handling data amounts you know will exceed limitations.
The gallary apps should not be storing all thousands of images in memory. Use the Viewholder pattern such that the image views displayed will get recycled (this is forced upon you if you use RecyclerView). On backend use an image cache and keep a limit on it size.
See e.g. What is the benefit of ViewHolder? and How to release memory of bitmap using imageloader in android?
The Android gallary app source may be a good reference: https://android.googlesource.com/platform/packages/apps/Gallery/+/android-5.1.1_r18/src/com/android/camera

How to set a dynamic background in Android (just like Tumblr Login UI)

I am new to Android and I having troubles setting a dynamic background just like Tumblr login UI,
The link below is where I got some help.
Set Animated .GIF As Background Android
But it only works when I load small-size animation, or I have to drop lots of frames of a GIF animation which leads to incoherence.
If I load all the frames which will cause OutOfMemoryError, I don't think it's the right way.
Is tumblr uses GIF animation or it's actually a short video?
I know that Twitter converts all GIFs to MP4. Video compression is far better than GIFs leading to smoother playback and reduced bandwidth and happy users :) Is using MP4s an option?
More on the subject here.
Not sure how long your animation is, or how high res its frames are, but you probably need to look at loading the image frames in scaled down form into memory. The Android docs give a very coherent explanation of how to do this here (basically, you first find the res of the bitmap, then load a scaled down version of it appropriate to the device's screen resolution). It may also be that the animation is too long, and you need to look at forcing bitmaps to recycle (using bitmap.recycle()) once displayed.

Crop image without loading into memory

I want to crop image of large size and tried using Bitmap.createBitmap but it gives OOM error. Also, tried multiple technique around createBitmap but none of them were successful.
Now I thinking of saving image to file system and crop it without loading image into memory that might solve the problem. But don't know how to do it.
User flow: User will take multiple pictures from in-app camera after each snap user can crop it manually or app will silently crop it on some predefine login and later it will send these images to server.
Can anybody guide me how I can achieve this?
There is a class called BitmapRegionDecoder which might help you, but it's available from API 10 and above.
If you can't use it :
Many image formats are compressed and therefore require some sort of loading into memory.
You will need to read about the best image format that fits your needs, and then read it by yourself, using only the memory that you need.
a little easier task would be to do it all in JNI, so that even though you will use a lot of memory, at least your app won't get into OOM so soon since it won't be constrained to the max heap size that is imposed on normal apps.
Of course, since android is open source, you can try to use the BitmapRegionDecoder and use it for any device.
I very much doubt you can solve this problem with the existing Android API.
What you need to do is obtain one of the available image access libraries (libpng is probably your best bet) and link it to your application via jni (see if there's a Java binding already available).
Use the low-level I/O operations to read the image a single scanline at a time. Discard any scanlines before or after the vertical cropped region. For those scanlines inside the vertical cropped region, take only those pixels inside the horizontal cropped region and write them out to the cropped image.

Android WebView - Dithering/Changes on Tap

I am currently working on an application that requires the use of a WebView. It basically takes up the entire screen space.
Initially the images inside of the WebView look fine and high quality. Unfortunately, when a user taps (and holds) a button in the webview, the images then lose quality and dither until the finger is released. Is there any way to disable this?
A good note, my app does not need any scrolling whatsoever. I thought Android would only lower the quality on scroll to better performance.
the only solution is to make your own image viewer, the webview resamples images at lower qualities
I've been dealing with the same issue for a long while. The best solution is to split the image into several sub-images and load them altogether within the same html file.
The easiest and fastest solution I found is with Adobe Photoshop:
Open you image
Create horizontal and vertical guides
Select the Slicing tool and activate the "create slices from guides"
Save for web (I'm not using the English version, but you get what I mean)
Select your desired image format
Save, but while saving check the option "Html and images"
With this, you'll avoid dithering with any image as long as you split it into enough pieces,

Loading image from server

I have activity that load's image from server into imageview. Image is displayed after it's fully loaded.
What I want to do is while image is being loaded display it first in low, than medium, and at the end high quality (some images are big). I have no idea how this thing is called and what to google, so any help is appreciated.
Loading an image like this is called progressive loading, it is even part of the JPEG standard.
Another possible search term might be interlacing.
It is certainly possible to create the image in progressive qualities from the same stream though some clever technical co-operation from both sides would be nessecary.
Are you grabbing pictures from a server in your control or from other url's?
If you control the server you could query a php script with image quality parameters and get them in succession though personally I think that's a waste of bandwidth.
Why not just indicate the image is loading and put a place holder image, and when the high quality image is downloaded just replace it?
I'm sorry i couldn't help you by telling you how to do it the first way although it's something I may try to implement myself in some spare time.
My finding is that iOS can progressively decode & render Progressive JPEG with NYXImagesKit (see How do I display a progressive JPEG in an UIImageView while it is being downloaded? ), but Android doesn't seem to have a library like that.

Categories

Resources