Lockbits in GDI +
Release date: March 31,201 1 Classification: Technology
Once efficiency is pursued, the underlying operations are still required. For example, to directly operate bitmap data in GDIGetDIBits
/SetDIBits
(Or the discardedGetBitmapBits
/SetBitmapBits
). Because most recently we have to deal with PNG images that cannot be processed by GDI, we still use GDI +. Direct operation in GDI +Bitmap
Data is requiredLockBits
/UnlockBits
.
First SightBitmap::LockBits
I am dizzy with the statement:
Status LockBits(const Rect *rect, UINT flags, PixelFormat format, BitmapData *lockedBitmapData);
But to be honest, the style of the entire GDI + Library is fresh and refined compared with other libraries of M $.
-
rect
-
Generally, the entire image size is locked in the rectangular area to be locked. (Tucao: cannot be passed for Shenma
NULL
Go in to show the full graph ~)
-
flags
-
In the locked area, you must perform read or write operations and determine whether to allocate a buffer. (Not pleasing to the eye
UINT
The type value is actually
enum
)
-
format
-
The pixel format required for the locked area. If the format of the locked area is inconsistent with that of the image, GDI + will automatically convert the image.
-
lockedBitmapData
-
Output locked area information and member variables
Scan0
Will point to the locked pixel area (if
flags
If you specify your own buffer allocation
Scan0
Refers to the buffer to write data ).
To lock the full image and read it:
int w = bmp->GetWidth();int h = bmp->GetHeight();BitmapData bmpData;bmp->LockBits(Rect(0, 0, w, h), ImageLockModeRead, PixelFormat32bppARGB, &bmpData);
After locking the image area, you can obtainBitmapData
.BitmapData
Contains the length, width, format, and pointer information of the locked area. The pixel color of the coordinate (x, y) can be used:
unsigned int *pData = reinterpret_cast<unsigned int *>(bmpData.Scan0);int stride = bmpData.Stride;unsigned int color = pData[y * stride / 4 + x]; // color= 0xAARRGGBB
There is a specialStride
It indicates the number of bytes occupied by the buffer corresponding to the "One Line" image (because bitmap files have an abnormal rule: when the image data is stored, the number of bytes in each row must be a multiple of 4. If the actual image data width is not a multiple of 4, you must use junk data to complete the insufficient number of bytes.Stride
=Width
Is called byte alignment ).
Remember to unlock the locked area after the image data operation is complete:
bmp->UnlockBits(&bmpData);
In this way, the merits are fulfilled.
Hmm ~ This is the case with this note. This is a meaningful day ~
Self-supplied Buffer
Keke ~ I have been writing this article for more than half a year. I found some useful stuff when I carefully read the document of GDI +.
As you can see 「LockBits
→ Read/writebmpData.San0
→UnlockBits
The trilogy is not similarGetDIBits
/SetDIBits
Completely matched. At least the latter reads data directly from the bitmap to the color buffer we provide, and writes the data directly from the color buffer to the in-place graph, however, the former requires manual switching of one row or even one pixel after the lock.
The good news isBitmap::LockBits
Offlags
In additionImageLockModeRead
AndImageLockModeWrite
You can alsoImageLockModeUserInputBuf
. This flag indicates thatLockBits
UseBitmapData
Instead of allocating and reading the buffer information.
Example
Int W = BMP-> getwidth (); int H = BMP-> getheight (); unsigned int * buffer = new unsigned int [w * H * 4]; // buffer, read bitmapdata BMP data in 32-bit argb mode. width = W; BMP data. height = H; BMP data. stride = W * 4; // the size of each row in the buffer zone. It is allocated on its own and no extra bytes are generated for each row. scan0 = buffer; BMP data. pixelformat = pixelformat32bppargb; BMP data. reserved = NULL; BMP-> lockbits (rect (0, 0, W, h), imagelockmoderead | imagelockmodeuserinputbuf, pixelformat32bppargb, & BMP data); BMP-> unlockbits (& BMP data );