Naografix Naografix - 1 month ago 16
Android Question

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

Answer

Image is null fix:

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

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