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
| package godraw
|
| import (
| "bufio"
| "bytes"
| "errors"
| "image"
| "image/color"
| "image/jpeg"
|
| "github.com/llgcode/draw2d/draw2dimg"
| )
|
| // ToImage bgr -> image.Image
| func ToImage(data []byte, w, h int) (image.Image, error) {
| width := w
| height := h
| step := w * 3
| channels := 3
|
| img := image.NewRGBA(image.Rect(0, 0, width, height))
| c := color.RGBA{
| R: uint8(0),
| G: uint8(0),
| B: uint8(0),
| A: uint8(255),
| }
|
| for y := 0; y < height; y++ {
| for x := 0; x < step; x = x + channels {
| c.B = uint8(data[y*step+x])
| c.G = uint8(data[y*step+x+1])
| c.R = uint8(data[y*step+x+2])
| if channels == 4 {
| c.A = uint8(data[y*step+x+3])
| }
| img.SetRGBA(int(x/channels), y, c)
| }
| }
|
| return img, nil
| }
|
| // Image2BGR img->bgr
| func Image2BGR(img image.Image) []byte {
| bounds := img.Bounds()
| x := bounds.Dx()
| y := bounds.Dy()
| data := make([]byte, 0, x*y*3)
| for j := bounds.Min.Y; j < bounds.Max.Y; j++ {
| for i := bounds.Min.X; i < bounds.Max.X; i++ {
| r, g, b, _ := img.At(i, j).RGBA()
| data = append(data, byte(b>>8), byte(g>>8), byte(r>>8))
| }
| }
| return data
| }
|
| // DrawRectangle draw rect
| func DrawRectangle(img image.Image, rc image.Rectangle, clr color.RGBA, lw float64) error {
|
| l, t, r, b := rc.Min.X, rc.Min.Y, rc.Max.X, rc.Max.Y
|
| pt := []image.Point{
| image.Pt(l, t),
| image.Pt(l, r),
| image.Pt(r, b),
| image.Pt(r, l),
| }
|
| return DrawPolygon(img, pt, clr, lw)
| }
|
| // DrawPolygon draw polygon
| func DrawPolygon(img image.Image, pt []image.Point, clr color.RGBA, lw float64) error {
| rgba, ok := img.(*image.RGBA)
| if !ok {
| return errors.New("IMAGE CONVERT TO RGBA ERROR")
| }
|
| pt = append(pt, pt[0])
|
| gc := draw2dimg.NewGraphicContext(rgba)
| gc.SetStrokeColor(clr)
| gc.SetLineWidth(lw)
|
| gc.BeginPath()
| start := pt[0]
| pt = pt[1:]
| gc.MoveTo((float64)(start.X), (float64)(start.Y))
| for _, v := range pt {
| gc.LineTo((float64)(v.X), (float64)(v.Y))
| }
| // gc.QuadCurveTo(100, 10, 10, 10)
| gc.Close()
| gc.Stroke()
| return nil
| }
|
| // ToJpeg bgr -> jpeg file
| func ToJpeg(bgr []byte, w, h int, quality *int) ([]byte, error) {
| img, err := ToImage(bgr, w, h)
| if err != nil {
| return nil, err
| }
| return ImageToJpeg(img, quality)
| }
|
| // ImageToJpeg save to jpeg data
| func ImageToJpeg(img image.Image, quality *int) ([]byte, error) {
| var o *jpeg.Options
|
| if quality != nil {
| o = &jpeg.Options{Quality: *quality}
| }
| var b bytes.Buffer
| w := bufio.NewWriter(&b)
| err := jpeg.Encode(w, img, o)
| if err != nil {
| return nil, err
| }
| return b.Bytes(), err
| }
|
|