如何使用Golang对图片进行蒙版和遮罩效果

在图像处理中,很常见的一种需求是对图像进行蒙版和遮罩处理。用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()函数将灰度图像作为遮罩应用到彩色图像上。

在实际应用中,我们可以根据具体的需求和场景选择不同的处理方式,来达到更好的图像效果。

后端开发标签