Reprint please indicate the source, thank you: http://blog.csdn.net/harryweasley/article/details/51955467
Android pictures are in the form of bitmap, then the bitmap of memory, directly affect the amount of memory used by the application, first of all to know the amount of memory bitmap accounted for the size of the calculation method:
Picture length × picture width x number of bytes occupied by one pixel
Here is the compressed format of the picture:
where a represents transparency; R is red; G is green; b stands for blue.
Alpha_8
Represents a 8-bit alpha bitmap, a=8, with a pixel that occupies 1 bytes, it has no color, and only transparency
argb_4444
Represents a 16-bit ARGB bitmap, which is a=4,r=4,g=4,b=4, a pixel that occupies 4+4+4+4=16 bit, 2 bytes
argb_8888
Represents a 32-bit ARGB bitmap, which is a=8,r=8,g=8,b=8, a pixel that occupies 8+8+8+8=32 bit, 4 bytes
rgb_565
Represents a 16-bit RGB bitmap, r=5,g=6,b=5, which has no transparency, a pixel that occupies 5+6+5=16 bit, 2 bytes
I am using the Xiaomi phone 2s to test, remove a photo from the SD card as follows:
bit = BitmapFactory.decodeFile(Environment .getExternalStorageDirectory().getAbsolutePath() "/DCIM/Camera/test.jpg"); Log.i("wechat""压缩前图片的大小" + (bit.getByteCount10241024) "M宽度为" + bit.getWidth"高度为" + bit.getHeight());
The log that came out is:
Will get the bitmap to compress, the following begins to say, bitmap several compression ways.
1. Quality compression
Bytearrayoutputstream BAOs = new Bytearrayoutputstream ();int quality = Integer. ValueOf(EditText. GetText(). toString());Bit. Compress(Compressformat. JPEG, quality, BAOs);byte[] bytes = BAOs. Tobytearray();BM = Bitmapfactory. Decodebytearray(Bytes,0, bytes. Length);Log. I("WeChat","Size of compressed picture"+ (BM. GetByteCount() /1024x768/1024x768) +"m width is"+ BM. GetWidth() +"Height is"+ BM. GetHeight() +"Bytes.length="+ (bytes. Length/1024x768) +"KB"+"quality="+ quality);
Where quality is the number obtained from EditText, which can be changed from 0–100, here the log is:
You can see that the size of the picture is not changed, because the quality of compression does not reduce the image of the pixel, it is in the premise of keeping pixels to change the image bit depth and transparency, to achieve the purpose of compressing the picture, which is why the method called quality compression method. So, the image is long, wide, and the pixels are constant, so the memory size of the bitmap will not change.
But we see that the bytes.length is smaller as the quality becomes smaller. This is appropriate to pass binary image data, such as sharing images, to pass in the binary data past, limit 32kb within.
Here to say, if it is bit.compress (compressformat.png, Quality, BAOs), such a PNG format, quality will not work, The bytes.length does not change because PNG images are lossless and cannot be compressed.
Compressformat also has a property, COMPRESSFORMAT.WEBP format, which is Google's own introduction to a picture format, more information, at the end of the text will be posted address.
2. Sample rate compression
Bitmapfactory. Optionsoptions = new Bitmapfactory. Options();Options. Insamplesize=2;BM = Bitmapfactory. DecodeFile(Environment. getExternalStorageDirectory(). GetAbsolutePath() +"/dcim/camera/test.jpg", options);Log. I("WeChat","Size of compressed picture"+ (BM. GetByteCount() /1024x768/1024x768) +"m width is"+ BM. GetWidth() +"Height is"+ BM. GetHeight());
Out of the log is
Set the value of insamplesize (int type), if set to 2, then the width and height are the original 1/2, the width and height are reduced, natural memory is also reduced.
I didn't use the code above Options.injustdecodebounds = true; Because I am fixed to sample the data, why this compression method is called sample rate compression, is because with Injustdecodebounds, first get the image width, high "this process is sampling", and then by obtaining the width of the high, dynamic set the value of Insamplesize.
When Injustdecodebounds is set to True, Bitmapfactory will return an empty (null) Bitmap object when decoding the picture through Decoderesource or decodefile. This avoids bitmap memory allocations, but it can return the width, height, and mimetype of the bitmap.
3. Scaling method Compression (Martix)
Matrix matrix = new Matrix ();Matrix. Setscale(0.5F0.5F;BM = Bitmap. CreateBitmap(Bit,0,0, bit. GetWidth(), Bit. GetHeight(), Matrix, True);Log. I("WeChat","Size of compressed picture"+ (BM. GetByteCount() /1024x768/1024x768) +"m width is"+ BM. GetWidth() +"Height is"+ BM. GetHeight());
Out of the log is
As you can see, the length and width of the bitmap are reduced by half, and the image size is reduced by One-fourth.
For more information about Martix, there will be a reference article at the end of the text.
4.rgb_565 method
Bitmapfactory. OptionsOptions2 = new Bitmapfactory. Options();Options2. Inpreferredconfig= Bitmap. Config. RGB_565;BM = Bitmapfactory. DecodeFile(Environment. getExternalStorageDirectory(). GetAbsolutePath() +"/dcim/camera/test.jpg", OPTIONS2);Log. I("WeChat","Size of compressed picture"+ (BM. GetByteCount() /1024x768/1024x768) +"m width is"+ BM. GetWidth() +"Height is"+ BM. GetHeight());
The log that came out is:
We saw that the image size was reduced by half, and the length and width did not change, and the memory was reduced by half compared to argb_8888.
Note: Due to the argb_4444 quality, generally if the picture does not have the transparency requirements, can be changed to rgb_565, compared to argb_8888 will save half of the memory overhead.
5.createScaledBitmap
bm = Bitmap.createScaledBitmap150150, true); Log.i("wechat""压缩后图片的大小" + (bm.getByteCount1024"KB宽度为" + bm.getWidth"高度为" + bm.getHeight());
Out of the log is
This is to compress the picture into the length and width desired by the user, but here it would be unclear if the length and width of the user's expectation are too different from the length of the original.
Summarize
These are the 5 ways to compress images, and it's important to stress that their compression is only for bitmap in Android. If you save these compressed bitmap as SD, their memory size is not the same.
In Android phones, the amount of memory that a picture occupies is related to many factors, and it can be cumbersome to calculate. In order to calculate the memory size of a picture, the image can be calculated indirectly as a file, using the following method:
FilefilenewFile(Environment.getExternalStorageDirectory() "/DCIM/Camera/test.jpg"); Log.i("wechat""file.length()="file1024);
Or
null; try { new FileInputStream(file); catch (FileNotFoundException e) { e.printStackTrace(); } try { Log.i("wechat""fis.available()="1024); catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }
The above two methods calculate the same result.
After reading this content, in fact, bitmap compression is around this to make a fuss: bitmap occupied memory = picture length x image width x the number of bytes occupied by a pixel. 3 parameters, arbitrarily reduce the value of one, it achieves the effect of compression.
Reference article:
Android Bitmap Optimizer (1)-Image compression http://anany.me/2015/10/15/bitmap1/
Multi-figure comparison of Google WEBP and JPEG image format http://www.win7china.com/html/8668.html
The android-uses the matrix to process the bitmap http://blog.csdn.net/nupt123456789/article/details/24600055
Bitmap Six compression methods, image compression