Recently in the study of the SDK, in thumbnails this has encountered a bit of a problem.
The thumbnail requirement is no more than 32k, which requires compressing my picture. Tried several methods, one by one ways to come.
1, Quality compression method:
The code is as follows
- Bytearrayoutputstream BAOs = new bytearrayoutputstream ();
- Image.compress (Bitmap.CompressFormat.JPEG, BAOs);
- int options = +;
- while (Baos.tobytearray (). Length/ 1024x768>+) {
- Baos.reset ();
- Image.compress (Bitmap.CompressFormat.JPEG, Options, BAOs);
- options = ten;
- }
- Bytearrayinputstream ISBM = new bytearrayinputstream (Baos.tobytearray ());
- Bitmap Bitmap = Bitmapfactory.decodestream (ISBM, null, null);
The first use of this for compression, but always compressed less than 32k so small. Later to see the master's explanation to understand that this compression method is called quality compression, because it does not reduce the image of pixels. It is to keep pixels in the premise of changing the image of the bit depth and transparency, to achieve the purpose of compressing the picture. In the compressed image file size will change, but import into bitmap after the memory is unchanged. Because you want to keep the pixel constant, it cannot be compressed indefinitely, and after reaching a value it will not continue to become smaller. Obviously this method does not apply to the thumbnail, in fact, it is not suitable for compressing the image to reduce the application of memory, only for want to ensure the quality of the picture while reducing the file size.
2, Sampling rate compression method:
The code is as follows
- Bytearrayoutputstream out = new Bytearrayoutputstream ();
- Image.compress (Bitmap.CompressFormat.JPEG, N, out);
- Bitmapfactory.options newopts = new bitmapfactory.options ();
- int be = 2;
- newopts.insamplesize = be;
- BYTEARRAYINPUTSTREAM ISBM =  new bytearrayinputstream (Out.tobytearray ());   
- Bitmap Bitmap = Bitmapfactory.decodestream (ISBM,NULL, NULL);
The second is to use this method, you can compress the picture to be small enough, but there are some problems. Because the sampling rate is an integer, it is not a good guarantee of the quality of the picture. If we need to be between 2 and 3 sample rate, with 2, the picture is a little bigger, but with 3, the picture quality will be a significant decline. And that doesn't exactly meet my needs. However, the advantage of this method is to greatly reduce the use of memory, in the read memory on the picture, if you do not need high-definition effect, you can read only the edge of the picture, the width and height of the sample rate and then load the picture, so that it does not occupy too much memory. As follows
- bitmapfactory.options newopts = new bitmapfactory.options ();
- Newopts.injustdecodebounds = true;
- Bitmap Bitmap = Bitmapfactory.decodefile (path,newopts);
- Newopts.injustdecodebounds = false;
- int w = newopts.outwidth;
- < span class= "keyword" style= "Color:rgb (127,0,85); Font-weight:bold ">int h = newOpts.outHeight;
- //Calculate the sampling rate
- Newopts.insamplesize = be;
- Bitmap = Bitmapfactory.decodefile (Srcpath, newopts);
The advantage is that the large images are not first read into memory, greatly reducing the use of memory, and do not have to consider the release of large images into memory.
3. Scaling Method:
Neither of these methods satisfies the requirements, but it is only possible to consider scaling. This does not want to use this method to achieve, but the Internet to see the method is basically the above two kinds. The scaling method is actually very simple, set a good matrix, in the CreateBitmap can be. But we don't know the scale, but we're asking for the final size of the picture. Direct use of the size of the scale to do is certainly problematic, with the size of the proportion of the root to do will be more close, but there is a gap. But as long as the fine-tuning should be done, fine-tuning is the modified image size is larger than the final size, then 0.8 compression and comparison, cycle until the appropriate size. This will give you the right size of the picture, but also can be compared to ensure quality. The code is as follows
Bytearrayoutputstream out = new Bytearrayoutputstream (); Image.compress (Bitmap.CompressFormat.JPEG, in.); FLOAT zoom = (float) math.sqrt (Size * 1024x768/(float) out.tobytearray (). length); Matrix matrix = new Matrix (); Matrix.setscale (zoom, zoom); Bitmap result = Bitmap.createbitmap (image, 0, 0, image.getwidth (), Image.getheight (), Matrix, True); Out.reset (); Result.compress (Bitmap.CompressFormat.JPEG, in.); while (Out.tobytearray (). length > Size * 1024x768) {System.out.println (Out.tobytearray (). length); Matrix.setscale (0.9f, 0.9f); result = Bitmap.createbitmap (result, 0, 0, result.getwidth (), Result.getheight (), Matrix, True); Out.reset (); Result.compress (Bitmap.CompressFormat.JPEG, in.); }
Feel in the bitmap compression this piece should have more effective and convenient method, unfortunately not found on the Internet, their understanding of this may not be enough. There is a better way, or the article has the wrong place, I hope everyone to correct.