After three days of exploration, we finally succeeded in using known byte [] data to generate a bitmap (256-color grayscale BMP Bitmap ).
Many problems are encountered:
How to operate bitmap in C # (GDI +) to obtain various bitmap data, just like in C ++ |
How to modify the bitmap palette
How to solve the bitmap display dislocation problem, that is, the bitmap 4-byte alignment problem
How to use data to generate bitmap
To sum up, we hope to help our friends and avoid detours.
/// <Summary>
/// Use byte [] data to generate a 256-color grayscale BMP bitmap
/// </Summary>
/// <Param name = "originalimagedata"> </param>
/// <Param name = "originalwidth"> </param>
/// <Param name = "originalheight"> </param>
/// <Returns> </returns>
Public static bitmap createbitmap (byte [] originalimagedata, int originalwidth, int originalheight)
{
// Specify the 8-bit format, that is, the 256 color
Bitmap resultbitmap = new Bitmap (originalwidth, originalheight, system. Drawing. imaging. pixelformat. format8bppindexed );
// Save the bitmap to the memory
Memorystream curimagestream = new memorystream ();
Resultbitmap. Save (curimagestream, system. Drawing. imaging. imageformat. BMP );
Curimagestream. Flush ();
// Because the bitmap data requires DWORD alignment (4 byte multiple), the number of bits to be supplemented is calculated.
Int curpadnum = (originalwidth * 8 + 31)/32*4)-originalwidth;
// The size of the generated bitmap data
Int bitmapdatasize = (originalwidth * 8 + 31)/32*4) * originalheight;
// Start offset of the Data Part relative to the file. For details, refer to the bitmap file format.
Int dataoffset = readdata (curimagestream, 10, 4 );
// Change the color palette. Because the default color palette is 32-bit, you need to change it to the 256 color palette.
Int palettestart = 54;
Int paletteend = dataoffset;
Int color = 0;
For (INT I = palettestart; I <paletteend; I ++ = 4)
{
Byte [] tempcolor = new byte [4];
Tempcolor [0] = (byte) color;
Tempcolor [1] = (byte) color;
Tempcolor [2] = (byte) color;
Tempcolor [3] = (byte) 0;
Color ++;
Curimagestream. Position = I;
Curimagestream. Write (tempcolor, 0, 4 );
}
// The size and height of the generated bitmap data are not changed, and the width needs to be adjusted.
Byte [] destimagedata = new byte [bitmapdatasize];
Int destwidth = originalwidth + curpadnum;
// Generate the final bitmap data. Note that the bitmap data needs to be reversed from left to right and from bottom to top.
For (INT originalrowindex = originalheight-1; originalrowindex> = 0; originalrowindex --)
{
Int destrowindex = originalheight-originalrowindex-1;
For (INT dataindex = 0; dataindex <originalwidth; dataindex ++)
{
// Note that the width of the new bitmap data has changed to destwidth. Otherwise, a dislocation occurs.
Destimagedata [destrowindex * destwidth + dataindex] = originalimagedata [originalrowindex * originalwidth + dataindex];
}
}
// Move the stream position to the Data Segment
Curimagestream. Position = dataoffset;
// Write new bitmap data into memory
Curimagestream. Write (destimagedata, 0, bitmapdatasize );
Curimagestream. Flush ();
// Write bitmap in memory to bitmap object
Resultbitmap = new Bitmap (curimagestream );
Return resultbitmap;
}
/// <Summary>
/// Specify a location from the memory stream to read data
/// </Summary>
/// <Param name = "curstream"> </param>
/// <Param name = "startposition"> </param>
/// <Param name = "length"> </param>
/// <Returns> </returns>
Public static int readdata (memorystream curstream, int startposition, int length)
{
Int result =-1;
Byte [] tempdata = new byte [length];
Curstream. Position = startposition;
Curstream. Read (tempdata, 0, length );
Result = bitconverter. toint32 (tempdata, 0 );
Return result;
}
/// <Summary>
/// Write data to the specified location in the memory stream
/// </Summary>
/// <Param name = "curstream"> </param>
/// <Param name = "startposition"> </param>
/// <Param name = "length"> </param>
/// <Param name = "value"> </param>
Public static void writedata (memorystream curstream, int startposition, int length, int value)
{
Curstream. Position = startposition;
Curstream. Write (bitconverter. getbytes (value), 0, length );
}