简体   繁体   中英

Xamarin Android How to create BMP from Bitmap

I want to know how I can create a BMP with a bitmap file (png openned)

I tried this But it not working for me.

Updated for C# :

public class AndroidBmpUtil
{
    private readonly int BMP_WIDTH_OF_TIMES = 4;
    private readonly 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 bool Save(Bitmap orgBitmap, string filePath)
    {
        if (orgBitmap == null)
        {
            return false;
        }

        if (filePath == null)
        {
            return false;
        }

        var isSaveSuccess = true;

        //image size
        var width = orgBitmap.Width;
        var height = orgBitmap.Height;

        //image dummy data size
        //reason : bmp file's width equals 4's multiple
        var dummySize = 0;
        byte[] dummyBytesPerRow = null;
        var hasDummy = false;
        if (isBmpWidth4Times(width))
        {
            hasDummy = true;
            dummySize = BMP_WIDTH_OF_TIMES - width%BMP_WIDTH_OF_TIMES;
            dummyBytesPerRow = new byte[dummySize*BYTE_PER_PIXEL];
            for (var i = 0; i < dummyBytesPerRow.Length; i++)
            {
                dummyBytesPerRow[i] = 0xFF;
            }
        }

        var pixels = new int[width*height];
        var imageSize = pixels.Length*BYTE_PER_PIXEL + height*dummySize*BYTE_PER_PIXEL;
        var imageDataOffset = 0x36;
        var fileSize = imageSize + imageDataOffset;

        //Android Bitmap Image Data
        orgBitmap.GetPixels(pixels, 0, width, 0, 0, width, height);

        //ByteArrayOutputStream baos = new ByteArrayOutputStream(fileSize);
        var buffer = ByteBuffer.Allocate(fileSize);

        try
        {
            /**
             * BITMAP FILE HEADER Write Start
             **/
            buffer.Put(0x42);
            buffer.Put(0x4D);

            //size
            buffer.Put(WriteInt(fileSize));

            //reserved
            buffer.Put(WriteShort(0));
            buffer.Put(WriteShort(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
            buffer.Put(WriteInt(width));
            buffer.Put(WriteInt(height));

            //planes
            buffer.Put(WriteShort(1));

            //bit count
            buffer.Put(WriteShort(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 */

            var row = height;
            var col = width;
            var startPosition = 0;
            var endPosition = 0;

            while (row > 0)
            {
                startPosition = (row - 1)*col;
                endPosition = row*col;

                for (var i = startPosition; i < endPosition; i++)
                {
                    buffer.Put(Write24BitForPixcel(pixels[i]));

                    if (hasDummy)
                    {
                        if (isBitmapWidthLastPixcel(width, i))
                        {
                            buffer.Put(dummyBytesPerRow);
                        }
                    }
                }
                row--;
            }

            var fos = new FileOutputStream(filePath);
            fos.Write(new byte[buffer.Remaining()]);
            fos.Close();
        }
        catch (Exception e1)
        {
            isSaveSuccess = false;
        }
        finally
        {
        }

        return isSaveSuccess;
    }

    /**
     * Is last pixel in Android Bitmap width  
     * @param width
     * @param i
     * @return
     */

    private bool isBitmapWidthLastPixcel(int width, int i)
    {
        return i > 0 && i%(width - 1) == 0;
    }

    /**
     * BMP file is a multiples of 4?
     * @param width
     * @return
     */

    private bool isBmpWidth4Times(int width)
    {
        return width%BMP_WIDTH_OF_TIMES > 0;
    }

    /**
     * Write integer to little-endian 
     * @param value
     * @return
     * @throws IOException
     */

    private byte[] WriteInt(int value)
    {
        var 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 integer pixel to little-endian byte array
     * @param value
     * @return
     * @throws IOException
     */

    private byte[] Write24BitForPixcel(int value)
    {
        var
            b = new byte[3];

        b[0] = (byte) (value & 0x000000FF);
        b[1] = (byte) ((value & 0x0000FF00) >> 8);
        b[2] = (byte) ((value & 0x00FF0000) >> 16);

        return b;
    }

    /**
     * Write short to little-endian byte array
     * @param value
     * @return
     * @throws IOException
     */

    private byte[] WriteShort(short value)
    {
        var
            b = new byte[2];

        b[0] = (byte) (value & 0x00FF);
        b[1] = (byte) ((value & 0xFF00) >> 8);

        return b;
    }
}

It took so long time (40s) to create my BMP, and when it is created, it have 0 octet size.

So I need help ^^'

Thanks

Image is null fix:

var fos = new FileOutputStream(filePath); 
//fos.Write(new byte[buffer.Remaining()]); 
byte[] bmpData=new byte[buffer.Position()]; 
buffer.Position(0); //or buffer.Flip();
buffer.Get(bmpData, 0, buffer.Remaining()); 

fos.Write(bmpData); 
fos.Close();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM