/
image.go
105 lines (98 loc) · 2.26 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
// Copyright 2016 Pikkpoiss
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package core
import (
"bufio"
"bytes"
"image"
"image/draw"
"image/png"
"os"
)
func LoadPNG(path string) (img image.Image, err error) {
var file *os.File
if file, err = os.Open(path); err != nil {
return
}
defer file.Close()
img, err = png.Decode(file)
return
}
func WritePNG(path string, img image.Image) (err error) {
var (
f *os.File
b *bufio.Writer
)
if f, err = os.Create(path); err != nil {
return
}
defer f.Close()
b = bufio.NewWriter(f)
if err = png.Encode(b, img); err != nil {
return
}
err = b.Flush()
return
}
func imageBytes(img image.Image) (buf *bytes.Buffer, err error) {
var (
bounds image.Rectangle = img.Bounds()
rgba *image.RGBA
data []byte
)
buf = &bytes.Buffer{}
rgba = image.NewRGBA(bounds)
draw.Draw(rgba, bounds, img, bounds.Min, draw.Src)
data = make([]byte, len(rgba.Pix))
var (
destOffset int = len(data) - rgba.Stride
)
for srcOffset := 0; srcOffset < len(rgba.Pix); {
var (
dest = data[destOffset : destOffset+rgba.Stride]
source = rgba.Pix[srcOffset : srcOffset+rgba.Stride]
)
copy(dest, source)
destOffset -= rgba.Stride
srcOffset += rgba.Stride
}
for x := 0; x < len(data); {
buf.WriteByte(data[x+3])
buf.WriteByte(data[x+2])
buf.WriteByte(data[x+1])
buf.WriteByte(data[x+0])
x += 4
}
return
}
func pow2(i int) int {
p2 := 1
for p2 < i {
p2 = p2 << 1
}
return p2
}
func getPow2Image(img image.Image) image.Image {
var (
bounds = img.Bounds()
width = pow2(bounds.Max.X)
height = pow2(bounds.Max.Y)
)
if width == bounds.Max.X && height == bounds.Max.Y {
return img
}
out := image.NewRGBA(image.Rect(0, 0, width, height))
draw.Draw(out, bounds, img, image.ZP, draw.Src)
return out
}