我正在尝试编写解决方案,以便我的用户可以使用其公司徽标将其图像“水印”。我已经完成了实际的水印部分,所以现在我正在创建“上传徽标”功能,以便他们可以向我提供他们希望在他们的图像上出现水印的徽标。
我正在使用VB.NET,这可能最终会出现在接受Logo JPG文件的Web服务中,并返回“已更改”的徽标。我需要在这个Web服务中发生的是:
1)灰度图像。我感谢this article。
2)使背景透明(因此当水印到图像上时,徽标看起来很干净)。这就是我被困住的地方。
我认为,在大多数情况下,上传的任何徽标都将具有通用的白色背景,但我无法假设。有没有办法以某种方式检测图像的背景或背景颜色,以便我可以使那些颜色透明?
我已经下载并运行了名为Transpoint的this project from code.google.com,这正是我所需要的,除非我无法将其作为一个独立的应用程序。另外,我认为这是用Python写的,对我来说很陌生。
基本上我需要的只是一种确定图像背景的方法(如果可能的话?)甚至只是背景颜色,这样我就可以使它们透明。任何帮助/意见/建议将不胜感激!
谢谢, 劳埃德
答案 0 :(得分:3)
您可以执行类似于读取左上角像素并假设该像素代表背景颜色,然后迭代图像并将每个匹配像素的alpha值(按颜色匹配)设置为0的操作。 / p>
然而,我几乎可以保证你的结果会很糟糕。为了使透明度正常工作并且看起来很好,图像需要支持部分透明度,这样一些像素是完全透明的,而有些像素只是部分透明。任何采用非透明图像并且只将图像中的一种颜色设置为完全透明的算法最终会出现锯齿状边缘。
我曾经处理的大多数公司都有专业艺术家完成的徽标版本,具有流畅,部分透明的特点。如果要求客户提交具有透明度的徽标,而不是尝试使用代码将非透明图像制作成透明图像,那么您会好得多。对不起,但这不起作用。
答案 1 :(得分:1)
我认为这实际上会有用(对不起,这只是一个描述):
假设左上角像素是图像的背景颜色,您可以遍历图像中的每个像素,并且如果像素颜色与背景颜色匹配(正好或在某个阈值颜色距离内),则将alpha设置为0。然后,当您在不同颜色的背景上重新绘制时,这将为您留下具有透明背景的图像,但会出现锯齿状边缘。此外,如果背景颜色出现在内部图像本身的任何位置,它将变为透明,这是您不想要的。
要解决后一个问题,您的算法应该从左到右开始扫描图像的每一行,并在到达非背景色像素时停止;此时它应该从同一行开始并从右向左扫描,直到达到非bg像素。
要修复边缘,您只需模糊位图的Alpha值即可。基本上,您将每个像素的alpha值重新计算为9个像素的平均值(本身及其周围的8个像素,只是 alpha值 - 而不是rgb值)。为了防止测序工件,你需要一个临时数组来存储平均像素值,然后在处理结束时将其复制回图像的alpha值。
此外,可能有一个或多个第三方工具执行此操作(LEAD工具还在吗?)。
答案 2 :(得分:1)
@MusiGenesis(以及其他可能感兴趣的人)这里是我做的(有点)解决我的问题。我基本上遵循了你的想法的前半部分。我创建了一个接受bitmap
的函数,在(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