Xamarin Android 如何从位图创建 BMP
Xamarin Android How to create BMP from Bitmap
我想知道如何使用位图文件创建 BMP(已打开 png)
我试过了this
但它对我不起作用。
针对 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;
}
}
创建我的 BMP 花了很长时间(40 秒),创建时,它的八位字节大小为 0。
所以我需要帮助^^'
谢谢
图像无效修复:
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();
我想知道如何使用位图文件创建 BMP(已打开 png)
我试过了this 但它对我不起作用。
针对 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;
}
}
创建我的 BMP 花了很长时间(40 秒),创建时,它的八位字节大小为 0。
所以我需要帮助^^'
谢谢
图像无效修复:
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();