如题:::public static Region BitmapToRegion(Bitmap bitmap, Color transparencyColor)
{
if (bitmap == null)
throw new ArgumentNullException("Bitmap", "Bitmap cannot be null!"); int height = bitmap.Height;
int width = bitmap.Width; GraphicsPath path = new GraphicsPath(); for (int j = 0; j < height; j++)
for (int i = 0; i < width; i++)
{
if (bitmap.GetPixel(i, j) == transparencyColor)
continue; int x0 = i; while ((i < width) && (bitmap.GetPixel(i, j) != transparencyColor))
i++; path.AddRectangle(new Rectangle(x0, j, i - x0, 1));
} Region region = new Region(path);
path.Dispose();
return region;
}
{
if (bitmap == null)
throw new ArgumentNullException("Bitmap", "Bitmap cannot be null!"); int height = bitmap.Height;
int width = bitmap.Width; GraphicsPath path = new GraphicsPath(); for (int j = 0; j < height; j++)
for (int i = 0; i < width; i++)
{
if (bitmap.GetPixel(i, j) == transparencyColor)
continue; int x0 = i; while ((i < width) && (bitmap.GetPixel(i, j) != transparencyColor))
i++; path.AddRectangle(new Rectangle(x0, j, i - x0, 1));
} Region region = new Region(path);
path.Dispose();
return region;
}
解决方案 »
- 打包问题?
- 正则表达式问题!
- 弱弱的问什么是DLL 有什么作用
- object sender, EventArgs e 问题
- vs调试不了?并且在VS中打不开web.config的页面
- 你真正理解理对象吗?牛人面试题
- 急急急急急急急急急---调用Excel生成报表时的错误,因为配置类型不正确,系统无法开始服务器进程。请检查用户名和密码。
- 怎样用visual studio 2008打包基于.net framework 2.0的程序?
- 获取摄像头设备!
- c#书籍
- 怎么读取Excel.dll的元数据(类,接口,方法,属性,字段,事件)--反射Excel问题
- winform 窗体最大可以是多少?我的size 832, 780,我在变大了怎么变不了呢?
如下代码是优化了GetPixel()from
http://www.codeproject.com/cs/miscctrl/walkingrabbit.asp///<author>Arild Fines</author>
///<date>20.04.2002</date>
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;namespace BitmapToRegion
{ /// <summary>
/// determines the meaning of the transparencyKey argument to the Convert method
/// </summary>
public enum TransparencyMode
{
/// <summary>
/// the color key is used to define the transparent region of the bitmap
/// </summary>
ColorKeyTransparent,
/// <summary>
/// the color key is used to define the area that should _not_ be transparent
/// </summary>
ColorKeyOpaque
} /// <summary>
/// a class to convert a color-keyed bitmap into a region
/// </summary>
public class BitmapToRegion
{
/// <summary>
/// ctor made private to avoid instantiation
/// </summary>
private BitmapToRegion()
{}
/// <summary>
/// the meat of this class
/// converts the bitmap to a region by scanning each line one by one
/// this method will not affect the original bitmap in any way
/// </summary>
/// <param name="bitmap">The bitmap to convert</param>
/// <param name="transparencyKey">The color which will indicate either transparency or opacity</param>
/// <param name="mode">Whether the transparency key should indicate the transparent or the opaque region</param>
public unsafe static Region Convert( Bitmap bitmap, Color transparencyKey, TransparencyMode mode )
{
//sanity check
if ( bitmap == null )
throw new ArgumentNullException( "Bitmap", "Bitmap cannot be null!" ); //flag = true means the color key represents the opaque color
bool modeFlag = ( mode == TransparencyMode.ColorKeyOpaque );
GraphicsUnit unit = GraphicsUnit.Pixel;
RectangleF boundsF = bitmap.GetBounds( ref unit );
Rectangle bounds = new Rectangle( (int)boundsF.Left, (int)boundsF.Top,
(int)boundsF.Width, (int)boundsF.Height ); uint key = (uint)((transparencyKey.A << 24) | (transparencyKey.R << 16) |
(transparencyKey.G << 8) | (transparencyKey.B << 0));
//get access to the raw bits of the image
BitmapData bitmapData = bitmap.LockBits( bounds, ImageLockMode.ReadOnly,
PixelFormat.Format32bppArgb );
uint* pixelPtr = (uint*)bitmapData.Scan0.ToPointer(); //avoid property accessors in the for
int yMax = (int)boundsF.Height;
int xMax = (int)boundsF.Width; //to store all the little rectangles in
GraphicsPath path = new GraphicsPath(); for ( int y = 0; y < yMax; y++ )
{
//store the pointer so we can offset the stride directly from it later
//to get to the next line
byte* basePos = (byte*)pixelPtr; for ( int x = 0; x < xMax; x++, pixelPtr++ )
{
//is this transparent? if yes, just go on with the loop
if ( modeFlag ^ ( *pixelPtr == key ) )
continue; //store where the scan starts
int x0 = x; //not transparent - scan until we find the next transparent byte
while( x < xMax && !( modeFlag ^ ( *pixelPtr == key ) ) )
{
++x;
pixelPtr++;
} //add the rectangle we have found to the path
path.AddRectangle( new Rectangle( x0, y, x-x0, 1 ) );
}
//jump to the next line
pixelPtr = (uint*)(basePos + bitmapData.Stride);
} //now create the region from all the rectangles
Region region = new Region( path ); //clean up
path.Dispose();
bitmap.UnlockBits( bitmapData ); return region;
} }
}
RedTol: Byte=1; GreenTol: Byte=1; BlueTol: Byte=1): HRGN;
const
AllocUnit = 100;
type
PRectArray = ^TRectArray;
TRectArray = Array[0..(MaxInt div SizeOf(TRect))-1] of TRect;
var
pr: PRectArray; // used to access the rects array of RgnData by index
h: HRGN; // Handles to regions
RgnData: PRgnData; // Pointer to structure RGNDATA used to create regions
lr, lg, lb, hr, hg, hb: Byte; // values for lowest and hightest trans. colors
x,y, x0: Integer; // coordinates of current rect of visible pixels
b: PByteArray; // used to easy the task of testing the byte pixels (R,G,B)
ScanLinePtr: Pointer; // Pointer to current ScanLine being scanned
ScanLineInc: Integer; // Offset to next bitmap scanline (can be negative)
maxRects: Cardinal; // Number of rects to realloc memory by chunks of AllocUnit
begin
Result := 0;
{ Keep on hand lowest and highest values for the "transparent" pixels }
lr := GetRValue(TransparentColor);
lg := GetGValue(TransparentColor);
lb := GetBValue(TransparentColor);
hr := Min($ff, lr + RedTol);
hg := Min($ff, lg + GreenTol);
hb := Min($ff, lb + BlueTol);
{ ensures that the pixel format is 32-bits per pixel }
bmp.PixelFormat := pf32bit;
{ alloc initial region data }
maxRects := AllocUnit;
GetMem(RgnData,SizeOf(RGNDATAHEADER) + (SizeOf(TRect) * maxRects));
try
with RgnData^.rdh do
begin
dwSize := SizeOf(RGNDATAHEADER);
iType := RDH_RECTANGLES;
nCount := 0;
nRgnSize := 0;
SetRect(rcBound, MAXLONG, MAXLONG, 0, 0);
end;
{ scan each bitmap row - the orientation doesn't matter (Bottom-up or not) }
ScanLinePtr := bmp.ScanLine[0];
ScanLineInc := Integer(bmp.ScanLine[1]) - Integer(ScanLinePtr);
for y := 0 to bmp.Height - 1 do
begin
x := 0;
while x < bmp.Width do
begin
x0 := x;
while x < bmp.Width do
begin
b := @PByteArray(ScanLinePtr)[x*SizeOf(TRGBQuad)];
// BGR-RGB: Windows 32bpp BMPs are made of BGRa quads (not RGBa)
if (b[2] >= lr) and (b[2] <= hr) and
(b[1] >= lg) and (b[1] <= hg) and
(b[0] >= lb) and (b[0] <= hb) then
Break; // pixel is transparent
Inc(x);
end;
{ test to see if we have a non-transparent area in the image }
if x > x0 then
begin
{ increase RgnData by AllocUnit rects if we exceeds maxRects }
if RgnData^.rdh.nCount >= maxRects then
begin
Inc(maxRects,AllocUnit);
ReallocMem(RgnData,SizeOf(RGNDATAHEADER) + (SizeOf(TRect) * MaxRects));
end;
{ Add the rect (x0, y)-(x, y+1) as a new visible area in the region }
pr := @RgnData^.Buffer; // Buffer is an array of rects
with RgnData^.rdh do
begin
SetRect(pr[nCount], x0, y, x, y+1);
{ adjust the bound rectangle of the region if we are "out-of-bounds" }
if x0 < rcBound.Left then rcBound.Left := x0;
if y < rcBound.Top then rcBound.Top := y;
if x > rcBound.Right then rcBound.Right := x;
if y+1 > rcBound.Bottom then rcBound.Bottom := y+1;
Inc(nCount);
end;
end; // if x > x0
{ Need to create the region by muliple calls to ExtCreateRegion, 'cause }
{ it will fail on Windows 98 if the number of rectangles is too large }
if RgnData^.rdh.nCount = 2000 then
begin
h := ExtCreateRegion(nil, SizeOf(RGNDATAHEADER) + (SizeOf(TRect) * maxRects), RgnData^);
if Result > 0 then
begin // Expand the current region
CombineRgn(Result, Result, h, RGN_OR);
DeleteObject(h);
end
else // First region, assign it to Result
Result := h;
RgnData^.rdh.nCount := 0;
SetRect(RgnData^.rdh.rcBound, MAXLONG, MAXLONG, 0, 0);
end;
Inc(x);
end; // scan every sample byte of the image
Inc(Integer(ScanLinePtr), ScanLineInc);
end;
{ need to call ExCreateRegion one more time because we could have left }
{ a RgnData with less than 2000 rects, so it wasn't yet created/combined }
h := ExtCreateRegion(nil, SizeOf(RGNDATAHEADER) + (SizeOf(TRect) * MaxRects), RgnData^);
if Result > 0 then
begin
CombineRgn(Result, Result, h, RGN_OR);
DeleteObject(h);
end
else
Result := h;
finally
FreeMem(RgnData,SizeOf(RGNDATAHEADER) + (SizeOf(TRect) * MaxRects));
end;
end;
http://blog.sina.com.cn/u/589d32f5010009nf
private void Form1_Load(object sender, EventArgs e)
{
TransparencyKey = SystemColors.Control;
}//如果针对的只是Form(不是子窗体),那么建议用上面的方法合理些