github.com/aloncn/graphics-go@v0.0.1/graphics/graphicstest/graphicstest.go (about) 1 // Copyright 2011 The Graphics-Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package graphicstest 6 7 import ( 8 "bytes" 9 "errors" 10 "fmt" 11 "image" 12 "image/color" 13 "os" 14 ) 15 16 // LoadImage decodes an image from a file. 17 func LoadImage(path string) (img image.Image, err error) { 18 file, err := os.Open(path) 19 if err != nil { 20 return 21 } 22 defer file.Close() 23 img, _, err = image.Decode(file) 24 return 25 } 26 27 func delta(u0, u1 uint32) int { 28 d := int(u0) - int(u1) 29 if d < 0 { 30 return -d 31 } 32 return d 33 } 34 35 func withinTolerance(c0, c1 color.Color, tol int) bool { 36 r0, g0, b0, a0 := c0.RGBA() 37 r1, g1, b1, a1 := c1.RGBA() 38 r := delta(r0, r1) 39 g := delta(g0, g1) 40 b := delta(b0, b1) 41 a := delta(a0, a1) 42 return r <= tol && g <= tol && b <= tol && a <= tol 43 } 44 45 // ImageWithinTolerance checks that each pixel varies by no more than tol. 46 func ImageWithinTolerance(m0, m1 image.Image, tol int) error { 47 b0 := m0.Bounds() 48 b1 := m1.Bounds() 49 if !b0.Eq(b1) { 50 return errors.New(fmt.Sprintf("got bounds %v want %v", b0, b1)) 51 } 52 53 for y := b0.Min.Y; y < b0.Max.Y; y++ { 54 for x := b0.Min.X; x < b0.Max.X; x++ { 55 c0 := m0.At(x, y) 56 c1 := m1.At(x, y) 57 if !withinTolerance(c0, c1, tol) { 58 e := fmt.Sprintf("got %v want %v at (%d, %d)", c0, c1, x, y) 59 return errors.New(e) 60 } 61 } 62 } 63 return nil 64 } 65 66 // SprintBox pretty prints the array as a hexidecimal matrix. 67 func SprintBox(box []byte, width, height int) string { 68 buf := bytes.NewBuffer(nil) 69 i := 0 70 for y := 0; y < height; y++ { 71 for x := 0; x < width; x++ { 72 fmt.Fprintf(buf, " 0x%02x,", box[i]) 73 i++ 74 } 75 buf.WriteByte('\n') 76 } 77 return buf.String() 78 } 79 80 // SprintImageR pretty prints the red channel of src. It looks like SprintBox. 81 func SprintImageR(src *image.RGBA) string { 82 w, h := src.Rect.Dx(), src.Rect.Dy() 83 i := 0 84 box := make([]byte, w*h) 85 for y := src.Rect.Min.Y; y < src.Rect.Max.Y; y++ { 86 for x := src.Rect.Min.X; x < src.Rect.Max.X; x++ { 87 off := (y-src.Rect.Min.Y)*src.Stride + (x-src.Rect.Min.X)*4 88 box[i] = src.Pix[off] 89 i++ 90 } 91 } 92 return SprintBox(box, w, h) 93 } 94 95 // MakeRGBA returns an image with R, G, B taken from src. 96 func MakeRGBA(src []uint8, width int) *image.RGBA { 97 b := image.Rect(0, 0, width, len(src)/width) 98 ret := image.NewRGBA(b) 99 i := 0 100 for y := b.Min.Y; y < b.Max.Y; y++ { 101 for x := b.Min.X; x < b.Max.X; x++ { 102 ret.SetRGBA(x, y, color.RGBA{ 103 R: src[i], 104 G: src[i], 105 B: src[i], 106 A: 0xff, 107 }) 108 i++ 109 } 110 } 111 return ret 112 }