Recently to the development platform, is studying C #. C # is good, but manipulating pixels in one pixel at a time is not generally slow. In fact, Delphi is the same, but fortunately, the Delphi bitmap class provides scanlines, you can read a row of the map, the efficiency is higher. C # should have similar stuff. After a search, finally found the BitmapData class.
Let's take a look at the example, which is to make up the FF for each pixel of a bitmap, and then output it to a new graph (the code is verbose, but it should be able to explain the problem).
int h = m_bmp.height;
int w = m_bmp.width;
Bitmap bmpout = new Bitmap (W, H, Pixelformat.format24bpprgb);
BitmapData datain = m_bmp.lockbits (new Rectangle (0,0,w,h), IMAGELOCKMODE.READONLY,PIXELFORMAT.FORMAT24BPPRGB);
BitmapData dataout = bmpout.lockbits (new Rectangle (0, 0, W, h), Imagelockmode.readwrite, Pixelformat.format24bpprgb );
Unsafe
{
byte* pIn = (byte*) (DataIn.Scan0.ToPointer ());
Byte * pout = (byte*) (DataOut.Scan0.ToPointer ()) ;
for (int y = 0; y < datain.height; y++)
{
for (int x = 0; x < datain.width x + +)
{
Pout[0] = (b Yte) (255-pin[0]);
Pout[1] = (byte) (255-pin[1]);
Pout[2] = (byte) (255-pin[2]);
PIn = 3;
Pout + 3;
}
PIn + + datain.stride-datain.width * 3;
Pout + + dataout.stride-dataout.width * 3;
}
}
Bmpout.unlockbits (dataout);
M_bmp.unlockbits (DataIn);
Seemingly more complex than Delphi, do I really naturally allergic to the needle? Or the better understanding of the Delphi is to scan each line, and then the current pixel point of three components to do processing, very convenient. And what is the stride in C # code?
Looking for a lot of information, now I understand this:
Suppose you have a picture with a width of 6 because it is in Format24bpprgb format (3 bytes per pixel). In the following discussion, unless otherwise stated, Bitmap is considered to be 24-bit RGB, and it is clear that each row needs 6*3=18 byte storage. This is true for bitmap. But for BitmapData, although Bitmapdata.width is still equal to bitmap.width, the actual number of bytes per row will become greater than or equal to its nearest 4, but presumably for the sake of display performance, the actual byte count is stride. For this example, 18 is not an integer multiple of 4, and a multiple of 4 from the nearest 18 to 18 is 20, so this bitmapdata.stride = 20. Obviously, when the width itself is a multiple of 4, Bitmapdata.stride = Bitmap.width * 3.
Drawing a picture may be better understood. R, G, B represent 3 primary color component bytes, BGR represents a pixel. In order to look convenient I inserted a space between each pixel, there is actually no. x represents the byte that is automatically inserted when a multiple of 4 is replenished. In order to conform to human reading habits I branch, in fact, in the computer memory should be seen as a large segment.
Scan0
---------Stride-----------------
---------Wide-------------Note: width is a picture (BGR as a unit)
BGR BGR BGR BGR BGR BGR XX
BGR BGR BGR BGR BGR BGR XX
.
.
.
It should be very well understood now. First, use Bitmapdata.scan0 to find the address of the No. 0 component of the No. 0 pixel. This address points to a byte type, so it was defined as a byte* pIn.
In row scans, three values (3 primary colors) are continuously removed at the current pointer position (which may be considered as the No. 0 color component of the current pixel). Note that the order of 0 1 2 is b G R. When you take the value that the pointer points to, it looks like p[n] and P = n p[0] is equivalent, and then moves down 3 positions (PIn + 3, as the No. 0 color component of the next pixel). Once you have done bitmap.width, you have reached the position of Bitmap.width * 3, you should skip the byte marked X in the figure (a total of Stride-width * 3 bytes), the code is the PIn = = DATAIN.STRIDE-DATAIN.W Idth * 3;
After skipping, the pointer reaches the NO. 0 pixel of the downlink. With this algorithm, a bitmap.height scan is required (the code is for (int y = 0; y < datain.height; y++)).
In addition, because of the use of unsafe, it is necessary to set "allow unsafe code" when compiling.