以编程方式确定图像的背景(徽标等)并使其透明?

发布于 2024-11-09 07:29:26 字数 749 浏览 4 评论 0原文

我正在尝试编写一个解决方案,以便我的用户可以使用他们的公司徽标在他们的图像上“加水印”。我已经完成了实际的水印部分并正在工作,所以现在我正在创建“上传徽标”功能,以便他们可以向我提供他们希望在其图像上显示水印的徽标。

我正在使用 VB.NET,这可能最终会出现在接受徽标 JPG 文件并返回“更改的”徽标的 Web 服务中。我在此 Web 服务中需要做的是:

1)对图像进行灰度化。感谢这篇文章,我也可以使用它。

2) 使背景透明(这样当水印到图像上时徽标看起来很干净)。这就是我被困住的地方。

我认为在大多数情况下,上传的任何徽标都将具有通用的白色背景,但我不能假设这一点。有没有办法以某种方式检测图像的背景背景颜色,以便我可以使这些颜色透明?

我已经从 code.google.com 下载并运行了这个项目,名为 Transpoint,它是几乎是我所需要的,只是我无法将其作为独立的应用程序。另外,我认为这是用 Python 编写的,这对我来说很陌生。

所以基本上我需要的只是一种确定图像背景的方法(如果可能的话?),甚至只是背景颜色,以便我可以使它们透明。任何帮助/建议/建议将不胜感激!

谢谢, 劳埃德

I'm attempting to write a solution so that my user's can "watermark" their Images with their Company Logo. I've got the actual watermarking part done and working so now I'm creating the "upload logo" feature so that they can provide me with the Logo they wish to appear watermarked onto their Images.

I'm using VB.NET and this will probably end up in a Web Service that accepts the Logo JPG file, and returns the "altered" Logo. What I need to happen in this Web Service is:

1) Gray-scale the image. Which I have working as well, thanks to this article.

2) Make the background transparent (so the logo looks clean when watermarked onto an image). This is where I'm stuck.

I think for the most part, any logos that are uploaded will have a generic white background but I can't assume that. Is there a way to somehow detect the background of an image or the background colors, so that I may make those colors transparent?

I've downloaded and ran this project from code.google.com, called Transpoint, which is pretty much what I need except I won't be able to have this as a stand-alone app. Also, I think this is written in Python which is foreign to me.

So basically what I need is just a way to determine the background on an Image (if that's even possible?) or even just the background colors so that I may make them transparent. Any help/advice/suggestions would be greatly appreciated!

Thanks,
Lloyd

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

ぽ尐不点ル 2024-11-16 07:29:26

您可以执行类似读取左上角像素并假设该像素代表背景颜色的操作,然后迭代图像并将每个匹配像素(按颜色匹配)的 alpha 值设置为 0。

我几乎可以然而,我向你保证,结果将会很糟糕。为了使透明度正常工作并且看起来不错,图像需要支持部分透明度,使得某些像素完全透明,而某些像素仅部分透明。任何采用不透明图像并仅将图像中的一种颜色设置为完全透明的算法最终都会出现锯齿状边缘。

我接触过的大多数公司都有由专业艺术家制作的徽标版本,具有平滑、部分透明的效果。仅仅要求客户提交具有透明度的徽标比尝试使用代码将不透明图像变成透明图像要好得多。抱歉,但这行不通。

You could do something like reading the upper-left pixel and assuming that that pixel is representative of the background color, and then iterating through the image and setting the alpha value of each matching pixel (matching by color) to 0.

I can pretty much guarantee you, however, that the result will be awful. For transparency to work properly and look good, the image needs to support partial transparency, such that some pixels are completely transparent whereas some are only partially transparent. Any algorithm that takes a non-transparent image and sets only one color in the image to fully transparent is going to end up with jagged edges.

Most companies I've ever dealt with have versions of their logos done by professional artists, with smooth, partial transparency. You'd be much better off just requiring customers to submit a logo with transparency than trying to make a non-transparent image into a transparent one with code. Sorry, but this just doesn't work.

滥情空心 2024-11-16 07:29:26

我认为这实际上可行(抱歉,这只是一个描述):

假设左上角像素是图像的背景颜色,您可以迭代图像中的每个像素,如果像素颜色与背景颜色匹配,则将 alpha 设置为 0 (精确地或在某个阈值颜色距离内)。当您在不同颜色的背景上重新绘制它时,这将为您留下一个具有透明背景但锯齿状边缘的图像。另外,如果背景颜色出现在图像本身内部的任何位置,它将变成透明,这是您不希望的。

要解决后一个问题,您的算法应该从左到右开始扫描图像的每一行,并在到达非背景颜色像素时停止;此时它应该从同一行开始并从右到左扫描,直到到达非背景像素。

要修复边缘,您只需模糊位图的 Alpha 值即可。基本上,您将每个像素的 alpha 值重新计算为 9 个像素(本身及其周围的 8 个像素,并且只是 alpha 值 - 而不是 rgb 值)的平均值。为了防止排序伪影,您需要一个临时数组来存储平均像素值,然后在过程结束时将其复制回图像的 Alpha 值。

此外,可能有一个或多个第三方工具可以执行此操作(LEAD Tools 仍然存在吗?)。

I think this would actually work (sorry it's just a description):

Assuming the upper-left corner pixel is the image's background color, you could iterate through each pixel in the image and set the alpha to 0 if the pixel color matches the background color (either exactly or within some threshold color distance). This would then leave you with an image with a transparent background but jagged edges when you re-draw it on a different-color background. Also, if the background color is present anywhere inside the image itself, it will be turned transparent, which you don't want.

To fix the latter problem, your algorithm should start scanning each row of the image from left to right, and stop when it reaches a non-background color pixel; at this point it should start on the same row and scan right to left until reaching a non-bg pixel.

To fix the edges, you can just blur the alpha values of the bitmap. Basically, you re-calculate the alpha value of each pixel as the average of 9 pixels (itself and the 8 pixels surrounding it, and just the alpha values - not the rgb values). To prevent sequencing artifacts, you would have a temporary array to store the averaged pixel values, which you would then copy back into the image's alpha values at the end of the process.

Also, there's probably one or more third-party tools that do this (is LEAD Tools still around?).

被翻牌 2024-11-16 07:29:26

@MusiGenesis(以及其他可能感兴趣的人)这是我为(某种程度上)解决我的问题所做的事情。我基本上遵循了你前半部分的想法。我创建了一个函数,它将接受位图,对照 (0,0) 处的第一个像素检查每个像素 - 对每种 RGB 颜色使用 10 的阈值。对于该阈值内的每种颜色,像素都会变得透明。这是我的代码,对于我尝试过的几张图像来说似乎可以正常工作:

Private Function TransparifyBackground(ByVal bmp As Bitmap) As Bitmap

        Dim temp As Color

        Dim background As Color = bmp.GetPixel(0, 0) 'top left will be assumed background color

        For y As Integer = 0 To bmp.Height - 1
            For x As Integer = 0 To bmp.Width - 1

                'get the pixel for this position:
                temp = bmp.GetPixel(x, y)

                If ColorsMatch(background, temp) Then

                    'Make the Alpha value 50 for each pixel, leaving the other colors
                    Dim newColor As New Color
                    newColor = Color.Transparent

                    bmp.SetPixel(x, y, newColor)

                End If

            Next
        Next

        Return bmp

    End Function

    Private Function ColorsMatch(ByVal background As Color, ByVal temp As Color) As Boolean

        Dim nThreshold As Integer = 10

        Dim temp_R As Integer = CInt(temp.R)
        Dim temp_G As Integer = CInt(temp.G)
        Dim temp_B As Integer = CInt(temp.B)

        Dim R As Integer = CInt(background.R)
        Dim G As Integer = CInt(background.G)
        Dim B As Integer = CInt(background.B)

        'check the difference of each value against our threshold:
        If ((temp_R - R) < nThreshold) AndAlso ((temp_G - G) < nThreshold) AndAlso ((temp_B < B) < nThreshold) Then
            Return True
        Else
            Return False
        End If

    End Function

@MusiGenesis (and anyone else who may be interested) here is what I did to (kind of) solve my problem. I basically followed the first half of your idea. I've created a function that will accept a bitmap, check each pixel against the first pixel at (0,0) - using a threshold of 10 for each RGB color. For each color within that threshold, the pixel is made transparent. Here is my code, which seems to work alright for the few images I've tried it with:

Private Function TransparifyBackground(ByVal bmp As Bitmap) As Bitmap

        Dim temp As Color

        Dim background As Color = bmp.GetPixel(0, 0) 'top left will be assumed background color

        For y As Integer = 0 To bmp.Height - 1
            For x As Integer = 0 To bmp.Width - 1

                'get the pixel for this position:
                temp = bmp.GetPixel(x, y)

                If ColorsMatch(background, temp) Then

                    'Make the Alpha value 50 for each pixel, leaving the other colors
                    Dim newColor As New Color
                    newColor = Color.Transparent

                    bmp.SetPixel(x, y, newColor)

                End If

            Next
        Next

        Return bmp

    End Function

    Private Function ColorsMatch(ByVal background As Color, ByVal temp As Color) As Boolean

        Dim nThreshold As Integer = 10

        Dim temp_R As Integer = CInt(temp.R)
        Dim temp_G As Integer = CInt(temp.G)
        Dim temp_B As Integer = CInt(temp.B)

        Dim R As Integer = CInt(background.R)
        Dim G As Integer = CInt(background.G)
        Dim B As Integer = CInt(background.B)

        'check the difference of each value against our threshold:
        If ((temp_R - R) < nThreshold) AndAlso ((temp_G - G) < nThreshold) AndAlso ((temp_B < B) < nThreshold) Then
            Return True
        Else
            Return False
        End If

    End Function
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文