Android : save a Bitmap to bmp file format

后端 未结 4 881
盖世英雄少女心
盖世英雄少女心 2020-12-01 19:28

I have a Bitmap in memory and I need to save it in a bmp file (using the bmp file format).

Is there any way to do it on Android ?

(I read a lot of post sugg

相关标签:
4条回答
  • 2020-12-01 20:07

    Code to convert android Bitmap object to 8bit bmp file. It is derived from this C# project : https://www.codeproject.com/articles/70442/c-rgb-to-palette-based-bit-greyscale-bitmap-clas

    import android.graphics.Bitmap;
    import android.graphics.Color;
    
    
    public class BitmapConvertor {
    
        private  byte[] Color_palette = new byte[1024]; //a palette containing 256 colors
       private   byte[] BMP_File_Header = new byte[14];
       private  byte[] DIB_header = new byte[40];
      private   byte[] Bitmap_Data = null;
    
    
        //returns a byte array of a grey scale bitmap image
        public    byte[] CreateGrayBitmapArray(Bitmap Image) {
            try {
                create_parts(Image);
                //Create the array
                byte[] bitmap_array = new byte[BMP_File_Header.length + DIB_header.length
                        + Color_palette.length + Bitmap_Data.length];
                Copy_to_Index(bitmap_array, BMP_File_Header, 0);
                Copy_to_Index(bitmap_array, DIB_header, BMP_File_Header.length);
                Copy_to_Index(bitmap_array, Color_palette, BMP_File_Header.length + DIB_header.length);
                Copy_to_Index(bitmap_array, Bitmap_Data, BMP_File_Header.length + DIB_header.length + Color_palette.length);
    
                return bitmap_array;
            } catch (Exception e) {
                return null; //return a null single byte array if fails
            }
        }
    
    
        //creates byte array of 256 color grayscale palette
        private   byte[] create_palette() {
            byte[] color_palette = new byte[1024];
            for (int i = 0; i < 256; i++) {
                color_palette[i * 4 + 0] = (byte) (i); //bule
                color_palette[i * 4 + 1] = (byte) (i); //green
                color_palette[i * 4 + 2] = (byte) (i); //red
                color_palette[i * 4 + 3] = (byte) 0; //padding
            }
            return color_palette;
        }
    
    
        //adds dtata of Source array to Destinition array at the Index
       private   boolean Copy_to_Index(byte[] destination, byte[] source, int index) {
            try {
                for (int i = 0; i < source.length; i++) {
                    destination[i + index] = source[i];
                }
                return true;
            } catch (Exception e) {
                return false;
            }
        }
    
    
        //create different part of a bitmap file
      private    void create_parts(Bitmap img) {
            //Create Bitmap Data
            Bitmap_Data = ConvertToGrayscale(img);
            //Create Bitmap File Header (populate BMP_File_Header array)
            Copy_to_Index(BMP_File_Header, new byte[]{(byte) 'B', (byte) 'M'}, 0); //magic number
            Copy_to_Index(BMP_File_Header, writeInt(BMP_File_Header.length
                    + DIB_header.length + Color_palette.length + Bitmap_Data.length), 2); //file size
            Copy_to_Index(BMP_File_Header, new byte[]{(byte) 'M', (byte) 'C', (byte) 'A', (byte) 'T'}, 6); //reserved for application generating the bitmap file (not imprtant)
            Copy_to_Index(BMP_File_Header, writeInt(BMP_File_Header.length
                    + DIB_header.length + Color_palette.length), 10); //bitmap raw data offset
            //Create DIB Header (populate DIB_header array)
            Copy_to_Index(DIB_header, writeInt(DIB_header.length), 0); //DIB header length
            Copy_to_Index(DIB_header, writeInt(((Bitmap) img).getWidth()), 4); //image width
            Copy_to_Index(DIB_header, writeInt(((Bitmap) img).getHeight()), 8); //image height
            Copy_to_Index(DIB_header, new byte[]{(byte) 1, (byte) 0}, 12); //color planes. N.B. Must be set to 1
            Copy_to_Index(DIB_header, new byte[]{(byte) 8, (byte) 0}, 14); //bits per pixel
            Copy_to_Index(DIB_header, writeInt(0), 16); //compression method N.B. BI_RGB = 0
            Copy_to_Index(DIB_header, writeInt(Bitmap_Data.length), 20); //lenght of raw bitmap data
            Copy_to_Index(DIB_header, writeInt(1000), 24); //horizontal reselution N.B. not important
            Copy_to_Index(DIB_header, writeInt(1000), 28); //vertical reselution N.B. not important
            Copy_to_Index(DIB_header, writeInt(256), 32); //number of colors in the palette
            Copy_to_Index(DIB_header, writeInt(0), 36); //number of important colors used N.B. 0 = all colors are imprtant
            //Create Color palett
            Color_palette = create_palette();
        }
    
    
        //convert the color pixels of Source image into a grayscale bitmap (raw data)
      private    byte[] ConvertToGrayscale(Bitmap Source) {
            Bitmap source = (Bitmap) Source;
            int padding = (source.getWidth() % 4) != 0 ? 4 - (source.getWidth() % 4) : 0; //determine padding needed for bitmap file
            byte[] bytes = new byte[source.getWidth() * source.getHeight() + padding * source.getHeight()]; //create array to contain bitmap data with paddin
            for (int y = 0; y < source.getHeight(); y++) {
                for (int x = 0; x < source.getWidth(); x++) {
                    int pixel = source.getPixel(x, y);
                    int g = (int) (0.3 * Color.red(pixel) + 0.59 * Color.green(pixel) + 0.11 * Color.blue(pixel)); //grayscale shade corresponding to rgb
                    bytes[(source.getHeight() - 1 - y) * source.getWidth() + (source.getHeight() - 1 - y) * padding + x] = (byte) g;
                }
                //add the padding
                for (int i = 0; i < padding; i++) {
                    bytes[(source.getHeight() - y) * source.getWidth() + (source.getHeight() - 1 - y) * padding + i] = (byte) 0;
                }
            }
            return bytes;
        }
    
    
        /**
         * Write integer to little-endian
         *
         * @param value
         * @return
         * @throws IOException
         */
        private  byte[] writeInt(int value) {
            byte[] b = new byte[4];
    
            b[0] = (byte) (value & 0x000000FF);
            b[1] = (byte) ((value & 0x0000FF00) >> 8);
            b[2] = (byte) ((value & 0x00FF0000) >> 16);
            b[3] = (byte) ((value & 0xFF000000) >> 24);
    
            return b;
        }
    }
    
    0 讨论(0)
  • 2020-12-01 20:19

    (I'm answering my own question)

    Here is my current solution. It is derived from this source : https://github.com/ultrakain/AndroidBitmapUtil (thanks to ultrakain and @Francescoverheye )

    I just fix a little bug in computation of the dummy bytes that must be added to each row (so that the length of each row in bytes is a multiple of 4 (as required by the bmp format specifications).

    I also made some changes to improve the performances.

    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.nio.ByteBuffer;
    
    import android.graphics.Bitmap;
    import android.util.Log;
    
    public class AndroidBmpUtil {
    
        private static final int BMP_WIDTH_OF_TIMES = 4;
        private static final int BYTE_PER_PIXEL = 3;
    
        /**
         * Android Bitmap Object to Window's v3 24bit Bmp Format File
         * @param orgBitmap
         * @param filePath
         * @return file saved result
         */
        public static boolean save(Bitmap orgBitmap, String filePath) throws IOException {
            long start = System.currentTimeMillis();
            if(orgBitmap == null){
                return false;
            }
    
            if(filePath == null){
                return false;
            }
    
            boolean isSaveSuccess = true;
    
            //image size
            int width = orgBitmap.getWidth();
            int height = orgBitmap.getHeight();
    
            //image dummy data size
            //reason : the amount of bytes per image row must be a multiple of 4 (requirements of bmp format)
            byte[] dummyBytesPerRow = null;
            boolean hasDummy = false;
            int rowWidthInBytes = BYTE_PER_PIXEL * width; //source image width * number of bytes to encode one pixel.
            if(rowWidthInBytes%BMP_WIDTH_OF_TIMES>0){
                hasDummy=true;
                //the number of dummy bytes we need to add on each row
                dummyBytesPerRow = new byte[(BMP_WIDTH_OF_TIMES-(rowWidthInBytes%BMP_WIDTH_OF_TIMES))];
                //just fill an array with the dummy bytes we need to append at the end of each row
                for(int i = 0; i < dummyBytesPerRow.length; i++){
                    dummyBytesPerRow[i] = (byte)0xFF;
                }
            }
    
            //an array to receive the pixels from the source image
            int[] pixels = new int[width * height];
    
            //the number of bytes used in the file to store raw image data (excluding file headers)
            int imageSize = (rowWidthInBytes+(hasDummy?dummyBytesPerRow.length:0)) * height;
            //file headers size
            int imageDataOffset = 0x36; 
    
            //final size of the file
            int fileSize = imageSize + imageDataOffset;
    
            //Android Bitmap Image Data
            orgBitmap.getPixels(pixels, 0, width, 0, 0, width, height);
    
            //ByteArrayOutputStream baos = new ByteArrayOutputStream(fileSize);
            ByteBuffer buffer = ByteBuffer.allocate(fileSize);
    
            /**
             * BITMAP FILE HEADER Write Start
             **/
            buffer.put((byte)0x42);
            buffer.put((byte)0x4D);
    
            //size
            buffer.put(writeInt(fileSize));
    
            //reserved
            buffer.put(writeShort((short)0));
            buffer.put(writeShort((short)0));
    
            //image data start offset
            buffer.put(writeInt(imageDataOffset));
    
            /** BITMAP FILE HEADER Write End */
    
            //*******************************************
    
            /** BITMAP INFO HEADER Write Start */
            //size
            buffer.put(writeInt(0x28));
    
            //width, height
            //if we add 3 dummy bytes per row : it means we add a pixel (and the image width is modified.
            buffer.put(writeInt(width+(hasDummy?(dummyBytesPerRow.length==3?1:0):0)));
            buffer.put(writeInt(height));
    
            //planes
            buffer.put(writeShort((short)1));
    
            //bit count
            buffer.put(writeShort((short)24));
    
            //bit compression
            buffer.put(writeInt(0));
    
            //image data size
            buffer.put(writeInt(imageSize));
    
            //horizontal resolution in pixels per meter
            buffer.put(writeInt(0));
    
            //vertical resolution in pixels per meter (unreliable)
            buffer.put(writeInt(0));
    
            buffer.put(writeInt(0));
    
            buffer.put(writeInt(0));
    
            /** BITMAP INFO HEADER Write End */
    
            int row = height;
            int col = width;
            int startPosition = (row - 1) * col;
            int endPosition = row * col;
            while( row > 0 ){
                for(int i = startPosition; i < endPosition; i++ ){
                    buffer.put((byte)(pixels[i] & 0x000000FF));
                    buffer.put((byte)((pixels[i] & 0x0000FF00) >> 8));
                    buffer.put((byte)((pixels[i] & 0x00FF0000) >> 16));
                }
                if(hasDummy){
                    buffer.put(dummyBytesPerRow);
                }
                row--;
                endPosition = startPosition;
                startPosition = startPosition - col;
            }
    
            FileOutputStream fos = new FileOutputStream(filePath);
            fos.write(buffer.array());
            fos.close();
            Log.v("AndroidBmpUtil" ,System.currentTimeMillis()-start+" ms");
    
            return isSaveSuccess;
        }
    
        /**
         * Write integer to little-endian
         * @param value
         * @return
         * @throws IOException
         */
        private static byte[] writeInt(int value) throws IOException {
            byte[] b = new byte[4];
    
            b[0] = (byte)(value & 0x000000FF);
            b[1] = (byte)((value & 0x0000FF00) >> 8);
            b[2] = (byte)((value & 0x00FF0000) >> 16);
            b[3] = (byte)((value & 0xFF000000) >> 24);
    
            return b;
        }
    
        /**
         * Write short to little-endian byte array
         * @param value
         * @return
         * @throws IOException
         */
        private static byte[] writeShort(short value) throws IOException {
            byte[] b = new byte[2];
    
            b[0] = (byte)(value & 0x00FF);
            b[1] = (byte)((value & 0xFF00) >> 8);
    
            return b;
        }
    }
    
    0 讨论(0)
  • 2020-12-01 20:20

    Note, the code above is very slow. I've found that to optimize the code above it's necessary to make a byte array to store all the data before you put it. Of course, I was working in Xamarin C# so maybe that's why. Anyway, here's my Xamarin code in case anyone has the same problem.

          public class AndroidBmpUtil
            {
    
                private static int BMP_WIDTH_OF_TIMES = 4;
                private static int BYTE_PER_PIXEL = 3;
    
                /**
                 * Android Bitmap Object to Window's v3 24bit Bmp Format File
                 * @param orgBitmap
                 * @param filePath
                 * @return file saved result
                 */
                public static byte[] ConvertAndroidBitmapByteArray(Bitmap orgBitmap, String filePath)
                {
                    if (orgBitmap == null)
                    {
                        return null;
                    }
    
                    if (filePath == null)
                    {
                        return null;
                    }
    
                    //image size
                    int width = orgBitmap.Width;
                    int height = orgBitmap.Height;
    
                    //image dummy data size
                    //reason : the amount of bytes per image row must be a multiple of 4 (requirements of bmp format)
                    byte[] dummyBytesPerRow = null;
                    bool hasDummy = false;
                    int rowWidthInBytes = BYTE_PER_PIXEL * width; //source image width * number of bytes to encode one pixel.
                    if (rowWidthInBytes % BMP_WIDTH_OF_TIMES > 0)
                    {
                        hasDummy = true;
                        //the number of dummy bytes we need to add on each row
                        dummyBytesPerRow = new byte[(BMP_WIDTH_OF_TIMES - (rowWidthInBytes % BMP_WIDTH_OF_TIMES))];
                        //just fill an array with the dummy bytes we need to append at the end of each row
                        for (int i = 0; i < dummyBytesPerRow.Length; i++)
                        {
                            dummyBytesPerRow[i] = (byte)0xFF;
                        }
                    }
    
                    //an array to receive the pixels from the source image
                    int[] pixels = new int[width * height];
    
                    //the number of bytes used in the file to store raw image data (excluding file headers)
                    int imageSize = (rowWidthInBytes + (hasDummy ? dummyBytesPerRow.Length : 0)) * height;
                    //file headers size
                    int imageDataOffset = 0x36;
    
                    //final size of the file
                    int fileSize = imageSize + imageDataOffset;
    
                    //Android Bitmap Image Data
                    orgBitmap.GetPixels(pixels, 0, width, 0, 0, width, height);
    
                    //ByteArrayOutputStream baos = new ByteArrayOutputStream(fileSize);
                    ByteBuffer buffer = ByteBuffer.Allocate(fileSize);
    
                    /**
                     * BITMAP FILE HEADER Write Start
                     **/
                    buffer.Put((sbyte)0x42);
                    buffer.Put((sbyte)0x4D);
    
                    //size
                    buffer.Put(writeInt(fileSize));
    
                    //reserved
                    buffer.Put(writeShort((short)0));
                    buffer.Put(writeShort((short)0));
    
                    //image data start offset
                    buffer.Put(writeInt(imageDataOffset));
    
                    /** BITMAP FILE HEADER Write End */
    
                    //*******************************************
    
                    /** BITMAP INFO HEADER Write Start */
                    //size
                    buffer.Put(writeInt(0x28));
    
                    //width, height
                    //if we add 3 dummy bytes per row : it means we add a pixel (and the image width is modified.
                    buffer.Put(writeInt(width + (hasDummy ? (dummyBytesPerRow.Length == 3 ? 1 : 0) : 0)));
                    buffer.Put(writeInt(height));
    
                    //planes
                    buffer.Put(writeShort((short)1));
    
                    //bit count
                    buffer.Put(writeShort((short)24));
    
                    //bit compression
                    buffer.Put(writeInt(0));
    
                    //image data size
                    buffer.Put(writeInt(imageSize));
    
                    //horizontal resolution in pixels per meter
                    buffer.Put(writeInt(0));
    
                    //vertical resolution in pixels per meter (unreliable)
                    buffer.Put(writeInt(0));
    
                    buffer.Put(writeInt(0));
    
                    buffer.Put(writeInt(0));
    
                    /** BITMAP INFO HEADER Write End */
                    int row = height;
                    int col = width;
                    int startPosition = (row - 1) * col;
                    int endPosition = row * col;
    
                    // This while loop is a lengthy process
                    // Puts take a while so only do one by creating a big array called final
                    byte[] final = new byte[0];
                    while (row > 0)
                    {
                        // This array is also used to cut down on time of puts
                        byte[] b = new byte[(endPosition - startPosition)*3];
                        int counter = 0;
                        for (int i = startPosition; i < endPosition; i++)
                        {
    
                            b[counter] = (byte)((pixels[i] & 0x000000FF));
                            b[counter + 1] = (byte)((pixels[i] & 0x0000FF00) >> 8);
                            b[counter + 2] = (byte)((pixels[i] & 0x00FF0000) >> 16);
                            counter += 3;
                        }
                        int finalPriorLength = final.Length;
                        Array.Resize<byte>(ref final, finalPriorLength + b.Length);
                        Array.Copy(b, 0, final, finalPriorLength, b.Length);
    
                        if (hasDummy)
                        {
                            finalPriorLength = final.Length;
                            Array.Resize<byte>(ref final, finalPriorLength + dummyBytesPerRow.Length);
                            Array.Copy(dummyBytesPerRow, 0, final, finalPriorLength, dummyBytesPerRow.Length);
                        }
                        row--;
                        endPosition = startPosition;
                        startPosition = startPosition - col;
                    }
                    buffer.Put(final);
                    buffer.Rewind();
    
                    IntPtr classHandle = JNIEnv.FindClass("java/nio/ByteBuffer");
                    IntPtr methodId = JNIEnv.GetMethodID(classHandle, "array", "()[B");
                    IntPtr resultHandle = JNIEnv.CallObjectMethod(buffer.Handle, methodId);
                    byte[] result = JNIEnv.GetArray<byte>(resultHandle);
                    JNIEnv.DeleteLocalRef(resultHandle);
    
                    return result;
                }
    
                /**
                 * Write integer to little-endian
                 * @param value
                 * @return
                 * @throws IOException
                 */
                private static byte[] writeInt(int value)
                {
                    byte[] b = new byte[4];
    
                    b[0] = (byte)(value & 0x000000FF);
                    b[1] = (byte)((value & 0x0000FF00) >> 8);
                    b[2] = (byte)((value & 0x00FF0000) >> 16);
                    b[3] = (byte)((value & 0xFF000000) >> 24);
    
                    return b;
                }
    
                /**
                 * Write short to little-endian byte array
                 * @param value
                 * @return
                 * @throws IOException
                 */
                private static byte[] writeShort(short value)
                {
                    byte[] b = new byte[2];
    
                    b[0] = (byte)(value & 0x00FF);
                    b[1] = (byte)((value & 0xFF00) >> 8);
    
                    return b;
                }
            }
        }
    

    To use it here's the calling code:

    using (FileStream outStream = new    FileStream(@yourFilePath, FileMode.Create))
    {
        Bitmap Signature = Bitmap.CreateBitmap(user defined values...); 
        byte[] buffer = AndroidBmpUtil.ConvertAndroidBitmapByteArray(Signature, @yourFilePath); 
    
        // Actually create the file                                 
        outStream.Write(buffer, 0, buffer.Length);
    }
    
    0 讨论(0)
  • 2020-12-01 20:27

    Unfortunately, the answers above didn't fully work for grayscale images, in my case. Not sure why.

    That's why I wrote this one (Additionally I'm using a ByteBuffer, because of the performance):

    import android.graphics.Bitmap;
    import android.util.Log;
    
    import java.io.FileOutputStream;
    import java.io.OutputStream;
    import java.nio.ByteBuffer;
    
    public class BmpFile {
        // Private constants
        private final static int BITMAPFILEHEADER_SIZE = 14;
        private final static int BITMAPINFOHEADER_SIZE = 40;
        // Private variable declaration
        // Bitmap file header
        private byte bitmapFileHeader[] = new byte[14];
        private byte bfType[] = {'B', 'M'};
        private int bfSize = 0;
        private int bfReserved1 = 0;
        private int bfReserved2 = 0;
        private int bfOffBits = BITMAPFILEHEADER_SIZE + BITMAPINFOHEADER_SIZE;
        // Bitmap info header
        private byte bitmapInfoHeader[] = new byte[40];
        private int biSize = BITMAPINFOHEADER_SIZE;
        private int biWidth = 0;
        private int biHeight = 0;
        private int biPlanes = 1;
        private int biBitCount = 24;
        private int biCompression = 0;
        private int biSizeImage = 0x030000;
        private int biXPelsPerMeter = 0x0;
        private int biYPelsPerMeter = 0x0;
        private int biClrUsed = 0;
        private int biClrImportant = 0;
        // Bitmap raw data
        private int pixels[];
        // File section
        private ByteBuffer buffer = null;
        private OutputStream outputStream;
    
        // Default constructor
        public BmpFile() {
        }
    
        public void saveBitmap(
            String parFilename,
            Bitmap bitmap
        ) {
            try {
                outputStream = new FileOutputStream(parFilename);
                save(bitmap);
                outputStream.close();
            } catch (Exception e) {
                Log.e("Exception", e.getMessage());
            }
        }
    
        public void saveBitmap(
            Bitmap bitmap,
            OutputStream outputStream
        ) {
            this.outputStream = outputStream;
            save(bitmap);
        }
    
        /*
         *  The saveMethod is the main method of the process. This method
         *  will call the convertImage method to convert the memory image to
         *  a byte array; method writeBitmapFileHeader creates and writes
         *  the bitmap file header; writeBitmapInfoHeader creates the
         *  information header; and writeBitmap writes the image.
         */
        private void save(
            Bitmap bitmap
        ) {
            try {
                convertImage(bitmap);
                writeBitmapFileHeader();
                writeBitmapInfoHeader();
                writeBitmap();
                // write to output stream
                outputStream.write(buffer.array());
            } catch (Exception e) {
                Log.e("Exception", e.getMessage());
            }
        }
    
        /*
         * convertImage converts the memory image to the bitmap format (BRG).
         * It also computes some information for the bitmap info header.
         */
        private boolean convertImage(
            Bitmap bitmap
        ) {
            int pad;
            int width = bitmap.getWidth();
            int height = bitmap.getHeight();
    
            pixels = new int[width * height];
    
            bitmap.getPixels(
                pixels,
                0,
                width,
                0,
                0,
                width,
                height);
    
            pad = (4 - ((width * 3) % 4)) * height;
            biSizeImage = ((width * height) * 3) + pad;
            bfSize = biSizeImage + BITMAPFILEHEADER_SIZE +
                BITMAPINFOHEADER_SIZE;
    
            buffer = ByteBuffer.allocate(bfSize);
            biWidth = width;
            biHeight = height;
            return (true);
        }
    
        /*
         * writeBitmap converts the image returned from the pixel grabber to
         * the format required. Remember: scan lines are inverted in
         * a bitmap file!
         * Each scan line must be padded to an even 4-byte boundary.
         */
        private void writeBitmap() {
            int size;
            int value;
            int j;
            int i;
            int rowCount;
            int rowIndex;
            int lastRowIndex;
            int pad;
            int padCount;
            byte rgb[] = new byte[3];
            size = (biWidth * biHeight) - 1;
            pad = 4 - ((biWidth * 3) % 4);
            if (pad == 4)   // Bug correction
                pad = 0;    // Bug correction
            rowCount = 1;
            padCount = 0;
            rowIndex = size - biWidth;
            lastRowIndex = rowIndex;
            try {
                for (j = 0; j < size; j++) {
                    value = pixels[rowIndex];
                    rgb[0] = (byte) (value & 0xFF);
                    rgb[1] = (byte) ((value >> 8) & 0xFF);
                    rgb[2] = (byte) ((value >> 16) & 0xFF);
                    buffer.put(rgb);
                    if (rowCount == biWidth) {
                        padCount += pad;
                        for (i = 1; i <= pad; i++) {
                            buffer.put((byte) 0x00);
                        }
                        rowCount = 1;
                        rowIndex = lastRowIndex - biWidth;
                        lastRowIndex = rowIndex;
                    } else
                        rowCount++;
                    rowIndex++;
                }
                // Update the size of the file
                bfSize += padCount - pad;
                biSizeImage += padCount - pad;
            } catch (Exception e) {
                Log.e("Exception", e.getMessage());
            }
        }
    
        /*
         * writeBitmapFileHeader writes the bitmap file header to the file.
         */
        private void writeBitmapFileHeader() {
            try {
                buffer.put(bfType);
                buffer.put(intToDWord(bfSize));
                buffer.put(intToWord(bfReserved1));
                buffer.put(intToWord(bfReserved2));
                buffer.put(intToDWord(bfOffBits));
            } catch (Exception e) {
                Log.e("Exception", e.getMessage());
            }
        }
    
        /*
         * writeBitmapInfoHeader writes the bitmap information header
         * to the file.
         */
        private void writeBitmapInfoHeader() {
            try {
                buffer.put(intToDWord(biSize));
                buffer.put(intToDWord(biWidth));
                buffer.put(intToDWord(biHeight));
                buffer.put(intToWord(biPlanes));
                buffer.put(intToWord(biBitCount));
                buffer.put(intToDWord(biCompression));
                buffer.put(intToDWord(biSizeImage));
                buffer.put(intToDWord(biXPelsPerMeter));
                buffer.put(intToDWord(biYPelsPerMeter));
                buffer.put(intToDWord(biClrUsed));
                buffer.put(intToDWord(biClrImportant));
            } catch (Exception e) {
                Log.e("Exception", e.getMessage());
            }
        }
    
        /*
         * intToWord converts an int to a word, where the return
         * value is stored in a 2-byte array.
         */
        private byte[] intToWord(
            int parValue
        ) {
            byte retValue[] = new byte[2];
            retValue[0] = (byte) (parValue & 0x00FF);
            retValue[1] = (byte) ((parValue >> 8) & 0x00FF);
            return (retValue);
        }
    
        /*
         * intToDWord converts an int to a double word, where the return
         * value is stored in a 4-byte array.
         */
        private byte[] intToDWord(
            int parValue
        ) {
            byte retValue[] = new byte[4];
            retValue[0] = (byte) (parValue & 0x00FF);
            retValue[1] = (byte) ((parValue >> 8) & 0x000000FF);
            retValue[2] = (byte) ((parValue >> 16) & 0x000000FF);
            retValue[3] = (byte) ((parValue >> 24) & 0x000000FF);
            return (retValue);
        }
    }
    
    0 讨论(0)
提交回复
热议问题