使用go创建简单的图片

43 篇文章 1 订阅
30 篇文章 0 订阅

前言

这篇文章是学习记录,所诉内容应该是相对片面的,欢迎指正。
参考文章如下:

https://www.cnblogs.com/msnsj/p/4242572.html
https://studygolang.com/pkgdoc

image接口

在go语言中文网中对image接口有如下描述:

image实现了基本的2D图片库。

基本接口叫作Image。图片的色彩定义在image/color包。

Image接口可以通过调用如NewRGBA和NewPaletted函数等获得;也可以通过调用Decode函数解码包含GIF、JPEG或PNG格式图像数据的输入流获得。解码任何具体图像类型之前都必须注册对应类型的解码函数。注册过程一般是作为包初始化的副作用,放在包的init函数里。

image接口的源代码:

type Image interface {
    // ColorModel方法返回图像的色彩模型
    ColorModel() color.Model
    // Bounds方法返回图像的范围,范围不一定包括点(0, 0)
    Bounds() Rectangle
    // At方法返回(x, y)位置的色彩
    // At(Bounds().Min.X, Bounds().Min.Y)返回网格左上角像素的色彩
    // At(Bounds().Max.X-1, Bounds().Max.Y-1) 返回网格右下角像素的色彩
    At(x, y int) color.Color
}

任何一个struct只要实现了image中的三个方法,便实现了image接口

RGBA

RGBA是一个结构体,可以用来保存图片信息

type RGBA struct {
    // Pix保管图像的像素色彩信息,顺序为R, G, B, A
    // 像素(x, y)起始位置是Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*4]
    Pix []uint8
    // Stride是Pix中每行像素占用的字节数
    Stride int
    // Rect是图像的范围
    Rect Rectangle
}

RGBA类型代表一幅内存中的图像,其At方法返回color.RGBA类型的值。
因为不是很懂RGBA是什么,所以我对这个名词进行了搜索,结果如下:

RGBA是代表Red(红色)Green(绿色)Blue(蓝色)和Alpha的色彩空间。虽然它有的时候被描述为一个颜色空间,但是它其实仅仅是RGB模型的附加了额外的信息。采用的颜色是RGB,可以属于任何一种RGB颜色空间,但是Catmull和Smith在1971至1972年间提出了这个不可或缺的alpha数值,使得alpha渲染和alpha合成变得可能。提出者以alpha来命名是源于经典的线性插值方程αA + (1-α)B所用的就是这个希腊字母。

也就是说RGBA代表的是四个颜色的值,而在go语言中,我们可以通过color.RGBA对图片的颜色进行调控,构建我们想要的结果。

与RGBA相关的函数

func NewRGBA(r Rectangle) *RGBA

NewRGBA函数创建并返回一个具有指定范围的RGBA。

func (*RGBA) At
func (p *RGBA) At(x, y int) color.Color
func (*RGBA) Bounds
func (p *RGBA) Bounds() Rectangle
func (*RGBA) ColorModel
func (p *RGBA) ColorModel() color.Model
func (*RGBA) Opaque
func (p *RGBA) Opaque() bool

Opaque方法可以扫描整个图像并报告图像是否是完全不透明的。

func (*RGBA) PixOffset
func (p *RGBA) PixOffset(x, y int) int

PixOffset方法返回像素(x, y)的数据起始位置在Pix字段的偏移量/索引。

func (*RGBA) Set
func (p *RGBA) Set(x, y int, c color.Color)
func (*RGBA) SetRGBA
func (p *RGBA) SetRGBA(x, y int, c color.RGBA)
func (*RGBA) SubImage
func (p *RGBA) SubImage(r Rectangle) Image

SubImage方法返回代表原图像一部分(r的范围)的新图像。返回值和原图像的像素数据是共用的。

创建图片(示例)

示例一

过程:
首先使用os包下的create函数创建一个jpeg格式的图片,然后使用NewAlpha调用image接口,创建一个以(0,0)为起点,(500,200)为终点的图片对象,再依次遍历每一个像素点,使用Set函数对像素点的颜色进行设置。设置完成后,将image中的信息导入到文件中。

package main
 
import (
	"fmt"
	"image"
	"image/color"
	"image/jpeg"
	"log"
	"os"
)
 
const (
	dx = 500
	dy = 200
)
 
func main() {
 	//新建文件,作为操作目标
	file, err := os.Create("test.jpeg")
	if err != nil {
		log.Fatal(err)
	}
	defer file.Close()
	//调用NewAlpha函数,实现image接口
	alpha := image.NewAlpha(image.Rect(0, 0, dx, dy))
	//遍历每一个像素点,设置图片
	for x := 0; x < dx; x++ {
		for y := 0; y < dy; y++ {
			alpha.Set(x, y, color.Alpha{uint8(x % 256)})   //设定alpha图片的透明度
		}
	}
 	//在这一行的后边,尝试调用上边提到的各种方法
	fmt.Println(alpha.At(400, 100))    //查看在指定位置的像素
	fmt.Println(alpha.Bounds())        //查看图片边界
	fmt.Println(alpha.Opaque())        //查看是否图片完全透明
	fmt.Println(alpha.PixOffset(1, 1)) //查看指定点相对于第一个点的距离
	fmt.Println(alpha.Stride)          //查看两个垂直像素之间的距离
	jpeg.Encode(file, alpha, nil)      //将alpha中的信息写入图片文件中
}

在示例中,先使用os包下的Create函数在项目中创建了test.jpeg图片文件。
运行结果如下:
在这里插入图片描述
所创建的图片如下图所示:
在这里插入图片描述

这个是一个黑白渐变的图片,因为这里只使用Alpha对图片进行了透明度渐变设定。

示例二

和上文一样,这个示例依旧是使用RGBA对图片的像素点进行设置,但这个示例调整了RGBA,图像结果会不一样。

package main

import (
	"fmt"
	"image"
	"image/color"
	"image/jpeg"
	"log"
	"os"
)

const (
	dx = 500
	dy = 200
)

func main() {
	//创建图片文件jpeg
	file, err := os.Open("test.jpg")
	if err != nil {
		log.Fatal(err)
	}
	defer file.Close()
	//新建图片接口起始点是0,0,定义矩形边界
	rgba := image.NewRGBA(image.Rect(0, 0, dx, dy))
	//为图片添加颜色
	for x := 0; x < dx; x++ {
		for y := 0; y < dy; y++ {
			//set函数设定(x,y)的color
			//NRGBA,保存像素信息
			rgba.Set(x, y, color.NRGBA{uint8(x % 256), uint8(y % 256), 0, 255})
		}
	}

	fmt.Println(rgba.At(400, 100))    //{144 100 0 255}
	fmt.Println(rgba.Bounds())        //(0,0)-(500,200)
	fmt.Println(rgba.Opaque())        //true,其完全透明
	fmt.Println(rgba.PixOffset(1, 1)) //2004
	fmt.Println(rgba.Stride)          //2000
	jpeg.Encode(file, rgba, nil)      //将image信息存入文件中
}

运行结果:
在这里插入图片描述
可以看到,左上角是绿色,右上角是红色,中间呈现出渐变的颜色,因为这里使用了RGBA对每一个像素点进行了颜色调控。

示例三

当然,可以使用这个方法去创建纯色的图像:

package main

import (
	"fmt"
	"image"
	"image/color"
	"image/jpeg"
	"log"
	"os"
)

const (
	dx = 500
	dy = 200
)

func main() {
	//创建图片文件jpeg
	file, err := os.Create("test4.png")
	if err != nil {
		log.Fatal(err)
	}
	defer file.Close()
	//新建图片接口起始点是0,0,定义矩形边界
	rgba := image.NewRGBA(image.Rect(0, 0, dx, dy))
	//为图片添加颜色
	for x := 0; x < dx; x++ {
		for y := 0; y < dy; y++ {
			//set函数设定(x,y)的color
			//NRGBA,保存像素信息
			rgba.Set(x, y, color.NRGBA{240,255,255, 255})
		}
	}
	jpeg.Encode(file, rgba, nil)      //将image信息存入文件中
}

运行结果如图所示(我的查看器有背景图片所以可以看到一个动漫小姐姐的轮廓):
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值