在图像处理中,很常见的一种需求是对图像进行蒙版和遮罩处理。用Golang实现这一目的非常简单,本文就来详细介绍如何使用Golang对图片进行蒙版和遮罩处理。
1. 读取和保存图片
在进行图像处理之前,首先需要将需要处理的图片读取进来,然后对图片进行处理,最后再将处理后的图片保存。
对于Golang而言,处理图片的主要工具是image包,该包提供了Image、RGBA、RGBA64、NRGBA、NRGBA64和YCbCr等多种图像类型,在这里我们使用最基础的Image类型。
1.1 读取图片
在Golang中读取本地图片非常简单,只需要使用image包下的image.Decode()函数即可,它能够识别多种常见的图片格式,如JPEG、PNG、BMP等。
下面的示例代码演示了如何读取一张本地的图片。在示例中,我们使用JPEG图片作为示例图片,该图片保存在本地路径E:/test.jpg下。
import (
"fmt"
"image"
_ "image/jpeg"
"os"
)
func main() {
// 读取本地图片
imgFile, err := os.Open("E:/test.jpg")
if err != nil {
fmt.Println("open file err:", err)
return
}
defer imgFile.Close()
img, _, err := image.Decode(imgFile)
if err != nil {
fmt.Println("decode file err:", err)
return
}
}
运行上面的代码可以读取并解码JPEG图片,得到image.Image类型的图像对象img。
1.2 保存图片
在对图片进行处理后,需要将处理后的图片保存到本地。在Golang中,保存图片的最简单方式是使用image包提供的jpeg.Encode()函数进行JPEG编码,然后将JPEG编码后的数据写入文件中。
下面的示例代码演示了如何将处理后的图片保存到本地。在示例中,我们将图片保存到了本地路径E:/output.jpg下。
import (
"fmt"
"image"
"image/jpeg"
"os"
)
func main() {
// ...
// 保存图片
out, err := os.Create("E:/output.jpg")
if err != nil {
fmt.Println("create file err:", err)
return
}
defer out.Close()
err = jpeg.Encode(out, img, &jpeg.Options{Quality: 100})
if err != nil {
fmt.Println("encode file err:", err)
return
}
}
上面的代码通过jpeg.Encode()函数将图像对象img编码为JPEG格式,并将编码后的数据写入到out文件中。
2. 图片蒙版(Mask)
图像蒙版是指将一个二值图像(通常是灰度图像)应用到另外一个彩色图像上,产生一种新的图像效果。这种效果通常用于制作图标、水印、阴影、圆角等效果,也可用于拼图、图像合成等操作中。
在Golang中实现图像蒙版也比较简单,只需要将二值图像作为一个alpha通道(透明度通道)与彩色图像进行合成即可。
下面的示例代码将演示如何对图片进行蒙版处理。在示例中,我们使用一张灰度图作为蒙版,将其应用到一张彩色图像上,得到一张新的图像。
import (
"fmt"
"image"
"image/color"
_ "image/jpeg"
"image/png"
"os"
)
func main() {
// 读取彩色图像
imgFile, err := os.Open("E:/test.jpg")
if err != nil {
fmt.Println("open file err:", err)
return
}
defer imgFile.Close()
img, _, err := image.Decode(imgFile)
if err != nil {
fmt.Println("decode file err:", err)
return
}
// 读取蒙版
maskFile, err := os.Open("E:/mask.png")
if err != nil {
fmt.Println("open file err:", err)
return
}
defer maskFile.Close()
maskImg, err := png.Decode(maskFile)
if err != nil {
fmt.Println("decode file err:", err)
return
}
// 蒙版处理
bounds := img.Bounds()
maskBounds := maskImg.Bounds()
newImg := image.NewRGBA(bounds)
for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
for x := bounds.Min.X; x < bounds.Max.X; x++ {
newImg.Set(x, y, img.At(x, y))
// 只处理蒙版范围内的像素
if x < maskBounds.Min.X || x >= maskBounds.Max.X || y < maskBounds.Min.Y || y >= maskBounds.Max.Y {
continue
}
// 计算alpha通道值
maskColor := maskImg.At(x-maskBounds.Min.X, y-maskBounds.Min.Y)
_, _, _, maskA := maskColor.RGBA()
alpha := uint8(maskA >> 8)
// 蒙版处理
r, g, b, _ := newImg.At(x, y).RGBA()
newImg.Set(x, y, color.RGBA{R: uint8(r), G: uint8(g), B: uint8(b), A: alpha})
}
}
// 保存图片
out, err := os.Create("E:/output.jpg")
if err != nil {
fmt.Println("create file err:", err)
return
}
defer out.Close()
err = jpeg.Encode(out, newImg, &jpeg.Options{Quality: 100})
if err != nil {
fmt.Println("encode file err:", err)
return
}
}
上面的代码中,我们先读取彩色图像和蒙版,然后创建一个新的RGBA类型图像newImg,将彩色图像复制到新图像中,并在蒙版范围内按照蒙版的alpha通道进行颜色混合处理。最后,将处理后的图像保存起来。
3. 图片遮罩(Masks)
与蒙版不同,遮罩(Masks)是指将一个图像B裁剪成与另外一个图像A相同大小的部分,然后将这个裁剪后的图像作为图像A的遮罩效果。通常情况下,裁剪后的图像B需要是一张灰度图像。
在Golang中实现图片遮罩也非常简单,只需要调用Mask()函数即可。该函数需要传入两张图像,将第二张图像作为遮罩应用到第一张图像上,并返回一个新的图像对象。
下面的示例代码将演示如何对图片进行遮罩处理。在示例中,我们使用一张彩色图作为底图,将一张灰度图像作为遮罩应用到底图上,得到一张新的图像。
import (
"fmt"
"image"
"image/draw"
"image/png"
"os"
)
func main() {
// 读取底图
imgFile, err := os.Open("E:/test.jpg")
if err != nil {
fmt.Println("open file err:", err)
return
}
defer imgFile.Close()
img, _, err := image.Decode(imgFile)
if err != nil {
fmt.Println("decode file err:", err)
return
}
// 读取遮罩
maskFile, err := os.Open("E:/mask.png")
if err != nil {
fmt.Println("open file err:", err)
return
}
defer maskFile.Close()
maskImg, err := png.Decode(maskFile)
if err != nil {
fmt.Println("decode file err:", err)
return
}
// 遮罩处理
mask := image.NewUniform(color.Alpha{A: 0xff})
draw.Draw(maskImg, maskImg.Bounds(), mask, image.Point{}, draw.Src)
newImg := image.NewRGBA(img.Bounds())
draw.DrawMask(newImg, img.Bounds(), img, image.Point{}, maskImg, maskImg.Bounds().Min, draw.Over)
// 保存图片
out, err := os.Create("E:/output.jpg")
if err != nil {
fmt.Println("create file err:", err)
return
}
defer out.Close()
err = jpeg.Encode(out, newImg, &jpeg.Options{Quality: 100})
if err != nil {
fmt.Println("encode file err:", err)
return
}
}
上面的代码中,我们先读取底图和遮罩,然后创建一个新的RGBA类型图像newImg,并将遮罩应用到底图上,得到新图像。最后,将处理后的图像保存起来。
4. 总结
通过本文的介绍,我们了解了Golang如何实现图片蒙版和遮罩处理。在对图片进行处理前,我们需要先读取和保存图片;蒙版处理主要是将二值图像作为一个alpha通道与彩色图像进行合成;遮罩处理则需要使用draw.DrawMask()函数将灰度图像作为遮罩应用到彩色图像上。
在实际应用中,我们可以根据具体的需求和场景选择不同的处理方式,来达到更好的图像效果。