We need to downsample image received from InputStream. It is an image received from some URL and it can be either pretty small or very large. To fit this image in memory we have to downsample it. First we retrieve image size with the help of inJustDecodeBounds and calculate necessary sample. Then we create downsampled bitmap by specifying this sample in BitmapFactory.Options.inSampleSize. This 2-steps decoding needs two calls of decodeStream() and works just fine.
This works just fine for files from SD card. But in our case input stream cannot be reset so we can't call decodeStream() twice. Cloning of input stream is also not an option because of its huge size. Alternatively, we can create 2 HTTP requests to the same URL: first to get image size, and then to decode actual image with downsampling, but this solution seems to be rather ugly.
Can we reuse stream which cannot be reset? Or please propose some known workarounds for this problem.
If you wan't to reuse the stream it is obviously must be saved to either RAM or the SD-card, because network InputStream (let's imagine it is not Buffered) is not keeping downloaded data.
So the option to workaround this as said before is to save image directly to the sd-card (maybe in some temp directory) if image could really huge.
Related
I am trying to write a content provider in order to send an image to another process via ImageView.setImageUri() call, the Bitmap i want to send is in memory and, due to performance reasons, i would prefer avoiding saving it on disk and even encoding it because it might take up to 2/3 seconds to encode in PNG and it wouldn't make much sense since the other end is then decoding it.
So, i am able to send the image in PNG correctly using a PipeHelper but i cannot send it "raw" (so an Android Bitmap as a bytearray directly from memory), is there any option to do that? Am i passing the wrong mime type? Why setImageBitmap() works with raw bitmaps while setImageUri() doesn't?
I know i could use a Parcelable Bitmap but i want to overcome Parcelable size constraints. Finally, is there any encoding faster than PNG that supports alpha if ending size is not an issue?
Is there any way to save bitmap to sd card and then load it from there without using decode?
I want to decode bitmaps only once and then use decoded files on sd card, is it possible?
You can use a .bmp formatted image with no compression. You'd still need to call decode to open it, but it will be a pretty much instant call since you aren't compressed. It will lead to huge files though- 4 bytes per pixel, plus some headers.
I'm downloading images from the internet and then displaying them scaled on the screen. The idea is to use inSampleSize so I can scale large images while decompressing and prevent OutOfMemory exception. But in order to find inSampleSize I need to know image resolution. It can be obtained using inJustDecodeBounds option.
The problem is that I can't pass it the stream and download the image from the internet directly, because it will be downloaded twice (first to get the size, then to get the scaled Bitmap). I can't download the image and store it in RAM, because image size may be large. The only solution left is to download the image to SD card / internal memory and read it from there, but when user has no space left bad things are going to happen.
The question is - is there any way to do it without relying on the storage and RAM memory which doesn't require the image to be downloaded twice? Or maybe BitmapFactory doesn't download whole image when it's using inJustDecodeBounds, but just headers?
Thanks
If you're downloading a PNG, GIF or JPG it should be possible to read the file headers to determine the width and height, which should mean you avoid having to download the entire file.
This post has some C# code for reading the width and height from the headers for the above format which you could port to Java for use in Android.
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.
I would like to capture an image with the Android Camera but because the image may contain sensitive data I dont want the image saved to the phone or sd card. Instead I would like a base64 string (compressed) which would be sent to the server immediately
In PhoneGap it seems files are saved to various places automatically.
Natively I was never able to get the image stream - in onJpegPictureTaken() the byte[] parameter was always null.
can anyone suggest a way?
See Camera.onPreviewFrame() and the YuvImage.compresstoJpeg() to be able to get a byte array you can convert into a bitmap.
Note that YuvImage.compressToJpeg() is only available in SDK 8 or later, I think. For earlier versions you'll need to implement your own YUV decoder. There are several examples around or, I could provide you an example.
Those two methods will allow you to get a camera picture in memory and never persist it to SD. Beware that bitmaps of most camera preview sizes will chew up memory pretty quickly and you'll need to be very careful to recycle the bitmaps and probably also have to scale them down a bit to do much with them and still fit inside the native heap restrictions on most devices.
Good luck!