New file |
| | |
| | | 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 |
| | | } |