script>
script>
BMP2RGN
script> transforms to Region for HBitmap in various colors.
HRGN Bitmaptoregion (Hbitmap HBMP, ColorRef CTransparentColor = 0, ColorRef CTolerance = 0x101010)
{
HRGN HRGN = NULL;
IF (HBMP)
{
// Create a Memory DC Inside Which We Will Scan The Bitmap Content
HDC HMEMDC = CreateCompatibleDC (NULL);
IF (HMEMDC)
{
// Get Bitmap Size
Bitmap BM;
GetObject (HBMP, SIZEOF (BM), & BM);
// Create A 32 Bits Depth Bitmap and SELECT IT INTO THE MEMORY DC
BitMapInfoHeader rgb32bitsbitmapinfo = {
Sizeof (BitmapInfoHeader), // bisize
BM.BMWIDTH, / / BIWIDTH;
BM.BMHEIGHT, / / BIHEIGHT;
1, // biplanes;
32, // BiBitcount
Bi_RGB, // bicompression;
0, // bisizeImage;
0, // Bixpelspermeter;
0, // biypelspermeter;
0, // biclrused;
0 // BICLRIMPORTANT;
}
Void * PBITS32;
Hbitmap HBM32 = Createdibsection (HMEMDC, (BitmapInfo *) & RGB32BitsbitmapInfo, DIB_RGB_COLORS, & PBITS32, NULL, 0);
IF (HBM32)
{
Hbitmap HoldBMP = (Hbitmap) SelectObject (HMEMDC, HBM32);
// Create a DC Just to Copy The Bitmap INTO The Memory DC
HDC HDC = CREATECOMPATIBLEDC (HMEMDC);
IF (HDC)
{
// Get How Many BYTES Per Row We Have for the Bitmap Bits (Rounded Up to 32 Bits)
Bitmap BM32;
GetObject (HBM32, SIZEOF (BM32), & BM32);
While (BM32.BMWIDTHBYTES% 4)
BM32.BMWIDTHBYTES ;
// Copy the Bitmap INTO THE MEMORY DC
Hbitmap HoldBMP = (HBitmap) SelectObject (HDC, HBMP);
Bitblt (HMEMDC, 0, 0, BM.BMWIDTH, BM.BMHEIGHT, HDC, 0, 0, SRCCopy);
// for Better Performances, We will use the xtcreateegength () Function to create the
// Region. This function take a rgndata structure on entry. We will add rectangles by
// Amount of Alloc_Unit Number in this structure.
#define alloc_Unit 100
DWORD MAXRECTS = Alloc_Unit;
Handle HData = Globalalloc (GMEM_MOVEABLE, SIZEOF (RGndataHeader) (SIZEOF (RECT) * MAXRECTS);
Rgndata * pdata = (rgndata *) Globalock (HDATA);
PDATA-> rdh.dwsize = sizeof (rgndatahead);
PDATA-> rdh.itype = rdh_rectangles;
PDATA-> rdh.ncount = pdata-> rdh.nrgnsize = 0;
SetRect (& PData-> Rdh.rcbound, Maxlong, Maxlong, 0, 0);
// Keep On Hand Highest and Lowest Values for the "Transparent" Pixels
BYTE LR = GtrValue (CTransparentColor);
Byte lg = getgvalue (cTransparentColor);
Byte lb = getBValue (CTransparentColor);
BYTE HR = min (0xFF, LR GETRVALUE (CTOLERANCE));
Byte hg = min (0xFF, LG GETGVALUE (CTOLERANCE));
BYTE HB = Min (0xFF, LB GetBValue (CTolerance));
// Scan Each Bitmap Row from bottom to TOP (The Bitmap is inverted Vertical)
BYTE * P32 = (Byte *) BM32.BMBITS (BM32.BMHEIGHT - 1) * BM32.BMWIDTHBYTES;
For (int y = 0; y { // Scan Each Bitmap Pixel from Left to Right For (int x = 0; x { // Search for a Continuous Range of "Non Transparent Pixels" INT x0 = x; Long * p = (long *) p32 x; While (x { BYTE B = GtrValue (* P); IF (B> = LR && B <= HR) { B = getGValue (* p); IF (b> = lg && b <= hg) { B = getBValue (* P); IF (b> = lb && b <= HB) // this pixel is "transparent" Break; } } P ; X ; } IF (x> x0) { // Add the Pixels (x0, y) to (x, y 1) AS A New Rectangle in the region IF (pdata-> rdh.ncount> = maxRECTS) { GlobalUnlock (HDATA); MaxRects = alloc_unit; HDATA = GlobalRealloc (HDATA, SIZEOF (RGndataHeader) (SIZEOF (RECT) * MAXRECTS, GMEM_MOVEABLE); PDATA = (rgndata *) GlobalLock (HDATA); } Rect * Pr = (Rect *) & pdata-> buffer; SetRect (& Pr [PDATA-> RDH.NCOUNT], X0, Y, X, Y 1); IF (x0 PDATA-> rdh.rcbound.Left = x0; IF (Y PDATA-> rdh.rcbound.top = y; IF (x> pdata-> rdh.rcbound.right) PDATA-> rdh.rcbound.right = x; IF (y 1> pdata-> rdh.rcbound.bottom) PDATA-> rdh.rcbound.bottom = y 1; PDATA-> RDH.NCOUNT ; // on windows98, extcreateregion () May Fail if the number of reccTangles is TOO // Large (IE:> 4000). Therefore, we have to create the region by Multiple Steps. IF (pdata-> rdh.ncount == 2000) { HRGN H = ExtcreateRegion (NULL, SIZEOF (RGNDATAHEADER) (SIZEOF (Rect) * MaxRects), PDATA); IF (hrgn) { Combinergn (HRGN, HRGN, H, RGN_OR); DeleteObject (h); } Else HRGN = H; PDATA-> rDH.NCOUNT = 0; SetRect (& PData-> Rdh.rcbound, Maxlong, Maxlong, 0, 0); } } } // Go to Next Row (Remember, The Bitmap is inverted Vertical) P32 - = BM32.BMWIDTHBYTES; } // Create or Extend the region with the remaining reccTangleshRGN H = ExtcreateREGON (NULL, SIZEOF (RGNDATAHEADER) (SIZEOF (RECT) * MAXRECTS, PDATA) IF (hrgn) { Combinergn (HRGN, HRGN, H, RGN_OR); DeleteObject (h); } Else HRGN = H; // Clean Up Globalfree (HDATA); SELECTOBJECT (HDC, HoldBMP); Deletedc (HDC); } DeleteObject (SELECTOBJECT (HMEMDC, HoldBMP); } Deletedc (HMEMDC); } } Return hrgn }