In recent projects, the save as function of pictures is required to save pictures as jpg, png, bmp. It is relatively simple for jpg and png, and Android provides a () method that can be solved immediately. However, there is no good support for the BMP format. I spent a few days searching online for a long time, but I couldn't find any useful answers. I also asked questions and had no suitable answers.
package ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; public class Mainactivity extends Activity { ImageView img; @Override public void onCreate(Bundle savedInstanceState) { (savedInstanceState); setContentView(); Button btn = (Button) findViewById(); img = (ImageView) findViewById(.img1); (new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub View view = (); (true); (); Bitmap bitmap = (); if (bitmap != null) { // ByteArrayOutputStream bos = new ByteArrayOutputStream(); // (, 90, bos); Only convert to PNG or JPEG// byte[] data = (); // ((data, 0, // )); int w = (), h = (); int[] pixels=new int[w*h]; (pixels, 0, w, 0, 0, w, h); // ByteBuffer dst = (() // * h); // (dst); // IntBuffer dst=(w*h); // (dst); byte[] rgb = addBMP_RGB_888(pixels,w,h); byte[] header = addBMPImageHeader(); byte[] infos = addBMPImageInfosHeader(w, h); byte[] buffer = new byte[54 + ]; (header, 0, buffer, 0, ); (infos, 0, buffer, 14, ); (rgb, 0, buffer, 54, ); try { FileOutputStream fos = new FileOutputStream(Environment .getExternalStorageDirectory().getPath() + "/"); (buffer); } catch (FileNotFoundException e) { // TODO Auto-generated catch block (); } catch (IOException e) { // TODO Auto-generated catch block (); } } } }); } //BMP file headerprivate byte[] addBMPImageHeader(int size) { byte[] buffer = new byte[14]; buffer[0] = 0x42; buffer[1] = 0x4D; buffer[2] = (byte) (size >> 0); buffer[3] = (byte) (size >> 8); buffer[4] = (byte) (size >> 16); buffer[5] = (byte) (size >> 24); buffer[6] = 0x00; buffer[7] = 0x00; buffer[8] = 0x00; buffer[9] = 0x00; buffer[10] = 0x36; buffer[11] = 0x00; buffer[12] = 0x00; buffer[13] = 0x00; return buffer; } //BMP file information headerprivate byte[] addBMPImageInfosHeader(int w, int h) { byte[] buffer = new byte[40]; buffer[0] = 0x28; buffer[1] = 0x00; buffer[2] = 0x00; buffer[3] = 0x00; buffer[4] = (byte) (w >> 0); buffer[5] = (byte) (w >> 8); buffer[6] = (byte) (w >> 16); buffer[7] = (byte) (w >> 24); buffer[8] = (byte) (h >> 0); buffer[9] = (byte) (h >> 8); buffer[10] = (byte) (h >> 16); buffer[11] = (byte) (h >> 24); buffer[12] = 0x01; buffer[13] = 0x00; buffer[14] = 0x18; buffer[15] = 0x00; buffer[16] = 0x00; buffer[17] = 0x00; buffer[18] = 0x00; buffer[19] = 0x00; buffer[20] = 0x00; buffer[21] = 0x00; buffer[22] = 0x00; buffer[23] = 0x00; buffer[24] = (byte) 0xE0; buffer[25] = 0x01; buffer[26] = 0x00; buffer[27] = 0x00; buffer[28] = 0x02; buffer[29] = 0x03; buffer[30] = 0x00; buffer[31] = 0x00; buffer[32] = 0x00; buffer[33] = 0x00; buffer[34] = 0x00; buffer[35] = 0x00; buffer[36] = 0x00; buffer[37] = 0x00; buffer[38] = 0x00; buffer[39] = 0x00; return buffer; } private byte[] addBMP_RGB_888(int[] b,int w, int h) { int len = ; (); byte[] buffer = new byte[w*h * 3]; int offset=0; for (int i = len-1; i>=w; i-=w) { //The last line of the DIB file format is the first line, each line is in order from left to rightint end=i,start=i-w+1; for(int j=start;j<=end;j++){ buffer[offset]=(byte)(b[j]>>0); buffer[offset+1]=(byte)(b[j]>>8); buffer[offset+1]=(byte)(b[j]>>16); offset += 3; } } return buffer; } }
However, after I use this method, the saved image will have a big color difference compared to the original one. See the attachment for details.
So I encountered new trouble, downloaded an UltraEdit software, and then opened the previous bmp image and the first saved bmp image and the first saved bmp image. Analyze the format of bmp image. I found a very good explanation from the Internet. Please see the attachment for detailed analysis of the Chinese version. Provide two URLs for analysis of bmp format:
https:///article/
https:///article/
Image file header
1) 1-2: (The numbers here represent "word", that is, two bytes, the same below) Image file header. 0x4d42='BM' means it is the BMP format supported by Windows. (Note: Check the ascii table B 0x42, M0x4d, bfType is two bytes, B is low byte, M is high byte, so bfType=0x4D42, not 0x424D, but note)
2) 3-6: The entire file size. 4690 0000, 00009046h=36934.
3) 7-8: Reserved, must be set to 0.
4) 9-10: Reserved, must be set to 0.
5) 11-14: Offset from the start of the file to the bitmap data (14+40+4* (2^biBitCount)). 4600 0000, 0000046h=70, the file header above is 35 words = 70 bytes.
Bitmap information header
6) 15-18: Bitmap information head length.
7) 19-22: Bitmap width, in pixels. 8000 0000, 00000080h=128.
8) 23-26: Bitmap height, in pixels. 9000 0000, 00000090h=144.
9) 27-28: The number of planes of the bitmap, the value is always 1.0100, which is 0001h=1.
10) 29-30: Number of bits per pixel. There are 1 (monochrome), 4 (16 colors), 8 (256 colors), 16 (64K colors, high color), 24 (16M colors, true color), 32 (4096M colors, enhanced true color). 1000 is 0010h=16.
11) 31-34: Compression description: There are 0 (not compressed), 1 (RLE 8, 8-bit RLE compression), 2 (RLE 4, 4-bit RLE compression, 3 (Bitfields, bitfields). RLE is simply used to compress the number of pixels + pixel values. T408 adopts the bitfield storage method, which represents a pixel in two bytes, and the bitfield is allocated as r5b6g5. In the figure, 0300 0000 is 0000003h=3.
12) 35-38: The size of the bitmap data represented by the number of bytes must be a multiple of 4, which is numerically equal to (≥ the smallest multiple of 4 of the bitmap width) × bitmap height × number of bits per pixel. 0090 0000 is 00009000h=80×90×2h=36864.
13) 39-42: Horizontal resolution represented by pixels/meter. A00F 0000 is 0000 0FA0h=4000.
14) 43-46: Vertical resolution represented by pixels/meter. A00F 0000 is 0000 0FA0h=4000.
15) 47-50: The number of color indexes used by the bitmap. If set to 0, all palette items are used.
16) 51-54: The number of color indexes that have an important impact on the image display. If it is 0, it means it is important.
This 54-bit information is very important, so I made an attempt to verify whether it is because of the different header information of the bmp image, causing color deviation? The experimental method is as follows: In fact, it is very simple. The first step is to open the bmp image before saving and after saving using UltraEdit, and copy and paste the header of the bmp image before saving, that is, the value of the first 54 digits, and then paste it on the header of the saved image. In this way, the header information of the two pictures is the header of the picture before saving. Then ctrl+s the saved image, then open it and find that the image has not changed. The first step is to do the opposite operation this time, that is, copy and paste the head of the saved bmp image, that is, the value of the first 54 digits, to the head of the image before saving. It is found that there is no change, indicating that the file header is not the reason for affecting the color difference.
At this time, only the code is left: byte[] rgb = addBMP_RGB_888(pixels,w,h); The problem here is. Enter this function and read it carefully. I found that it is the place where the color information is stored. After reading the code, I found that there was a bug in the original author's code. Here: buffer[offset+1]=(byte)(b[j]>>16); should be buffer[offset+2]=(byte)(b[j]>>16); that is, offset should be +2, not add 1. After correcting the error, run it again and find that the saved image color returns to normal and is the same as the original image, and the problem is solved.
Summary: I don’t know why I often encounter it. It’s very common on the Internet, but I can’t find a solution to my problem. I’m very depressed. Many links on the Internet point to this address, but I don’t have a more detailed explanation after entering. It's very regretful and annoyed. I hope to share more useful and feasible solutions online, which will benefit everyone and avoid wasting your search time.
I cherish this here and thank the blogger of csdn for solving my problem. Of course, when using other people's code, you should also think more and not believe it completely easily.