1. 程式人生 > >golang中image包用法

golang中image包用法

image包實現了一個基本的2D影象庫,該包中包含基本的介面叫做image,這個裡面包含color,這個將在image/color中描述,

image介面的值建立方式有如下幾種:

1呼叫NewRGBA和NewPaletted

2解碼一個包含gif.jpen或者png格式的image資料的io.Reader

首先介紹一些image介面


type Image    //image是一個從顏色模型中採取color.Color的矩形網格

type Image interface {
	ColorModel() color.Model //ColorModel 返回圖片的 color.Model
	Bounds() Rectangle    //圖片中非0color的區域
	At(x, y int) color.Color  //返回指定點的畫素color.Color
}
任何一個struct只要實現了image中的三個方法,便實現了image介面

func Decode(r io.Reader) (Image, string, error) //Decode對一個根據指定格式進行編碼的圖片進行解碼操作,string返回的是在註冊過程中使用的格式化名字,如"gif"或者"jpeg"等.

func RegisterFormat(name, magic string, decode func(io.Reader) (Image, error), decodeConfig func(io.Reader) (Config, error))

RegisterFormat註冊一個image格式給解碼使用,name是格式化名字,例如"jpeg"或者"png",magic標明格式化編碼的字首,magic字串中能夠包含一個?字元,用來匹配任何一個字元,decode是用來解碼"編碼影象"的函式,DecodeConfig是一個僅僅解碼它的配置的函式.


type Alpha //用來設定圖片的透明度

type Alpha struct {
	
	Pix []uint8  // Pix 儲存圖片的畫素 ,像 alpha 值. 在(X,Y)的畫素 starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*1].
	
	Stride int          // Stride 表示垂直兩個畫素之間的步幅(距離)

	Rect Rectangle  // Rect 表示 圖片邊界.
}


func NewAlpha(r Rectangle) *Alpha       //利用給定矩形邊界產生一個alpha
func (p *Alpha) AlphaAt(x, y int) color.Alpha      //獲取指定點的透明度
func (p *Alpha) At(x, y int) color.Color   //獲取指定點的color(指定點的紅綠藍的透明度)
func (p *Alpha) Bounds() Rectangle   //獲取alpha的邊界
func (p *Alpha) ColorModel() color.Model //獲取alpha的顏色模型
func (p *Alpha) Opaque() bool      //檢查alpha是否完全不透明
func (p *Alpha) PixOffset(x, y int) int   //獲取指定畫素相對於第一個畫素的相對偏移量
func (p *Alpha) Set(x, y int, c color.Color) //設定指定位置的color
func (p *Alpha) SetAlpha(x, y int, c color.Alpha)  //設定指定位置的alpha

func (p *Alpha) SubImage(r Rectangle) Image   //獲取p影象中被r覆蓋的子影象,父影象和子影象公用畫素

下面舉例說明其用法:

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()
	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))    //144 在指定位置的畫素
	fmt.Println(alpha.Bounds())        //(0,0)-(500,200),圖片邊界
	fmt.Println(alpha.Opaque())        //false,是否圖片完全透明
	fmt.Println(alpha.PixOffset(1, 1)) //501,指定點相對於第一個點的距離
	fmt.Println(alpha.Stride)          //500,兩個垂直畫素之間的距離
	jpeg.Encode(file, alpha, nil)      //將image資訊寫入檔案中
}

得到的圖形如下所示:



由於每種型別其方法類似,下面不再距離說明。

type Alpha16

type Alpha16 struct {
	// Pix holds the image's pixels, as alpha values in big-endian format. The pixel at
	// (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*2]. 大端模式,所以畫素計算和alpha不同
	Pix []uint8
	// Stride is the Pix stride (in bytes) between vertically adjacent pixels.
	Stride int
	// Rect is the image's bounds.
	Rect Rectangle
}
其中alpha16中方法用法與alpha中方法用法類似,這裡不再贅述.
func NewAlpha16(r Rectangle) *Alpha16
func (p *Alpha16) Alpha16At(x, y int) color.Alpha16
func (p *Alpha16) At(x, y int) color.Color
func (p *Alpha16) Bounds() Rectangle
func (p *Alpha16) ColorModel() color.Model
func (p *Alpha16) Opaque() bool
func (p *Alpha16) PixOffset(x, y int) int
func (p *Alpha16) Set(x, y int, c color.Color)
func (p *Alpha16) SetAlpha16(x, y int, c color.Alpha16)
func (p *Alpha16) SubImage(r Rectangle) Image


type Config //包括影象的顏色模型和寬高尺寸

type Config struct {
	ColorModel    color.Model
	Width, Height int
}


func DecodeConfig(r io.Reader) (Config, string, error)


type Gray  //用來設定圖片的灰度

type Gray struct {
	// Pix holds the image's pixels, as gray values. The pixel at
	// (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*1].
	Pix []uint8
	// Stride is the Pix stride (in bytes) between vertically adjacent pixels.
	Stride int
	// Rect is the image's bounds.
	Rect Rectangle
}
其中Gray方法與Alpha完全相同,不在贅述

func NewGray(r Rectangle) *Gray
func (p *Gray) At(x, y int) color.Color
func (p *Gray) Bounds() Rectangle
func (p *Gray) ColorModel() color.Model
func (p *Gray) GrayAt(x, y int) color.Gray
func (p *Gray) Opaque() bool
func (p *Gray) PixOffset(x, y int) int
func (p *Gray) Set(x, y int, c color.Color)
func (p *Gray) SetGray(x, y int, c color.Gray)
func (p *Gray) SubImage(r Rectangle) Image


type Gray16

type Gray16 struct {
	// Pix holds the image's pixels, as gray values in big-endian format. The pixel at
	// (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*2].
	Pix []uint8
	// Stride is the Pix stride (in bytes) between vertically adjacent pixels.
	Stride int
	// Rect is the image's bounds.
	Rect Rectangle
}
Gray16方法與Alpha16方法完全相同,不再贅述
func NewGray16(r Rectangle) *Gray16
func (p *Gray16) At(x, y int) color.Color
func (p *Gray16) Bounds() Rectangle
func (p *Gray16) ColorModel() color.Model
func (p *Gray16) Gray16At(x, y int) color.Gray16
func (p *Gray16) Opaque() bool
func (p *Gray16) PixOffset(x, y int) int
func (p *Gray16) Set(x, y int, c color.Color)
func (p *Gray16) SetGray16(x, y int, c color.Gray16)
func (p *Gray16) SubImage(r Rectangle) Image

type NRGBA

type NRGBA struct {
	// Pix holds the image's pixels, in R, G, B, A order. The pixel at
	// (x, y) starts at <span style="color:#FF0000;">Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*4]</span>.
	Pix []uint8
	// Stride is the Pix stride (in bytes) between vertically adjacent pixels.
	Stride int
	// Rect is the image's bounds.
	Rect Rectangle
}

func NewNRGBA(r Rectangle) *NRGBA
func (p *NRGBA) At(x, y int) color.Color
func (p *NRGBA) Bounds() Rectangle
func (p *NRGBA) ColorModel() color.Model
func (p *NRGBA) NRGBAAt(x, y int) color.NRGBA
func (p *NRGBA) Opaque() bool
func (p *NRGBA) PixOffset(x, y int) int
func (p *NRGBA) Set(x, y int, c color.Color)
func (p *NRGBA) SetNRGBA(x, y int, c color.NRGBA)
func (p *NRGBA) SubImage(r Rectangle) Image


type NRGBA64

type NRGBA64 struct {
	// Pix holds the image's pixels, in R, G, B, A order and big-endian format. The pixel at
	// (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*8].
	Pix []uint8
	// Stride is the Pix stride (in bytes) between vertically adjacent pixels.
	Stride int
	// Rect is the image's bounds.
	Rect Rectangle
}

func NewNRGBA64(r Rectangle) *NRGBA64
func (p *NRGBA64) At(x, y int) color.Color
func (p *NRGBA64) Bounds() Rectangle
func (p *NRGBA64) ColorModel() color.Model
func (p *NRGBA64) NRGBA64At(x, y int) color.NRGBA64
func (p *NRGBA64) Opaque() bool
func (p *NRGBA64) PixOffset(x, y int) int
func (p *NRGBA64) Set(x, y int, c color.Color)
func (p *NRGBA64) SetNRGBA64(x, y int, c color.NRGBA64)
func (p *NRGBA64) SubImage(r Rectangle) Image


type Paletted

type Paletted struct {
	// Pix holds the image's pixels, as palette indices. The pixel at
	// (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*1].
	Pix []uint8
	// Stride is the Pix stride (in bytes) between vertically adjacent pixels.
	Stride int
	// Rect is the image's bounds.
	Rect Rectangle
	// Palette is the image's palette. 圖片的調色盤
	Palette color.Palette
}

func NewPaletted(r Rectangle, p color.Palette) *Paletted  //根據指定的寬高和顏色調色盤生成一個新的調色盤
func (p *Paletted) At(x, y int) color.Color
func (p *Paletted) Bounds() Rectangle
func (p *Paletted) ColorIndexAt(x, y int) uint8
func (p *Paletted) ColorModel() color.Model
func (p *Paletted) Opaque() bool
func (p *Paletted) PixOffset(x, y int) int
func (p *Paletted) Set(x, y int, c color.Color)
func (p *Paletted) SetColorIndex(x, y int, index uint8)
func (p *Paletted) SubImage(r Rectangle) Image


type PalettedImage  //調色盤影象介面

type PalettedImage interface {
	
	ColorIndexAt(x, y int) uint8 //返回在位置(x,y)處畫素的索引
	Image  //image介面
}


type Point //一個點的(x,y)座標對
type Point struct {
	X, Y int
}

func Pt(X, Y int) Point      //Pt是Point{X, Y}的簡寫
func (p Point) Add(q Point) Point  //兩個向量點求和
func (p Point) Div(k int) Point   //Div returns the vector p/k,求Point/k的值
func (p Point) Eq(q Point) bool   //判定兩個向量點是否相等
func (p Point) In(r Rectangle) bool //判斷某個向量點是否在矩陣中
func (p Point) Mod(r Rectangle) Point    //在矩陣r中求一個點q,是的p.x-q.x是矩陣寬的倍數,p.y-q.y是矩陣高的倍數
func (p Point) Mul(k int) Point   //返回向量點和指定值的乘積組成的向量點
func (p Point) String() string    //返回用string表示的向量點,其樣式如(1,2)

func (p Point) Sub(q Point) Point      //兩個向量點求差

舉例說明如下:

func main() {
	pt := image.Point{X: 5, Y: 5}
	fmt.Println(pt)            //(5,5) ,輸出一個點位置(X,Y)
	fmt.Println(image.Pt(1, 2))   //(1,2)  ,Pt輸出一個點位置的簡寫形式
	fmt.Println(pt.Add(image.Pt(1, 1)))  //(6,6),兩個點求和
	fmt.Println(pt.String())      //(5,5) ,以字串形式輸出點
	fmt.Println(pt.Eq(image.Pt(5, 5)))        //true,判斷兩個點是否完全相等
	fmt.Println(pt.In(image.Rect(0, 0, 10, 10)))    //true,判斷一個點是否在矩陣中
	fmt.Println(pt.Div(2))          //(2,2),求點的商
 	fmt.Println(pt.Mul(2))             // (10,10),求點的乘積
	fmt.Println(pt.Sub(image.Pt(1, 1)))     // (4,4),求兩個點的差fmt.Println(pt.Mod(image.Rect(9, 8, 10, 10)))  // (9,9),dx=10-9=1,dy=10-8=2,9-5=4,4是1和2的倍數並且(9,9)在矩陣中
}

type RGBA

type RGBA struct {
	// Pix holds the image's pixels, in R, G, B, A order. The pixel at
	// (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*4]
	Pix []uint8
	// Stride is the Pix stride (in bytes) between vertically adjacent pixels.
	Stride int
	// Rect is the image's bounds.
	Rect Rectangle
}

func NewRGBA(r Rectangle) *RGBA
func (p *RGBA) At(x, y int) color.Color
func (p *RGBA) Bounds() Rectangle
func (p *RGBA) ColorModel() color.Model
func (p *RGBA) Opaque() bool
func (p *RGBA) PixOffset(x, y int) int
func (p *RGBA) Set(x, y int, c color.Color)
func (p *RGBA) SetRGBA(x, y int, c color.RGBA)

func (p *RGBA) SubImage(r Rectangle) Image

舉例說明RGBA用法:

package main

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

const (
	dx = 500
	dy = 200
)

func main() {

	file, err := os.Create("test.jpg")
	if err != nil {
		log.Fatal(err)
	}
	defer file.Close()
	rgba := image.NewRGBA(image.Rect(0, 0, dx, dy))
	for x := 0; x < dx; x++ {
		for y := 0; y < dy; y++ {
			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資訊存入檔案中
}

得到的檔案如下;



type RGBA64

type RGBA64 struct {
	// Pix holds the image's pixels, in R, G, B, A order and big-endian format. The pixel at
	// (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*8].
	Pix []uint8
	// Stride is the Pix stride (in bytes) between vertically adjacent pixels.
	Stride int
	// Rect is the image's bounds.
	Rect Rectangle
}

func NewRGBA64(r Rectangle) *RGBA64
func (p *RGBA64) At(x, y int) color.Color
func (p *RGBA64) Bounds() Rectangle
func (p *RGBA64) ColorModel() color.Model
func (p *RGBA64) Opaque() bool
func (p *RGBA64) PixOffset(x, y int) int
func (p *RGBA64) RGBA64At(x, y int) color.RGBA64
func (p *RGBA64) Set(x, y int, c color.Color)
func (p *RGBA64) SetRGBA64(x, y int, c color.RGBA64)
func (p *RGBA64) SubImage(r Rectangle) Image


type Rectangle   //利用兩個座標點來生成矩陣

type Rectangle struct {
	Min, Max Point
}

func Rect(x0, y0, x1, y1 int) Rectangle //Rect是Rectangle{Pt(x0, y0), Pt(x1, y1)}的一種簡寫形式
func (r Rectangle) Add(p Point) Rectangle //矩陣中兩個點都與指定的點求和組成一個新的矩陣
func (r Rectangle) Canon() Rectangle  //返回標準格式的矩形,如果有必要的話,會進行最小值座標和最大座標的交換
func (r Rectangle) Dx() int       //返回矩陣寬度dx
func (r Rectangle) Dy() int       //返回矩陣高度dy
func (r Rectangle) Empty() bool              //判定是否該矩陣為空,即不包含任何point
func (r Rectangle) Eq(s Rectangle) bool    //判斷兩個矩陣是否相等,指的是完全重合
func (r Rectangle) In(s Rectangle) bool  //判斷一個矩陣是否在另外一個矩陣之內

func (r Rectangle) Inset(n int) Rectangle //返回根據n算出的嵌入的矩陣,計算方法是矩陣的每個座標都減去n,求得的矩陣必須在已知矩陣內嵌,如果沒有的話則返回空矩陣
func (r Rectangle) Intersect(s Rectangle) Rectangle     //求兩個矩陣的相交矩陣,如果兩個矩陣不相交,則返回0矩陣
func (r Rectangle) Overlaps(s Rectangle) bool  //判斷兩個矩陣是否有交集,即判斷兩個矩陣是否有公共區域
func (r Rectangle) Size() Point       //返回矩陣的寬和高,即dx和dy
func (r Rectangle) String() string                         //返回矩陣的字串表示
func (r Rectangle) Sub(p Point) Rectangle  //一個矩陣的兩個座標點同時減去一個指定的座標點p,得到的一個新的矩陣
func (r Rectangle) Union(s Rectangle) Rectangle //兩個矩陣的並集,這個是和Intersect(求兩個矩陣的交集)相對的

舉例說明Rectangle用法:

package main

import (
	"fmt"
	"image"
)

func main() {
	rt := image.Rect(0, 0, 100, 50)
	rt1 := image.Rect(100, 100, 10, 10)

	fmt.Println(rt1.Canon())      //(10,10)-(100,100),rt1大小座標交換位置
	fmt.Println(rt, rt1)          //(0,0)-(100,50) (10,10)-(100,100)
	fmt.Println(rt.Dx(), rt.Dy()) //100 50,返回矩陣的寬度和高度
	fmt.Println(rt.Empty())       //false,矩陣是否為空
	fmt.Println(rt.Eq(rt1))       //false,兩個矩陣是否相等
	fmt.Println(rt.In(rt1))       //false,矩陣rt是否在矩陣rt1中
	fmt.Println(rt.Inset(10))     //(10,10)-(90,40),查詢內嵌矩陣,用原矩陣座標點減去給定的值10得到的矩陣,該矩陣必須是原矩陣的內嵌矩陣

	if rt.Overlaps(rt1) {
		fmt.Println(rt.Intersect(rt1)) //(10,10)-(100,50) //求兩個矩陣的交集
	}
	fmt.Println(rt.Size())                //(100,50),求矩陣大小,其等價與(dx,dy)
	fmt.Println(rt.String())              //  (0,0)-(100,50)
	fmt.Println(rt.Sub(image.Pt(10, 10))) // (-10,-10)-(90,40),求矩陣和一個點的差,用於將矩陣進行移位操作
	fmt.Println(rt.Union(rt1))            //(0,0)-(100,100),求兩個矩陣的並集
}

type Uniform     //Uniform是一個具有統一顏色無窮大小的圖片,它實現了color.Color, color.Model, 以及 Image的介面

type Uniform struct {
	C color.Color
}

func NewUniform(c color.Color) *Uniform  //根據color.Color產生一個Uniform
func (c *Uniform) At(x, y int) color.Color             //獲取指定點的畫素資訊
func (c *Uniform) Bounds() Rectangle    //獲取影象的邊界矩陣資訊
func (c *Uniform) ColorModel() color.Model  //獲取影象的顏色模型
func (c *Uniform) Convert(color.Color) color.Color //將圖片的畫素資訊轉換為另外一種指定的畫素資訊
func (c *Uniform) Opaque() bool         //判定圖片是否完全透明
func (c *Uniform) RGBA() (r, g, b, a uint32)    //返回圖片的r,g,b,a(紅,綠,藍,透明度)的值


type YCbCr  //YCbCr是一個Y'CbCr顏色的圖片,每個Y樣本表示一個畫素,但是每個Cb和Cr能夠代表一個或者更多的畫素,YStride是在相鄰垂直畫素的Yslice索引增         //量,CStride是Cb和 Cr slice在相鄰垂直畫素(對映到獨立色度取樣)的索引增量.通常YStride和len(Y)是8的倍數,而CStride結果如下:

For 4:4:4, CStride == YStride/1 && len(Cb) == len(Cr) == len(Y)/1.
For 4:2:2, CStride == YStride/2 && len(Cb) == len(Cr) == len(Y)/2.
For 4:2:0, CStride == YStride/2 && len(Cb) == len(Cr) == len(Y)/4.
For 4:4:0, CStride == YStride/1 && len(Cb) == len(Cr) == len(Y)/2.

type YCbCr struct {
	Y, Cb, Cr      []uint8
	YStride        int
	CStride        int
	SubsampleRatio YCbCrSubsampleRatio
	Rect           Rectangle
}

func NewYCbCr(r Rectangle, subsampleRatio YCbCrSubsampleRatio) *YCbCr //通過給定邊界和子樣本比例建立新的YCbCr
func (p *YCbCr) At(x, y int) color.Color     //獲取指定點的畫素
func (p *YCbCr) Bounds() Rectangle     //獲取影象邊界
func (p *YCbCr) COffset(x, y int) int       //獲取指定點相對於第一個Cb元素的畫素點的相對位置
func (p *YCbCr) ColorModel() color.Model    //獲取顏色Model
func (p *YCbCr) Opaque() bool                              //判定是否完全透明
func (p *YCbCr) SubImage(r Rectangle) Image  //根據指定矩陣獲取原影象的子影象
func (p *YCbCr) YCbCrAt(x, y int) color.YCbCr  
func (p *YCbCr) YOffset(x, y int) int       //獲取相對於第一個Y元素的畫素點的相對位置


type YCbCrSubsampleRatio //YCbCr的色度子樣本比例,常用於NewYCbCr(r Rectangle, subsampleRatio YCbCrSubsampleRatio)中用來建立YCbCr

const (
	YCbCrSubsampleRatio444 YCbCrSubsampleRatio = iota
	YCbCrSubsampleRatio422
	YCbCrSubsampleRatio420
	YCbCrSubsampleRatio440
)


func (s YCbCrSubsampleRatio) String() string //YCbCrSubsampleRatio結構的字串表示