-
-
Notifications
You must be signed in to change notification settings - Fork 5
/
image.go
138 lines (111 loc) · 3.33 KB
/
image.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
package gfx
import (
"bytes"
"image"
"image/color"
"image/draw"
"image/png"
"io"
)
// ZP is the zero image.Point.
var ZP = image.ZP
// NewImage creates an image of the given size (optionally filled with a color)
func NewImage(w, h int, colors ...color.Color) *image.RGBA {
m := NewRGBA(IR(0, 0, w, h))
if len(colors) > 0 {
DrawColor(m, m.Bounds(), colors[0])
}
return m
}
// NewNRGBA returns a new NRGBA image with the given bounds.
func NewNRGBA(r image.Rectangle) *image.NRGBA {
return image.NewNRGBA(r)
}
// NewRGBA returns a new RGBA image with the given bounds.
func NewRGBA(r image.Rectangle) *image.RGBA {
return image.NewRGBA(r)
}
// NewGray returns a new Gray image with the given bounds.
func NewGray(r image.Rectangle) *image.Gray {
return image.NewGray(r)
}
// NewGray16 returns a new Gray16 image with the given bounds.
// (For example useful for height maps)
func NewGray16(r image.Rectangle) *image.Gray16 {
return image.NewGray16(r)
}
// NewUniform creates a new uniform image of the given color.
func NewUniform(c color.Color) *image.Uniform {
return image.NewUniform(c)
}
// Pt returns an image.Point for the given x and y.
func Pt(x, y int) image.Point {
return image.Pt(x, y)
}
// IR returns an image.Rectangle for the given input.
func IR(x0, y0, x1, y1 int) image.Rectangle {
return image.Rect(x0, y0, x1, y1)
}
// Mix the current pixel color at x and y with the given color.
func Mix(m draw.Image, x, y int, c color.Color) {
_, _, _, a := c.RGBA()
switch a {
case 0xFFFF:
m.Set(x, y, c)
default:
DrawColorOver(m, IR(x, y, x+1, y+1), c)
}
}
// MixPoint the current pixel color at the image.Point with the given color.
func MixPoint(dst draw.Image, p image.Point, c color.Color) {
Mix(dst, p.X, p.Y, c)
}
// Set x and y to the given color.
func Set(dst draw.Image, x, y int, c color.Color) {
dst.Set(x, y, c)
}
// SetPoint to the given color.
func SetPoint(dst draw.Image, p image.Point, c color.Color) {
dst.Set(p.X, p.Y, c)
}
// SetVec to the given color.
func SetVec(dst draw.Image, u Vec, c color.Color) {
pt := u.Pt()
dst.Set(pt.X, pt.Y, c)
}
// EachImageVec calls the provided function for each Vec
// in the provided image in the given direction.
//
// gfx.V(1,1) to call the function on each pixel starting from the top left.
func EachImageVec(src image.Image, dir Vec, fn func(u Vec)) {
BoundsToRect(src.Bounds()).EachVec(dir, fn)
}
// EachPixel calls the provided function for each pixel in the provided rectangle.
func EachPixel(r image.Rectangle, fn func(x, y int)) {
for x := r.Min.X; x < r.Max.X; x++ {
for y := r.Min.Y; y < r.Max.Y; y++ {
fn(x, y)
}
}
}
// EncodePNG encodes an image as PNG to the provided io.Writer.
func EncodePNG(w io.Writer, src image.Image) error {
return png.Encode(w, src)
}
// DecodePNG decodes a PNG from the provided io.Reader.
func DecodePNG(r io.Reader) (image.Image, error) {
return png.Decode(r)
}
// DecodePNGBytes decodes a PNG from the provided []byte.
func DecodePNGBytes(b []byte) (image.Image, error) {
return DecodePNG(bytes.NewReader(b))
}
// DecodeImage decodes an image from the provided io.Reader.
func DecodeImage(r io.Reader) (image.Image, error) {
m, _, err := image.Decode(r)
return m, err
}
// DecodeImageBytes decodes an image from the provided []byte.
func DecodeImageBytes(b []byte) (image.Image, error) {
return DecodeImage(bytes.NewReader(b))
}