如果您的Image Control(如PictureBox)在运行时没有被用户移动(通过按住鼠标并拖动),您可以使用这种技术,让您可以在彼此之上显示图像。图片应具有透明背景:
public class ImageControl : Control {
public ImageControl(){
SetStyle(ControlStyles.Opaque, true);
}
public Image Image {get;set;}
protected override CreateParams CreateParams {
get {
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x20;
return cp;
}
}
protected override void OnPaint(PaintEventArgs e){
if(Image != null) e.Graphics.DrawImage(Image, Point.Empty);
}
}
您可以使用上面的控件代替PictureBox。通过在运行时拖动来移动此控件会导致大量闪烁。因此,如果您愿意,我认为只有 1 个使用 Region 的解决方案。在这种方法中,您必须将您的 Bitmap 转换为 Region 并将此 Region 分配给您的 Control.Region 属性。 Chris Dunaway 提供的链接对您执行此操作非常有帮助。但是我不得不说Region 的边框并不像您所期望的那样平滑。这是这种方法的不足之处。为方便起见,我将代码在这里稍作修改,此代码使用LockBits,这将优于原始代码:
public class Util {
//invert will toggle backColor to foreColor (in fact, I mean foreColor here is the Solid Color which makes your image distinct from the background).
public static Region RegionFromBitmap(Bitmap bm, Color backColor, bool invert)
{
Region rgn = new Region();
rgn.MakeEmpty();//This is very important
int argbBack = backColor.ToArgb();
BitmapData data = bm.LockBits(new Rectangle(0, 0, bm.Width, bm.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
int[] bits = new int[bm.Width * bm.Height];
Marshal.Copy(data.Scan0, bits, 0, bits.Length);
//
Rectangle line = Rectangle.Empty;
line.Height = 1;
bool inImage = false;
for (int i = 0; i < bm.Height; i++)
{
for (int j = 0; j < bm.Width; j++)
{
int c = bits[j + i * bm.Width];
if (!inImage)
{
if (invert ? c == argbBack : c != argbBack)
{
inImage = true;
line.X = j;
line.Y = i;
}
}
else if(invert ? c != argbBack : c == argbBack)
{
inImage = false;
line.Width = j - line.X;
rgn.Union(line);
}
}
}
bm.UnlockBits(data);
return rgn;
}
}
//Use the code
//if your Bitmap is a PNG with transparent background, you can get the Region from it like this:
Region rgn = Util.RegionFromBitmap(yourPng, Color.FromArgb(0), false);
//if your Bitmap has a figure with solid color of Black, you can get the Region like this:
Region rgn = Util.RegionFromBitmap(yourPng, Color.Black, true);