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  }