从透明表格上的图像中删除轮廓

Posted

技术标签:

【中文标题】从透明表格上的图像中删除轮廓【英文标题】:Remove outline from image on transparent form 【发布时间】:2021-12-21 07:29:22 【问题描述】:

我正在尝试将窗口形式转换为透明的,并使其仅显示一个对象。但它仍然在我的对象周围有一条线(笔划),它并不像我想要的那样完美。我怎样才能取出线(中风)? (附上图片对比。)

这是我的代码:

private void Form1_Load(object sender, EventArgs e)

    this.FormBorderStyle = FormBorderStyle.None;
    this.Width = this.pictureBox1.Width;
    this.Height = this.pictureBox1.Height;
    SetStyle(ControlStyles.SupportsTransparentBackColor, true);
    this.BackColor = Color.Black;
    this.TransparencyKey = this.pictureBox1.BackColor;

【问题讨论】:

很确定这与图像有关,而不是在代码中,图像本身有轮廓 您能发布有关图像格式的详细信息吗?所以我们可以知道它是否支持 alpha 通道,这将是最有可能导致这张图片出现边缘问题的原因,而没有像 png 文件那样正确的 alpha 通道。抗锯齿永远不会正确渲染。抗锯齿是您需要将弯曲边缘与背景混合,在透明背景的情况下,您需要 alpha 在边缘具有半透明不透明度来实现这一点,这只是因为您无法知道背景将是什么。跨度> 是的,格式文件是.png。我已经从互联网上获取了它。 pngmart.com/image/16212 边框像素很可能是半透明的。 TransparencyKey 不支持。您需要删除它们或将它们填充到 alpha=255。如果你需要一个例行程序来做到这一点,那就这么说吧.. 【参考方案1】:

您的图像具有半透明像素。 TransparencyKey 只会使 一种 颜色透明。所以边界像素会混合显示图像颜色和Parent 控件或表单的颜色..

这是一个通过使它们完全透明来消除所有半透明像素的功能:

using System.Runtime.InteropServices;
..

public static void UnSemi(Bitmap bmp)

    Size s = bmp.Size;
    PixelFormat fmt = bmp.PixelFormat;
    Rectangle rect = new Rectangle(Point.Empty, s);
    BitmapData bmpData = bmp.LockBits(rect, ImageLockMode.ReadOnly, fmt);
    int size1 = bmpData.Stride * bmpData.Height;
    byte[] data = new byte[size1];
    System.Runtime.InteropServices.Marshal.Copy(bmpData.Scan0, data, 0, size1);
    for (int y = 0; y < s.Height; y++)
    
        for (int x = 0; x < s.Width; x++)
        
            int index = y * bmpData.Stride + x * 4;
             // alpha,  threshold = 255
            data[index + 3] = (data[index + 3] < 255) ? (byte)0 : (byte)255; 
        
    
    System.Runtime.InteropServices.Marshal.Copy(data, 0, bmpData.Scan0, data.Length);
    bmp.UnlockBits(bmpData);

请注意,这也意味着漂亮的抗锯齿外观会变得有些粗糙......

还请注意,该例程假定为 32 位 ARGB 像素格式,正如 PNGs 通常具有的那样。

最后请注意,由于图像有 很多 Black,您应该选择不同的颜色。 Fuchsia在野外比较少见,但在龙的世界里可能没有,你想随便挑一些颜色..

另外:你想设置pictureBox1.BackColor = Color.Transparent..

最后:有时将threshold 参数添加到函数签名以设置打开或关闭alpha 的级别是有意义的。..

这是一个用法示例:

this.BackColor = Color.FromArgb(1,2,3,4);
this.TransparencyKey = this.BackColor;
UnSemi((Bitmap)this.pictureBox1.Image);

【讨论】:

还是不行。我什至尝试过透明的圆形,但没有任何改变。 :( 如果你不介意的话,你可以用c#快速创建一个,然后把那个文件发给我?所以我可以看到它。谢谢。 我确实试过了。虽然它并不像我希望的那样完美,但这段代码非常有帮助。谢谢你的帮助。你真棒! :D【参考方案2】:

使用具有透明背景的PNG图像 将您的控件/表单背景颜色和透明键设置为图像中不存在的颜色

【讨论】:

我做到了,但这是同样的问题。没有任何改变。

以上是关于从透明表格上的图像中删除轮廓的主要内容,如果未能解决你的问题,请参考以下文章

绘制 OpenCV 轮廓并保存为透明图像

如何使用JS将图像制作成具有透明背景的轮廓

从图像上的 alt 标记文本中删除边框

Java - 跟踪抽象形状的轮廓并使外部像素透明

如何从 Chart.js 中下载的图像中删除透明度

从图像中删除白色背景并使其透明