Reputation: 3912
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.
Upvotes: 3
Views: 4978
Reputation: 1464
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())
}
}
Upvotes: 2
Reputation: 53418
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, see color.Alpha16
.
When calling draw.DrawMask()
, you most likely want to use the draw.Over
Op instead of draw.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.
Upvotes: 5