C # BitmapData usage tips

Source: Internet
Author: User

Recently I want to switch to the development platform, and I am studying C #. C # is good, but the operation pixel of one pixel and one pixel during image processing is not very slow. In fact, the same is true for Delphi. Fortunately, the Bitmap class of Delphi provides ScanLines to read images in one row, which is highly efficient. C # should have something similar. After some searches, we finally found the BitmapData class.

Let's take a look at the example. This is to add each pixel of a bitmap by FF, and then output it to a new image (the code is a bit wordy, but it should be clear ).

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] = (byte) (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 );


It seems much more complicated than Delphi. Is it true that I am naturally allergic to pointers? Delphi is better at understanding, that is, scanning each line and processing the three components of the current pixel, which is very convenient. What is Stride in C # code?

I have found a lot of information, so I understand it as follows:

Assume that the width of an image is 6, because the format is Format24bppRgb (3 bytes per pixel. In the following discussion, unless otherwise specified, Bitmap is considered to be a 24-bit RGB). Obviously, each row needs 6*3 = 18 bytes of storage. This is true for Bitmap. However, for BitmapData, although BitmapData. width is equal to Bitmap. width, but probably because of the display performance, the actual number of bytes in each line will be an integer greater than or equal to the 4 nearest to it, the actual number of bytes is Stride. In this example, 18 is not an integer multiple of 4, and the multiples of 4 closest to 18 are 20, so BitmapData. Stride = 20. Obviously, when the Width itself is a multiple of 4, BitmapData. Stride = Bitmap. Width * 3.

It may be better to draw a picture. R, G, and B represent three primary color component bytes, respectively. BGR represents one pixel. To make it look convenient, I inserted a space between each pixel, which is actually none. X indicates the number of automatically inserted bytes that multiply by 4. In order to meet the reading habits of humans, I am a branch. In fact, it should be regarded as a continuous segment in the computer memory.

Scan0
 
--------- Stride -----------------
--------- Width ------------- Note: Width is the Width of the image (BGR as a unit ).
BGR XX
BGR XX
.
.
.

It should be easy to understand now. First, use BitmapData. Scan0 to find the address of the 0th component in 0th pixels. This address points to a byte type, so it is defined as a byte * pIn.
During the row scan, three values (three primary color components) are taken consecutively at the current pointer position (0th color components of the current pixel. Note that 0 1 2 represents the order of B G R. When getting the pointer to the value, it seems that p [n] and p + = n and then p [0] are equivalent), and then move down three positions (pIn + = 3, it refers to the 0th color components of the next pixel ). Bitmap. after the Width operation, it reaches the Bitmap. the position of Width * 3 should be skipped from the byte marked as X in the figure (a total of three Stride-Width * bytes). The Code is pIn + = dataIn. stride-dataIn. width * 3;

After skipping, the pointer will reach the downstream 0th pixels. According to this algorithm, Bitmap. Height is required for a row scan (the code is for (int y = 0; y <dataIn. Height; y ++ )).

In addition, because unsafe is used, you need to set "allow Insecure code" during compilation ".

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.