The Go image/draw package
29 September 2011
Introduction
Package image/draw defines only one operation: drawing a source image onto a destination image, through an optional mask image. This one operation is surprisingly versatile and can perform a number of common image manipulation tasks elegantly and efficiently.
Composition is performed pixel by pixel in the style of the Plan 9 graphics library and the X Render extension. The model is based on the classic "Compositing Digital Images" paper by Porter and Duff, with an additional mask parameter: dst = (src IN mask) OP dst
. For a fully opaque mask, this reduces to the original Porter-Duff formula: dst = src OP dst
The Porter-Duff paper presented 12 different composition operators, but with an explicit mask, only 2 of these are needed in practice: source-over-destination and source. In Go, these operators are represented by the Over
Src
constants. The Over
operator performs the natural layering of a source image over a destination image: the change to the destination image is smaller where the source (after masking) is more transparent (that is, has lower alpha). The Src
operator merely copies the source (after masking) with no regard for the destination image's original content. For fully opaque source and mask images, the two operators produce the same output, but the Src
operator is usually faster.
Geometric Alignment
Composition requires associating destination pixels with source and mask pixels. Obviously, this requires destination, source and mask images, and a composition operator, but it also requires specifying what rectangle of each image to use. Not every drawing should write to the entire destination: when updating an animating image, it is more efficient to only draw the parts of the image that have changed. Not every drawing should read from the entire source: when using a sprite that combines many small images into one large one, only a part of the image is needed. Not every drawing should read from the entire mask: a mask image that collects a font's glyphs is similar to a sprite. Thus, drawing also needs to know three rectangles, one for each image. Since each rectangle has the same width and height, it suffices to pass a destination rectangle r
and two points sp
and mp
: the source rectangle is equal to r
translated so that r.Min
in the destination image aligns with sp
in the source image, and similarly for mp
. The effective rectangle is also clipped to each image's bounds in their respective co-ordinate space.
The DrawMask
function takes seven arguments, but an explicit mask and mask-point are usually unnecessary, so the Draw
function takes five:
// Draw calls DrawMask with a nil mask. 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)
The destination image must be mutable, so the image/draw package defines a draw.Image
interface which has a Set
method.
type Image interface { image.Image Set(x, y int, c color.Color) }
Filling a Rectangle
To fill a rectangle with a solid color, use an image.Uniform
source. The ColorImage
type re-interprets a Color
as a practically infinite-sized Image
of that color. For those familiar with the design of Plan 9's draw library, there is no need for an explicit "repeat bit" in Go's slice-based image types; the concept is subsumed by Uniform
.
// image.ZP is the zero point -- the origin. draw.Draw(dst, r, &image.Uniform{c}, image.ZP, draw.Src)
To initialize a new image to all-blue:
m := image.NewRGBA(image.Rect(0, 0, 640, 480)) blue := color.RGBA{0, 0, 255, 255} draw.Draw(m, m.Bounds(), &image.Uniform{blue}, image.ZP, draw.Src)
To reset an image to transparent (or black, if the destination image's color model cannot represent transparency), use image.Transparent
, which is an image.Uniform
:
draw.Draw(m, m.Bounds(), image.Transparent, image.ZP, draw.Src)
Copying an Image
To copy from a rectangle sr
in the source image to a rectangle starting at a point dp
in the destination, convert the source rectangle into the destination image's co-ordinate space:
r := image.Rectangle{dp, dp.Add(sr.Size())} draw.Draw(dst, r, src, sr.Min, draw.Src)
Alternatively:
r := sr.Sub(sr.Min).Add(dp) draw.Draw(dst, r, src, sr.Min, draw.Src)
To copy the entire source image, use sr = src.Bounds()
.
Scrolling an Image
Scrolling an image is just copying an image to itself, with different destination and source rectangles. Overlapping destination and source images are perfectly valid, just as Go's built-in copy function can handle overlapping destination and source slices. To scroll an image m by 20 pixels:
b := m.Bounds() p := image.Pt(0, 20) // Note that even though the second argument is b, // the effective rectangle is smaller due to clipping. draw.Draw(m, b, m, b.Min.Add(p), draw.Src) dirtyRect := b.Intersect(image.Rect(b.Min.X, b.Max.Y-20, b.Max.X, b.Max.Y))
Converting an Image to RGBA
The result of decoding an image format might not be an image.RGBA
: decoding a GIF results in an image.Paletted
, decoding a JPEG results in a ycbcr.YCbCr
, and the result of decoding a PNG depends on the image data. To convert any image to an image.RGBA
:
b := src.Bounds() m := image.NewRGBA(image.Rect(0, 0, b.Dx(), b.Dy())) draw.Draw(m, m.Bounds(), src, b.Min, draw.Src)
Drawing Through a Mask
To draw an image through a circular mask with center p
and radius r
:
type circle struct { p image.Point r int } func (c *circle) ColorModel() color.Model { return color.AlphaModel } func (c *circle) Bounds() image.Rectangle { return image.Rect(c.p.X-c.r, c.p.Y-c.r, c.p.X+c.r, c.p.Y+c.r) } func (c *circle) At(x, y int) color.Color { xx, yy, rr := float64(x-c.p.X)+0.5, float64(y-c.p.Y)+0.5, float64(c.r) if xx*xx+yy*yy < rr*rr { return color.Alpha{255} } return color.Alpha{0} } draw.DrawMask(dst, dst.Bounds(), src, image.ZP, &circle{p, r}, image.ZP, draw.Over)
Drawing Font Glyphs
To draw a font glyph in blue starting from a point p
, draw with an image.ColorImage
source and an image.Alpha mask
. For simplicity, we aren't performing any sub-pixel positioning or rendering, or correcting for a font's height above a baseline.
src := &image.Uniform{color.RGBA{0, 0, 255, 255}} mask := theGlyphImageForAFont() mr := theBoundsFor(glyphIndex) draw.DrawMask(dst, mr.Sub(mr.Min).Add(p), src, image.ZP, mask, mr.Min, draw.Over)
Performance
The image/draw package implementation demonstrates how to provide an image manipulation function that is both general purpose, yet efficient for common cases. The DrawMask
function takes arguments of interface types, but immediately makes type assertions that its arguments are of specific struct types, corresponding to common operations like drawing one image.RGBA
image onto another, or drawing an image.Alpha
mask (such as a font glyph) onto an image.RGBA
image. If a type assertion succeeds, that type information is used to run a specialized implementation of the general algorithm. If the assertions fail, the fallback code path uses the generic At
and Set
methods. The fast-paths are purely a performance optimization; the resultant destination image is the same either way. In practice, only a small number of special cases are necessary to support typical applications.
相關推薦
The Go image/draw package
29 September 2011 Introduction Package image/draw defines only one operation: drawing a source image onto a dest
The Go image package
21 September 2011 Introduction The image and image/color packages define a number of types: color.Color and colo
Research Report on the Optical Image Stabilization
電子科技大學 格拉斯哥學院 2017/2018級 席文正 Introduction Image stabilization is the technique of improving image quality by actively removing the apparent mo
Go語言開發者福利 - 國內版 The Go Playground
本文為原創文章,轉載註明出處,歡迎掃碼關注公眾號flysnow_org或者網站www.flysnow.org/,第一時間看後續精彩文章。覺得好的話,順手分享到朋友圈吧,感謝支援。 作為Go語言開發者,我們都知道,Golang為我們提供了一個線上的、可以執行Go語言程式碼的、可以分享Go語言程式碼的
Chapter 8:Automating the Featurizer: Image Feature Extraction and Deep Learning
一、the simplest image features 最簡單的image表徵方法為:pixel matrix。但是,這種表徵方法,沒有將pixel之間的relationship囊括在內,因此,無法capture enough semantic inform
How to Enable the GD Image Library for WordPress?
很久以前還在用 php5 + wordpress 時,文章的縮圖都有自動被產生,某一次升級之後,縮圖功能就不見了。花了2小時Google 終於找到原因。 解法如下: apt-get install php7.0-gd phpenmod gd /etc/init.d/php7.0-fpm restart p
How can i detect the library image is from front camera or back camera
遇到一個奇怪的問題,iOS 前鏡頭拍的照片,被旋轉了 180度。 解法如下: Your code checks for available cameras on the device. What you need to do is read the metadata for the image after
The Go init Function
There are times, when creating applications in Go, that you need to be able to set up some form of state on the initial startup of your program. Th
How the Go runtime implements maps efficiently (without generics)
This post discusses how maps are implemented in Go. It is based on a presentation I gave at the GoCon Spring 2018 conference in Tokyo, Japan. What is a
Updating the Go Code of Conduct
23 May 2018 In November 2015, we introduced the Go Code of Conduct. It was developed in a collaboratio
The empty interface in the Go programming language
One of the most hotly debated topics in the world of the Go programming language, is the lack of generics. Generics are considered a key feature in othe
Use "conda info " to see the dependencies for each package
我這裡使用conda install tensorflow失敗,出現上述問題 我這裡主要是更換conda映象資料來源 1.檢視當前映象資料來源列表 conda config --get channels 2.網路上面均有的清華映象源(使用方式) conda config --
golang基礎--image/draw渲染圖片、利用golang/freetype庫在圖片上生成文字
文章目錄需求安裝依賴邏輯效果圖例項 需求 在一張A4紙上,利用image/draw標準庫生成4張二維碼,和該二維碼的客戶資訊 1、二維碼生成利用到的庫就是image/draw,通過draw.Draw進行寫入 2、然後字型渲染利用了golang/freetype開
A conversation with the Go team
6 June 2013 At Google I/O 2013, several members of the Go team hosted a "Fireside chat." Robert Griese
Introducing the Go Race Detector
26 June 2013 Introduction Race conditions are among the most insidious and elusive programming errors. The
The Go Programming Language turns two
10 November 2011 Two years ago a small team at Google went public with their fledgling project - the Go Prog
Getting to know the Go community
21 December 2011 Over the past couple of years Go has attracted a lot of users and contributors, and I've ha
Introducing the Go Playground
15 September 2010 If you visit golang.org today you'll see our new look. We have given the site a new coat o
Inside the Go Playground
12 December 2013 Introduction In September 2010 we introduced the Go Playground, a web service that compil
論文解析《Deep Convolutional Neural Network Features and the Original Image》
這一篇論文詳細分析了人臉識別中CNN網路提取到的features有一些什麼樣的性質,一般人臉識別中CNN出來後面接一個線性層用交叉熵來分類,這裡的features值得就是cnn出來的512或者128維的浮點陣列。文章首先用這個features作為輸入,使用LDA來分類,預測頭