graphicstest.go 2.5 KB

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