英文:
Setting opacity of image in golang
问题
我有以下代码。它将一个前景图像(logo.jpg)粘贴到背景图像(background.jpg)上。
在粘贴这个前景图像时,我想设置这个前景图像的不透明度。我使用了DrawMask(http://golang.org/doc/articles/image_draw.html),但似乎我在这里漏掉了一些东西。请看下面的代码。有人有任何想法吗?
package main
import (
"os"
"image/draw"
"image"
"image/jpeg"
)
func main() {
// 背景图像
fImg1, _ := os.Open("background.jpg")
defer fImg1.Close()
img1, _, _ := image.Decode(fImg1)
// 要粘贴在背景图像上的标志
fImg2, _ := os.Open("logo.jpg")
defer fImg2.Close()
img2, _, _ := image.Decode(fImg2)
// 掩码图像(只是一个与标志大小相同的纯浅灰色图像)
fmask, _ := os.Open("mask.jpg")
defer fImg2.Close()
mask, _, _ := image.Decode(fmask)
// 创建一个新的空白图像m
m := image.NewRGBA(image.Rect(0, 0, 1920, 1280))
// 将背景图像粘贴到m上
draw.Draw(m, m.Bounds(), img1, image.Point{0,0}, draw.Src)
// 现在使用掩码将标志图像粘贴到m上(参考 http://golang.org/doc/articles/image_draw.html)
// ******目标是在粘贴时使标志图像的不透明度为50******
draw.DrawMask(m, m.Bounds(), img2, image.Point{-100,-100}, mask, image.Point{-100,-100}, draw.Src)
toimg, _ := os.Create("new.jpg")
defer toimg.Close()
jpeg.Encode(toimg, m, &jpeg.Options{jpeg.DefaultQuality})
}
以上代码由Sathish(http://stackoverflow.com/questions/12430874/image-manipulation-in-golang)提供帮助。感谢Sathish。
英文:
I have following code. That does paste a foreground image (logo.jpg) over background image (background.jpg)
While pasting this foreground image, I want to set the opacity of this foreground image. I used DrawMask (http://golang.org/doc/articles/image_draw.html), but it seems I am missing something here. Please see the code below. Anyone has any idea?
package main
import (
"os"
"image/draw"
"image"
"image/jpeg"
)
func main() {
//Background image
fImg1, _ := os.Open("background.jpg")
defer fImg1.Close()
img1, _, _ := image.Decode(fImg1)
//Logo to stick over background image
fImg2, _ := os.Open("logo.jpg")
defer fImg2.Close()
img2, _, _ := image.Decode(fImg2)
//Mask image (that is just a solid light gray image of same size as logo)
fmask, _ := os.Open("mask.jpg")
defer fImg2.Close()
mask, _, _ := image.Decode(fmask)
//Create a new blank image m
m := image.NewRGBA(image.Rect(0, 0, 1920, 1280))
//Paste background image over m
draw.Draw(m, m.Bounds(), img1, image.Point{0,0}, draw.Src)
//Now paste logo image over m using a mask (ref. http://golang.org/doc/articles/image_draw.html )
//******Goal is to have opacity value 50 of logo image, when we paste it****
draw.DrawMask(m, m.Bounds(), img2, image.Point{-100,-100}, mask, image.Point{-100,-100}, draw.Src)
toimg, _ := os.Create("new.jpg")
defer toimg.Close()
jpeg.Encode(toimg, m, &jpeg.Options{jpeg.DefaultQuality})
}
Above code is helped by Sathish (http://stackoverflow.com/questions/12430874/image-manipulation-in-golang). Thanks Sathish.
答案1
得分: 5
我看到你的代码中有两个错误。
-
你设置遮罩的方式不正确。要获得50%的不透明度,你应该使用类似
mask := image.NewUniform(color.Alpha{128})
的方式,其中128是0(透明)和255(不透明)之间的一半。如果你想要更多的不透明度级别,可以参考color.Alpha16
。 -
在调用
draw.DrawMask()
时,你很可能想要使用draw.Over
操作而不是draw.Src
。尝试使用两者,你应该能看到它们之间的区别。
我还建议使用 m := image.NewRGBA(img1.Bounds())
,但手动设置也没有错。
英文:
I see two errors with your code.
-
You are setting the mask incorrectly. To get 50% opacity you want something like
mask := image.NewUniform(color.Alpha{128})
where 128 is half way between 0 (transparent), and 255 (opaque). If you want more than 256 levels of opacity, seecolor.Alpha16
. -
When calling
draw.DrawMask()
, you most likely want to use thedraw.Over
Op instead ofdraw.Src
. Try them both out and you should see the difference.
I also recommend m := image.NewRGBA(img1.Bounds())
, but it is not wrong to do it manually.
答案2
得分: 2
由于您想要基于另一张图像创建蒙版,您可能需要将灰度图像转换为阿尔法蒙版。下面的代码在我尝试的示例上运行得很好。
package main
import (
"fmt"
"image"
"image/color"
"image/draw"
"image/jpeg"
"os"
)
func main() {
fBg, err := os.Open("bkground.jpg")
defer fBg.Close()
bg, _, err := image.Decode(fBg)
fSrc, err := os.Open("arrow1.jpg")
defer fSrc.Close()
src, _, err := image.Decode(fSrc)
fMaskImg, err := os.Open("mask.jpg")
defer fMaskImg.Close()
maskImg, _, err := image.Decode(fMaskImg)
bounds := src.Bounds() //您已经定义了src和mask具有相同的大小,并且maskImg是src图像的灰度图像。因此,我们将使用这个共同的大小。
mask := image.NewAlpha(bounds)
for x := 0; x < bounds.Dx(); x++ {
for y := 0; y < bounds.Dy(); y++ {
//从蒙版图像中获取r、g、b之一...
r, _, _, _ := maskImg.At(x, y).RGBA()
//...并将其设置为蒙版上的阿尔法值。
mask.SetAlpha(x, y, color.Alpha{uint8(255 - r)}) //假设白色是您的透明度,从255中减去它
}
}
m := image.NewRGBA(bounds)
draw.Draw(m, m.Bounds(), bg, image.ZP, draw.Src)
draw.DrawMask(m, bounds, src, image.ZP, mask, image.ZP, draw.Over)
toimg, _ := os.Create("new.jpeg")
defer toimg.Close()
err = jpeg.Encode(toimg, m, nil)
if err != nil {
fmt.Println("Error: " + err.Error())
}
}
- 额外说明:在将jpeg图像转换为灰度图像时,我注意到gimp会自动保存一些图像包无法解码的选项。因此,您可能希望在每个操作之后检查错误值。为了减少代码大小,我在这里大部分都删除了它。
英文:
Since you want to base the mask off of another image, you probably have to do a conversion of the grayscale to an alpha mask. The below code works nicely on a sample that I tried.
package main
import (
"fmt"
"image"
"image/color"
"image/draw"
"image/jpeg"
"os"
)
func main() {
fBg, err := os.Open("bkground.jpg")
defer fBg.Close()
bg, _, err := image.Decode(fBg)
fSrc, err := os.Open("arrow1.jpg")
defer fSrc.Close()
src, _, err := image.Decode(fSrc)
fMaskImg, err := os.Open("mask.jpg")
defer fMaskImg.Close()
maskImg, _, err := image.Decode(fMaskImg)
bounds := src.Bounds() //you have defined that both src and mask are same size, and maskImg is a grayscale of the src image. So we'll use that common size.
mask := image.NewAlpha(bounds)
for x := 0; x < bounds.Dx(); x++ {
for y := 0; y < bounds.Dy(); y++ {
//get one of r, g, b on the mask image ...
r, _, _, _ := maskImg.At(x, y).RGBA()
//... and set it as the alpha value on the mask.
mask.SetAlpha(x, y, color.Alpha{uint8(255 - r)}) //Assuming that white is your transparency, subtract it from 255
}
}
m := image.NewRGBA(bounds)
draw.Draw(m, m.Bounds(), bg, image.ZP, draw.Src)
draw.DrawMask(m, bounds, src, image.ZP, mask, image.ZP, draw.Over)
toimg, _ := os.Create("new.jpeg")
defer toimg.Close()
err = jpeg.Encode(toimg, m, nil)
if err != nil {
fmt.Println("Error: " + err.Error())
}
}
- Extra note: while converting a jpeg image to grayscale in gimp, I noticed that it is automatically saving with some options that the image package could not decode. So you might want to check the error values after each of the operations. To reduce code size, I've mostly removed it here.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论