当前位置:网站首页>golang图片处理库image简介
golang图片处理库image简介
2022-07-30 14:40:00 【alwaysrun】
go中处理图片的标准库image支持常见的PNG、JPEG、GIF等格式的图片处理(可读取、裁剪、绘制、生成等)。
基本操作
图片的基本读取与保存。
读取
图片读取和文件读取类似,需要先获取流:
- 注册图片的解码器(如:jpg则
import _ "image/jpeg", png则import _ "image/png") - 通过
os.open打开文件获取流; - 通过
image.Decode解码流,获取图片;
import _ "image/jpeg"
func readPic() image.Image {
f, err := os.Open("C:\\hatAndSunglass.jpg")
if err != nil {
panic(err)
}
defer f.Close()
img, fmtName, err := image.Decode(f)
if err != nil {
panic(err)
}
fmt.Printf("Name: %v, Bounds: %+v, Color: %+v", fmtName, img.Bounds(), img.ColorModel())
return img
}
解码后返回的第一个参数为Image接口:
type Image interface {
ColorModel() color.Model // 返回图片的颜色模型
Bounds() Rectangle // 返回图片外框
At(x, y int) color.Color // 返回(x,y)像素点的颜色
}
新建
新建一个图片非常简单,只需image.NewRGBA即可创建一个透明背景的图片了
img := image.NewRGBA(image.Rect(0, 0, 300, 300))
保存
保存图片也很简单,需要编码后,写入文件流即可:
- 注册图片的解码器
- 通过
os.create创建文件; - 通过
png.Encode编码图片并写入文件;
func savePic(img *image.RGBA) {
f, err := os.Create("C:\\tmp.jpg")
if err != nil {
panic(err)
}
defer f.Close()
b := bufio.NewWriter(f)
err = jpeg.Encode(b, img, nil)
if err != nil {
panic(err)
}
b.Flush()
}
图片修改
很多操作都需要用到绘制图片:
func Draw(dst Image, r image.Rectangle, src image.Image, sp image.Point, op Op)
func DrawMask(dst Image, r image.Rectangle, src image.Image, sp image.Point, mask image.Image, mp image.Point, op Op)
主要参数说明:
- dst:绘图的背景图
- r:背景图的绘图区域
- src:要绘制的图
- sp:要绘制图src的开始点
- op:组合方式
DrawMask多了一个遮罩蒙层参数,Draw为其一种特殊形式(遮罩相关参数为nil)。
转换
读取的jpg图像不是RGBA格式的(为YCbCr格式);在操作前需要先转换格式:
- 创建一个大小相同的RGBA图像;
- 把jpg画到新建的图像上去;
func jpg2RGBA(img image.Image) *image.RGBA {
tmp := image.NewRGBA(img.Bounds())
draw.Draw(tmp, img.Bounds(), img, img.Bounds().Min, draw.Src)
return tmp
}
裁剪
通过subImage方法可方便地裁剪图片(需要为RGBA格式的)
func subImg() {
pic := readPic()
fmt.Printf("Type: %T\n", pic)
img := jpg2RCBA(pic)
sub := img.SubImage(image.Rect(0, 0, pic.Bounds().Dx(), pic.Bounds().Dy()/2))
savePic(sub.(*image.RGBA))
}
缩放
图片缩放分为保持比例与不保持比例的缩放;保持比例时,要确定新图片的位置(是否居中),以及如何填充空白处。
为了缩放,需要引入新的库golang.org/x/image/draw。
在保持比例缩放时,需要先计算缩放后的图片大小:
- 分别计算宽、高的缩放比例,以小者为准;
- 若是居中(否则靠左上)需要计算填充大小,然后据此计算位置;
func calcResizedRect(width int, src image.Rectangle, height int, centerAlign bool) image.Rectangle {
var dst image.Rectangle
if width*src.Dy() < height*src.Dx() {
// width/src.width < height/src.height
ratio := float64(width) / float64(src.Dx())
tH := int(float64(src.Dy()) * ratio)
pad := 0
if centerAlign {
pad = (height - tH) / 2
}
dst = image.Rect(0, pad, width, pad+tH)
} else {
ratio := float64(height) / float64(src.Dy())
tW := int(float64(src.Dx()) * ratio)
pad := 0
if centerAlign {
pad = (width - tW) / 2
}
dst = image.Rect(pad, 0, pad+tW, height)
}
return dst
}
有了缩放后的大小后,即可通过双线性插值bilinear的方式进行图片的缩放
- img为要缩放的图片
- width、height为缩放后的大小
- keepRatio为是否保持比例缩放
- fill为填充的颜色(R、G、B都为fill)
- centerAlign:保持比例缩放时,图片是否居中存放
import (
"image"
"image/color"
"golang.org/x/image/draw"
)
func resizePic(img image.Image, width int, height int, keepRatio bool, fill int, centerAlign bool) image.Image {
outImg := image.NewRGBA(image.Rect(0, 0, width, height))
if !keepRatio {
draw.BiLinear.Scale(outImg, outImg.Bounds(), img, img.Bounds(), draw.Over, nil)
return outImg
}
if fill != 0 {
fillColor := color.RGBA{
R: uint8(fill), G: uint8(fill), B: uint8(fill), A: 255}
draw.Draw(outImg, outImg.Bounds(), &image.Uniform{
C: fillColor}, image.Point{
}, draw.Src)
}
dst := calcResizedRect(width, img.Bounds(), height, centerAlign)
draw.ApproxBiLinear.Scale(outImg, dst.Bounds(), img, img.Bounds(), draw.Over, nil)
return outImg
}
边栏推荐
猜你喜欢
4 senior experts share the insider architecture design and implementation principles of Flink technology with years of experience in large factories

The highest level of wiring in the computer room, the beauty is suffocating

MongoDB启动报错 Process: 29784 ExecStart=/usr/bin/mongod $OPTIONS (code=exited, status=14)

算力顶天地,存力纳乾坤:国家超级计算济南中心的一体两面

双碳目标下:农田温室气体排放模拟

Flink optimization

MongoDB starts an error Process: 29784 ExecStart=/usr/bin/mongod $OPTIONS (code=exited, status=14)

面试何惧调优!腾讯技术官私藏的性能优化方案手册,原理实战齐全

Mac 中 MySQL 的安装与卸载

Understand the Chisel language. 29. Chisel advanced communication state machine (1) - communication state machine: take the flash as an example
随机推荐
关于MySQL主从复制的数据同步延迟问题
Huawei's 7-year-experienced software testing director, gives some advice to all friends who want to change careers to learn software testing
Get the Google Advertising ID as a unique identifier
JSON常用注解
JVM performance tuning
从实例来看DAO:权力分散的伟大尝试
B+树索引页大小是如何确定的?
Meta首份元宇宙白皮书9大看点,瞄准80万亿美元市场
存储器映射、位带操作
Allure Advanced - Dynamically Generate Report Content
5G-based Warehousing Informatization Solution 2022
泡沫褪去,DeFi还剩下什么
去腾讯面试,直接让人出门左拐 :幂等性都不知道!
Desktop Software Development Framework Awards
This editor actually claims to be as fast as lightning!
Normal and escaped strings for postgresql
Redis 缓存穿透、击穿、雪崩以及一致性问题
学习 MySQL 需要知道的 28 个小技巧
ESP32 Repeated Reboot Issue Arduino Shield Power Outage Detector
闭包和装饰器