How to compress GIF image before uploading to server in android? - android

how to compress GIF image before upload it to the server ?, i tried some android libraries to compress gif image but it convert it to png image. is there any way to compress gif image ?

im using a bitmap in my projects.
Bitmap
Example code:
ImageView carView = (ImageView) v.findViewById(R.id.imagen_cr7);
byte[] decodedString = Base64.decode(picture, Base64.NO_WRAP);
InputStream input=new ByteArrayInputStream(decodedString);
Bitmap ext_pic = BitmapFactory.decodeStream(input);
carView.setImageBitmap(ext_pic);

GIF is a lossless image compression format: it is set up to reproduce the image exactly.
As a consequence, there is no "image quality" slider (as in JPEG encoders); although a GIF will likely be much smaller than an uncompressed format (such as many camera RAW or common TIFF options), there is a limit to how far it can go.
Also, you should know that GIF is limited to 8 bits per pixel (so it is most appropriate for line art, not photo-like images). If your source image is a full 24 bits, it must be dithered to fit into a 256-entry color palette. So, although the GIF format itself is lossless, the image processing required to use it in the first place may be lossy.
There are a number of things you can do to reduce the size of your image file:
You can choose a lossy format (such as JPEG), which will allow much greater compression. Note that JPEG works well on photo-like images, but not so well on line art. Also, (although your question explicitly rejects it) PNG may be a reasonable option, as it (losslessly) supports 24-bpp images.
As mentioned in a comment, you can try reducing the resolution of your image, and shipping the reduced version. If you can't generate a smaller image to start with, image resizing typically works well on photo-like images, and there are nonlinear resizing filters available that are specifically intended to handle line art.
If a full-resolution GIF is mandatory for your application, you may be able to generate an image that is more compressible by the GIF format. GIF compresses solid blocks of color extremely well -- but does less well on dithered or noisy images (such as you might get from converting a 24-bpp image to GIF format).
Since you have not given any information on your requirements (what kind of image you have, where you got it, and what you need it for), it is hard to come up with specific advice.
However, there is a good chance that your GIF has far more resolution than you need for your particular application (leading to option #2).

Related

Android ImageSize Increases after downloading | Picasso

I have an image stored on my server whose size is 89kb.
https://s3-ap-southeast-1.amazonaws.com/images.crownit.in/emailer/push_banner_tambola_01072017_v2.jpg
However, after I download the bitmap using Picasso, The byteCount comes out to be 2 MB.
double lengthbmp = bitmap.getByteCount(); //1920000 Bytes
Is this anything to do with the resolution of the image?
The reason for the size change is due to a change in file format. The file is hosted as a JPEG, however you are converting it to a bitmap in your application. I converted the file using photoshop to give an example of the difference in file size based on format:
In terms of network load you will still only move the 89kb, as the file only increases in size when converted to bitmap in your application.
If you really want to maintain the JPG format follow the answer given in the following post: How to display image from URL on Android

Does BitmapFactory.decodeFile() file decompress the JPEG image when decoding it?

JPEG is a compressed format.
Does BitmapFactory.decodeFile("path to a JPEG file") decompress the JPEG image when decoding it as a Bitmap in the memory?
And when I use Bitmap.compress(Bitmap.CompressFormat.JPEG, 100, byteArrayOutputStream) on the resulting bitmap from the decoded JPEG file, then the size of the compressed image is more than the size of the original image. Can anybody exactly explain this phenomenon?
Does BitmapFactory.decodeFile("path to a JPEG file") decompress the JPEG image when decoding it as a Bitmap in the memory?
Yes.
And when I use Bitmap.compress(Bitmap.CompressFormat.JPEG, 100, byteArrayOutputStream) on the resulting bitmap from the decoded JPEG file, then the size of the compressed image is more than the size of the original image
That is very possible. With a quality level of 100, I would consider it likely, though perhaps not assured.
Can anybody exactly explain this phenomenon?
There is no requirement that they be the same for a JPEG. In fact, it will be almost random chance if they are the same.
Suppose we start with an in-memory image (Boriginal, where B is short for bitmap). We then compress that image to a JPEG (Joriginal). JPEG incorporates a lossy compression algorithm, to achieve better compression on real-world images (e.g., photos) by taking into account the fact that human eyes cannot discern small amounts of change.
Suppose we then decode Joriginal back into an in-memory bitmap (Breloaded). Breloaded will not be the same image as Boriginal, because the JPEG compression will have changed the image. How close Breloaded is to Boriginal will depend on a variety of factors, partly tied to the image itself, and partly tied to the quality level used when saving the JPEG (the 100 in your code). This quality level ranges from 0 to 100, with 100 meaning highest quality.
If we then compress Breloaded to a second JPEG (Jreloaded), the new JPEG will not be the same as the original JPEG (Joriginal). Partly, that is because the source bitmap changed, per the previous paragraph. Partly, that is because we might not choose the same quality level as we did with the original compression work.
In your case, you did not create Joriginal. You do not necessarily know what quality level was used (that information might be stored in the JPEG header; I forget). But because Breloaded will be different that the original bitmap (wherever it came from), when you compress the bitmap to Jreloaded, it is going to be different than Joriginal. On the whole, whether it is larger or smaller is difficult to say in the abstract. However, since you are choosing a quality level of 100, and Joriginal might well have been compressed with a lower quality level, your compressed image very easily could be larger.
This has nothing to do with Android. This is purely a function of how JPEG works. If you have further questions about JPEG itself, you may wish to read more about JPEG and ask questions on some site that has something to do with image formats.

Android imageview image quality matter?

I am writing a Android app which need to display some high quality picture(took from professional DSLR). The problem is it can't be display from gallery.
I choose a photo in Gallery first. The target picture is 2464*1632 JPEG, roughly 4.5M;
Then I just need to compress it to 800*600 and display it in imageview:
image.setImageBitmap(this.bmp);
Thing is that I have tested other image I downloaded form internet(really low quality), and it works without any problem. Can anybody tell me why it can't be displayed? I will be really appericiated
Large images are tricky to handle due to limited memory. You have several choices:
Use a WebView (this allows you to have pinch and zoom functionality to make use of those extra pixels
Decode the image down to the size of the display and then put it in an ImageView using BitmapOpts http://developer.android.com/reference/android/graphics/BitmapFactory.Options.html and changing inSampleSize. It seems you may be having difficulty with that, so consider using createScaledBitmap which just needs the dest width and height.

Is it possible to chop a bitmap to small pieces without loading the entire thing into memory?

I'm working on an image processing application for Android that recognizes music notation from pictures taken of music sheets.
I tried to load the entire image into a Bitmap using the BitmapFactory.decodeFile(imgPath) method, but because my phone doesn't have enough memory I get a "VM heap size" error. To work around this, I'd like to chop the full image into smaller pieces, but I'm not sure how to do that.
I also saw that it was possible to reduce the memory size of the Bitmap by using the inSampleSize property of the BitmapFactory.Option class, but if I do that I won't get the high resolution image I need for the music notation recognition process.
Is there anyway to handle this without going to NDK?
Android 2.3.3 has a new API called android.graphics.BitmapRegionDecoder that lets you do exactly what you want.
You would for instance do the following:
BitmapRegionDecoder decoder = BitmapRegionDecoder.newInstance(myStream, false);
Bitmap region = decoder.decodeRegion(new Rect(10, 10, 50, 50), null);
Easy :)
If it's from a camera the image will likely be jpeg format. You could use an external jpeg library - either in java or via the NDK, whatever you can find - to give you better control and load it a piece at a time. If you need it as an android.graphics.Bitmap then I suspect you will then need to re-encode the subimage as PNG or JPEG and pass it to BitmapFactory.decodeByteArray(). (If memory is a concern then do be sure to forget your references to the pieces of the bitmap promptly so that the garbage collector can run effectively.)
The same technique will also work if the input graphic is PNG format, or just about anything else provided you can find suitable decode code for it.
I think that by loading the image piecewise you are setting yourself an algorithmic challenge in deciding what parts of it you are really interested in the full detail of. I notice that BitmapFactory.Options includes the option to subsample, that might be useful if you want to analyse an overview of the image to decide what regions to load in full detail.
If you're dealing with JPEG images, see my answer to this question as well as this example.
I don't know how possible it is to get libijg on Android, but if it is, then it's worth a shot.

Access to separate pixel of JPEG image in Android

In my android project I need to get access for each separate pixel of JPEG image. Image created by built-in photo application. I try to convert JPEG into Bitmap class instance, but OutOfMemoryException was thrown. After searching info about this problem I have found the following solution: resize image! But quality of image is important in my project, and i can't resize it. Is there any way to get each-pixel access?
if your image is too big and the quality is important i suppose the best way is to use or create your own class to cut the image in zone (eg : 50*50 px) , there is several jpeg info class in the internet to help you understand how work jpeg files.
Have you tried BufferedImage ? (it's not in the sdk but maybe usable)
The nature of jpeg makes it very hard to get the value of a single pixel. The main reason is that the data is not byte aligned, another is that everything is encoded in blocks that can be of sizes 8x16, 16x8 and 8x8. Also, you need to handle subsampling of chroma values.
If the image contains restart markers, maybe you can skip into the image so you don't have to decode the whole image before getting the pixel value.

Categories

Resources