如何保存具有多个重叠图片框的图片框?

问题描述 投票:0回答:1

我尝试将图片框和图片框分层保存 下面是当前表单的位置

这张图片就是我想要的

尝试方法1

public Form1()
    {
        InitializeComponent();
        pictureBox1.Controls.Add(pictureBox2);
        pictureBox2.Location = new Point(0, 0);
        pictureBox2.BackColor = Color.Transparent;
    }
 private void button1_Click(object sender, EventArgs e)
    { 
        string path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
        pictureBox1.Image.Save(path+"\\image.jpg",System.Drawing.Imaging.ImageFormat.Jpeg);
    }

将图片框2覆盖在图片框1上

结果: 失败

尝试方法2

private void pictureBox1_Paint(object sender, PaintEventArgs e)
    {
        Graphics g = e.Graphics;
        g.DrawImage(this.imageList1.Images[0], 50, 50,393,336);
    }
 private void button1_Click(object sender, EventArgs e)
    { 
        string path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
        pictureBox1.Image.Save(path+"\\image.jpg",System.Drawing.Imaging.ImageFormat.Jpeg);
    }

在 picturebox1 中重画

结果: 失败

我希望两个图像完美重叠并保存。有解决办法吗?

c# winforms picturebox
1个回答
0
投票

据我了解,您想要绘制图层中的图片框,类似于流行的编辑应用程序。我们将制作自己的版本并将其命名为 PictureShop。正如 Jimi 评论的那样,您只需要一个

PictureBox
,当您想要绘制时,请调用其
Refresh
方法。它通过触发
Paint
消息并提供
Graphics
画布来进行响应。因此,如果我们将图像放入
Layers
位图列表中,我们就可以在彼此之上绘制图层。显然这样做有一个问题,但这是一个开始。

private List<Bitmap> Layers { get; } = new List<Bitmap>();
private void onPicturebox1Paint(object? sender, PaintEventArgs e)
{
    foreach (var bmp in Layers)
    {
        e.Graphics.DrawImage(bmp, pictureBox1.ClientRectangle);
    }
}

如果我们使用“其他”应用程序,我们将转到顶层并可能使用魔棒选择顶部图像周围,并使其透明。要使 PictureShop 执行类似的操作,如果颜色落在某个值范围内,请让它替换顶部图像中的像素。

现在,“容差”滑块可让您在保存之前调整数量或透明度。

透明法

private Bitmap replaceColor(Bitmap bmp, Color targetColor, int tolerance)
{
    if(tolerance == 0) return bmp;
    var copy = new Bitmap(bmp);
    for (int x = 0; x < bmp.Width; x++)
    {
        for (int y = 0; y < copy.Height; y++)
        {
            Color pixelColor = copy.GetPixel(x, y);
            if (localIsWithinTolerance(pixelColor, targetColor, tolerance))
            {
                copy.SetPixel(x, y, Color.Transparent);
            }
        }
    }
    bool localIsWithinTolerance(Color pixelColor, Color targetColor, int tolerance)
    {
        return Math.Abs(pixelColor.R - targetColor.R) <= tolerance &&
                Math.Abs(pixelColor.G - targetColor.G) <= tolerance &&
                Math.Abs(pixelColor.B - targetColor.B) <= tolerance;
    }
    return copy;
}

新的绘画方法

private void onPicturebox1Paint(object? sender, PaintEventArgs e)
{
    Bitmap bmp;
    for (int i = 0; i < Layers.Count; i++) 
    {
        switch (i)
        {
            case 0:
                bmp = Layers[i];
                break;
            case 1:
                bmp = replaceColor(Layers[i], Color.FromArgb(0xF0, 0xF0, 0xF0), trackBarTolerance.Value);
                break;
            default:
                return;
        }
        e.Graphics.DrawImage(bmp, pictureBox1.ClientRectangle);
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.