Description required
Some irregular images need to be synthesized in the project, and an irregular PNG Image (for example, a circular image with a white circle in the middle and a transparent area outside) is provided ), the user image needs to be cropped in the white area and the efficiency is not less than 1 s.
Solution
The Region Polygon Area in. net is used for collecting and cropping, And the win32 api is used: gdi32.dll.
Sample Code
// Regional collection function
Public static region imagetoregion (image aimage, color atransparent)
{
If (aimage = NULL) return NULL;
Bitmap vbitmap = new Bitmap (aimage );
Bitmapdata vbitmapdata = vbitmap. lockbits (New rectangle (0, 0, vbitmap. Width, vbitmap. Height), imagelockmode. readonly, pixelformat. format32bpprgb );
Int vAddress = (int) vBitmapData. Scan0;
Int vOffset = vBitmapData. Stride-vBitmap. Width * 4; // The number of extra bytes in each row
Int h = vBitmap. Height, w = vBitmap. Width;
Int vTransparent = ColorTranslator. ToWin32 (ATransparent); // transparent color
Int vAllocRect = (0x1000-sizeof (uint) * 8)/sizeof (int); // Number of pre-allocated rectangles
If (h * w <vAllocRect) vAllocRect = h * w;
Byte [] vBuffer = new byte [sizeof (uint) * 8 + sizeof (int) * 4 * vAllocRect];
// Header information dwSize \ iType \ nCount \ nRegSize
Uint vCount = 0;
VBuffer [0] = sizeof (uint) * 8; // dwSize // header information size
VBuffer [4] = 1; // iType // int RDH_RECTANGLES = 1; // data type
IntPtr vResult = IntPtr. Zero;
Uint vPointer = sizeof (uint) * 8;
Bool vWriteRect = false;
Bool vWriteAlways = false;
For (int y = 0; y {
Int vBlockStart = 0;
Bool vLastMaskBit = false;
For (int x = 0; x <w; x ++)
{
Int I = Marshal. ReadInt32 (IntPtr) vAddress) & 0x00FFFFFF;
If (I = 0) // transparent (the black area will also be recognized as transparent)
{
If (vLastMaskBit)
VWriteRect = true;
}
Else
{
If (! VLastMaskBit)
{
VBlockStart = x;
VLastMaskBit = true;
}
}
If (x = w-1)
{
If (y = h-1)
{
VWriteRect = true;
VWriteAlways = true;
}
Else if (vLastMaskBit)
{
VWriteRect = true;
}
X ++;
}
If (vWriteRect)
{
If (vLastMaskBit)
{
VCount ++;
WriteRect (vBuffer, ref vPointer, new Rectangle (vBlockStart, y, x-vBlockStart, 1 ));
}
If (vCount = vAllocRect | vWriteAlways)
{
VBuffer [8] = (byte) vCount;
VBuffer [9] = (byte) (vCount> 8 );
VBuffer [10] = (byte) (vCount> 16 );
Vbuffer [11] = (byte) (vcount> 24 );
Intptr htemp = extcreateregion (intptr. Zero,
Sizeof (uint) * 8 + sizeof (INT) * 4 * vcount,
Ref vbuffer [0]);
If (vResult = IntPtr. Zero)
VResult = hTemp;
Else
{
CombineRgn (vResult, vResult, hTemp, RGN_OR );
DeleteObject (hTemp );
}
VCount = 0;
VPointer = sizeof (uint) * 4;
VWriteAlways = false;
}
VWriteRect = false;
VLastMaskBit = false;
}
Vaddress + = 4;
}
Vaddress + = voffset;
}
Vbitmap. unlockbits (vbitmapdata );
Return region. fromhrgn (vresult );
}
// Crop the image according to the specified Cropping Area
Public static Bitmap CutRegionImage (Bitmap B, Region region)
{
Graphics g = System. Drawing. Graphics. FromImage (B );
// Obtain the region boundary
RectangleF validRect = region. GetBounds (g );
Int x = (int) validRect. X;
Int y = (int) validRect. Y;
Int width = (int) validRect. Width;
Int height = (int) validRect. Height;
// Pan the area
Region validRegion = region;
ValidRegion. Translate (-x,-y );
Bitmap dstImage = new Bitmap (width, height );
Graphics dstGraphics = System. Drawing. Graphics. FromImage (dstImage );
// Set the editing area
DstGraphics. SetClip (validRegion, CombineMode. Replace );
// Drawing
Dstgraphics. drawimage (B, new rectangle (0, 0, width, height ),
Validrect, graphicsunit. pixel );
G. Dispose ();
Dstgraphics. Dispose ();
B. Dispose ();
Return dstimage;
}
// Call the Function Definition of Win32 API
[Dllimport ("gdi32.dll")]
Public static extern IntPtr ExtCreateRegion (IntPtr lpXform, uint nCount,
Ref byte lpRgnData );
[DllImport ("gdi32.dll")]
Public static extern int CombineRgn (IntPtr hrgnDest, IntPtr hrgnSrc1, IntPtr hrgnSrc2,
Int fnCombineMode );
[DllImport ("gdi32.dll")]
Public static extern bool DeleteObject (IntPtr hObject );
Result
Complete code
/Files/ruimingde/PngImage.txt