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

How do I save pictureboxe with multiple overlapping pictureboxes?

提问人:LIKESCA 提问时间:11/17/2023 最后编辑:jpsLIKESCA 更新时间:11/17/2023 访问量:55

问:

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

这张照片就是我想要的enter image description here

尝试方法 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);
    }

在 picturebox1 上叠加 picturebox2

结果: enter image description here 失败

尝试方法 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);
    }

在图片框1中重绘

结果: enter image description here 失败

我希望这两张图片能够完美重叠并保存。有解决办法吗?

C# WinForms 图片框

评论

2赞 Jimi 11/17/2023
放弃第二个 PictureBox,并在位图中将两个图像一个接一个地绘制在另一个图像上。使用第一个 PictureBox 进行演示,然后将位图保存到磁盘(位图必须为 32bppARGB)

答:

1赞 IV. 11/17/2023 #1

据我了解,您希望在类似于流行的编辑应用程序的图层中绘制图片框。我们将制作自己的版本,并将其命名为 PictureShop。正如 Jimi 所说,你只需要一个,当你想在它上面绘制时,调用它的方法。它通过触发消息并提供画布进行响应。因此,如果我们将图像放在位图列表中,我们可以将图层相互叠加。显然这样做有问题,但这是一个开始。PictureBoxRefreshPaintGraphicsLayers

layers without transparency

/// <summary>
/// Add layer, then refresh PictureBox to draw.
/// </summary>
private void onButtonDrawClick(object? sender, EventArgs e)
{
    switch ( _clickCount++ ) 
    {
        case 0:
            Layers.Add((Bitmap)Bitmap.FromFile(Path.Combine(ImageFolder, "Image1.png")));
            break;
        case 1:
            Layers.Add((Bitmap)Bitmap.FromFile(Path.Combine(ImageFolder, "Image2.png")));
        break;
    }
    pictureBox1.Refresh();
}

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 执行类似操作,请让它替换顶部图像中的像素(如果颜色在值范围内)。

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

adjustable transparency

透明方式

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);
    }
}

评论

0赞 IV. 11/17/2023
克隆