Similar articles can be seen on the internet, but more or less there are some problems. These two days to do the project of the laboratory to use this function, I have it sorted out from the beginning.
Before looking at the code, first explain a few questions.
The byte array holds the gray value of each pixel of the image, and the byte type happens to be from the 0~255, storing the 8bit grayscale image, an array element is the gray value of a pixel. Only this array is not enough to restore the original image, but also must know the length and width of the image in advance;
When creating a bitmap class, you must specify PixelFormat as Format8bppindexed, which is most consistent with the characteristics of the image itself;
Although the bitmap class provides methods such as GetPixel (), SetPixel (), we must not use these two methods for large-scale pixel reads and writes, because their performance is very embarrassing;
In managed code, you can try not to use unsafe. The BitmapData class and its lockbits (), unlockbits () operations have been provided in. NET 2.0 to enable safe memory reading and writing;
The width of the image is different from the stride when it is stored. The scan line width of a bitmap must be a multiple of 4, so the size of the image in memory is not the size of its display;
The format8bppindexed type of PixelFormat is indexed, its palette is not grayscale but pseudo color, so we need to modify it.
The code is as follows, and the commentary is written in the note:
1///<summary>
2///converts a byte array to a 8bit grayscale bitmap
3///</summary>
4///<param name= "rawvalues" > Display byte array </param>
5///<param name= "width" > Image width </param>
6///<param name= "height" > Image height </param>
7///<returns> Bitmap </returns>
8 public static Bitmap Tograybitmap (byte[] rawvalues, int width, int height)
9 {
10////The variable for the target bitmap and locks its memory area
One Bitmap bmp = new Bitmap (width, height, pixelformat.format8bppindexed);
BitmapData bmpdata = bmp. LockBits (New Rectangle (0, 0, width, height),
Imagelockmode.writeonly, pixelformat.format8bppindexed);
14
15////Get Image parameters
int stride = Bmpdata.stride; Width of scan Line
int offset = stride-width; Show the gap between width and scan line width
IntPtr iptr = bmpdata.scan0; Gets the memory start position of the Bmpdata
int scanbytes = Stride * height; Use stride width to indicate that this is the size of the memory area
20
21////The original display size byte array into an actual byte array in memory
int posscan = 0, posreal = 0; Set two position pointers, pointing to the source and destination arrays, respectively
byte[] pixelvalues = new Byte[scanbytes]; Allocating memory for the target array
24
for (int x = 0; x < height/x + +)
26 {
27////The following loop section is an analog row scan
for (int y = 0; y < width; y++)
29 {
pixelvalues[posscan++] = rawvalues [posreal++];
31}
Posscan + = offset; Row scan ends, move the target position pointer over the interval
33}
34
35////with the marshal copy method, copy the memory byte array just obtained into bitmapdata
System.Runtime.InteropServices.Marshal.Copy (pixelvalues, 0, Iptr, scanbytes);
Panax Notoginseng bmp. Unlockbits (Bmpdata); Unlock Memory Area
38
39////The following code is to modify the indexed table that generates bitmaps, from pseudo color to grayscale
ColorPalette Temppalette;
A using (Bitmap tempbmp = new Bitmap (1, 1, pixelformat.format8bppindexed))
42 {
Temppalette = Tempbmp.palette;
44}
for (int i = 0; i < 256; i++)
46 {
Temppalette.entries[i] = Color.FromArgb (i, I, I);
48}
49
BMP. Palette = Temppalette;
51
52////algorithm to this end, return the result
return to BMP;
54}