tools_test.go 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808
  1. package imaging
  2. import (
  3. "image"
  4. "testing"
  5. )
  6. func TestCrop(t *testing.T) {
  7. testCases := []struct {
  8. name string
  9. src image.Image
  10. r image.Rectangle
  11. want *image.NRGBA
  12. }{
  13. {
  14. "Crop 2x3 2x1",
  15. &image.NRGBA{
  16. Rect: image.Rect(-1, -1, 1, 2),
  17. Stride: 2 * 4,
  18. Pix: []uint8{
  19. 0x00, 0x11, 0x22, 0x33, 0xcc, 0xdd, 0xee, 0xff,
  20. 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
  21. 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
  22. },
  23. },
  24. image.Rect(-1, 0, 1, 1),
  25. &image.NRGBA{
  26. Rect: image.Rect(0, 0, 2, 1),
  27. Stride: 2 * 4,
  28. Pix: []uint8{
  29. 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
  30. },
  31. },
  32. },
  33. }
  34. for _, tc := range testCases {
  35. t.Run(tc.name, func(t *testing.T) {
  36. got := Crop(tc.src, tc.r)
  37. if !compareNRGBA(got, tc.want, 0) {
  38. t.Fatalf("got result %#v want %#v", got, tc.want)
  39. }
  40. })
  41. }
  42. }
  43. func BenchmarkCrop(b *testing.B) {
  44. b.ReportAllocs()
  45. for i := 0; i < b.N; i++ {
  46. Crop(testdataBranchesJPG, image.Rect(100, 100, 300, 300))
  47. }
  48. }
  49. func TestCropCenter(t *testing.T) {
  50. testCases := []struct {
  51. name string
  52. src image.Image
  53. w, h int
  54. want *image.NRGBA
  55. }{
  56. {
  57. "CropCenter 2x3 2x1",
  58. &image.NRGBA{
  59. Rect: image.Rect(-1, -1, 1, 2),
  60. Stride: 2 * 4,
  61. Pix: []uint8{
  62. 0x00, 0x11, 0x22, 0x33, 0xcc, 0xdd, 0xee, 0xff,
  63. 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
  64. 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
  65. },
  66. },
  67. 2, 1,
  68. &image.NRGBA{
  69. Rect: image.Rect(0, 0, 2, 1),
  70. Stride: 2 * 4,
  71. Pix: []uint8{
  72. 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
  73. },
  74. },
  75. },
  76. {
  77. "CropCenter 2x3 0x1",
  78. &image.NRGBA{
  79. Rect: image.Rect(-1, -1, 1, 2),
  80. Stride: 2 * 4,
  81. Pix: []uint8{
  82. 0x00, 0x11, 0x22, 0x33, 0xcc, 0xdd, 0xee, 0xff,
  83. 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
  84. 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
  85. },
  86. },
  87. 0, 1,
  88. &image.NRGBA{
  89. Rect: image.Rect(0, 0, 0, 0),
  90. Stride: 0,
  91. Pix: []uint8{},
  92. },
  93. },
  94. {
  95. "CropCenter 2x3 5x5",
  96. &image.NRGBA{
  97. Rect: image.Rect(-1, -1, 1, 2),
  98. Stride: 2 * 4,
  99. Pix: []uint8{
  100. 0x00, 0x11, 0x22, 0x33, 0xcc, 0xdd, 0xee, 0xff,
  101. 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
  102. 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
  103. },
  104. },
  105. 5, 5,
  106. &image.NRGBA{
  107. Rect: image.Rect(0, 0, 2, 3),
  108. Stride: 2 * 4,
  109. Pix: []uint8{
  110. 0x00, 0x11, 0x22, 0x33, 0xcc, 0xdd, 0xee, 0xff,
  111. 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
  112. 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
  113. },
  114. },
  115. },
  116. }
  117. for _, tc := range testCases {
  118. t.Run(tc.name, func(t *testing.T) {
  119. got := CropCenter(tc.src, tc.w, tc.h)
  120. if !compareNRGBA(got, tc.want, 0) {
  121. t.Fatalf("got result %#v want %#v", got, tc.want)
  122. }
  123. })
  124. }
  125. }
  126. func TestCropAnchor(t *testing.T) {
  127. testCases := []struct {
  128. name string
  129. src image.Image
  130. w, h int
  131. anchor Anchor
  132. want *image.NRGBA
  133. }{
  134. {
  135. "CropAnchor 4x4 2x2 TopLeft",
  136. &image.NRGBA{
  137. Rect: image.Rect(-1, -1, 3, 3),
  138. Stride: 4 * 4,
  139. Pix: []uint8{
  140. 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
  141. 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
  142. 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
  143. 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
  144. },
  145. },
  146. 2, 2,
  147. TopLeft,
  148. &image.NRGBA{
  149. Rect: image.Rect(0, 0, 2, 2),
  150. Stride: 2 * 4,
  151. Pix: []uint8{
  152. 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
  153. 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
  154. },
  155. },
  156. },
  157. {
  158. "CropAnchor 4x4 2x2 Top",
  159. &image.NRGBA{
  160. Rect: image.Rect(-1, -1, 3, 3),
  161. Stride: 4 * 4,
  162. Pix: []uint8{
  163. 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
  164. 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
  165. 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
  166. 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
  167. },
  168. },
  169. 2, 2,
  170. Top,
  171. &image.NRGBA{
  172. Rect: image.Rect(0, 0, 2, 2),
  173. Stride: 2 * 4,
  174. Pix: []uint8{
  175. 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
  176. 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b,
  177. },
  178. },
  179. },
  180. {
  181. "CropAnchor 4x4 2x2 TopRight",
  182. &image.NRGBA{
  183. Rect: image.Rect(-1, -1, 3, 3),
  184. Stride: 4 * 4,
  185. Pix: []uint8{
  186. 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
  187. 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
  188. 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
  189. 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
  190. },
  191. },
  192. 2, 2,
  193. TopRight,
  194. &image.NRGBA{
  195. Rect: image.Rect(0, 0, 2, 2),
  196. Stride: 2 * 4,
  197. Pix: []uint8{
  198. 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
  199. 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
  200. },
  201. },
  202. },
  203. {
  204. "CropAnchor 4x4 2x2 Left",
  205. &image.NRGBA{
  206. Rect: image.Rect(-1, -1, 3, 3),
  207. Stride: 4 * 4,
  208. Pix: []uint8{
  209. 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
  210. 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
  211. 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
  212. 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
  213. },
  214. },
  215. 2, 2,
  216. Left,
  217. &image.NRGBA{
  218. Rect: image.Rect(0, 0, 2, 2),
  219. Stride: 2 * 4,
  220. Pix: []uint8{
  221. 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
  222. 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
  223. },
  224. },
  225. },
  226. {
  227. "CropAnchor 4x4 2x2 Center",
  228. &image.NRGBA{
  229. Rect: image.Rect(-1, -1, 3, 3),
  230. Stride: 4 * 4,
  231. Pix: []uint8{
  232. 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
  233. 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
  234. 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
  235. 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
  236. },
  237. },
  238. 2, 2,
  239. Center,
  240. &image.NRGBA{
  241. Rect: image.Rect(0, 0, 2, 2),
  242. Stride: 2 * 4,
  243. Pix: []uint8{
  244. 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b,
  245. 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b,
  246. },
  247. },
  248. },
  249. {
  250. "CropAnchor 4x4 2x2 Right",
  251. &image.NRGBA{
  252. Rect: image.Rect(-1, -1, 3, 3),
  253. Stride: 4 * 4,
  254. Pix: []uint8{
  255. 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
  256. 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
  257. 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
  258. 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
  259. },
  260. },
  261. 2, 2,
  262. Right,
  263. &image.NRGBA{
  264. Rect: image.Rect(0, 0, 2, 2),
  265. Stride: 2 * 4,
  266. Pix: []uint8{
  267. 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
  268. 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
  269. },
  270. },
  271. },
  272. {
  273. "CropAnchor 4x4 2x2 BottomLeft",
  274. &image.NRGBA{
  275. Rect: image.Rect(-1, -1, 3, 3),
  276. Stride: 4 * 4,
  277. Pix: []uint8{
  278. 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
  279. 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
  280. 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
  281. 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
  282. },
  283. },
  284. 2, 2,
  285. BottomLeft,
  286. &image.NRGBA{
  287. Rect: image.Rect(0, 0, 2, 2),
  288. Stride: 2 * 4,
  289. Pix: []uint8{
  290. 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
  291. 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
  292. },
  293. },
  294. },
  295. {
  296. "CropAnchor 4x4 2x2 Bottom",
  297. &image.NRGBA{
  298. Rect: image.Rect(-1, -1, 3, 3),
  299. Stride: 4 * 4,
  300. Pix: []uint8{
  301. 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
  302. 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
  303. 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
  304. 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
  305. },
  306. },
  307. 2, 2,
  308. Bottom,
  309. &image.NRGBA{
  310. Rect: image.Rect(0, 0, 2, 2),
  311. Stride: 2 * 4,
  312. Pix: []uint8{
  313. 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b,
  314. 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
  315. },
  316. },
  317. },
  318. {
  319. "CropAnchor 4x4 2x2 BottomRight",
  320. &image.NRGBA{
  321. Rect: image.Rect(-1, -1, 3, 3),
  322. Stride: 4 * 4,
  323. Pix: []uint8{
  324. 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
  325. 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
  326. 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
  327. 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
  328. },
  329. },
  330. 2, 2,
  331. BottomRight,
  332. &image.NRGBA{
  333. Rect: image.Rect(0, 0, 2, 2),
  334. Stride: 2 * 4,
  335. Pix: []uint8{
  336. 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
  337. 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
  338. },
  339. },
  340. },
  341. {
  342. "CropAnchor 4x4 0x0 BottomRight",
  343. &image.NRGBA{
  344. Rect: image.Rect(-1, -1, 3, 3),
  345. Stride: 4 * 4,
  346. Pix: []uint8{
  347. 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
  348. 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
  349. 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
  350. 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
  351. },
  352. },
  353. 0, 0,
  354. BottomRight,
  355. &image.NRGBA{
  356. Rect: image.Rect(0, 0, 0, 0),
  357. Stride: 0,
  358. Pix: []uint8{},
  359. },
  360. },
  361. {
  362. "CropAnchor 4x4 100x100 BottomRight",
  363. &image.NRGBA{
  364. Rect: image.Rect(-1, -1, 3, 3),
  365. Stride: 4 * 4,
  366. Pix: []uint8{
  367. 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
  368. 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
  369. 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
  370. 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
  371. },
  372. },
  373. 100, 100,
  374. BottomRight,
  375. &image.NRGBA{
  376. Rect: image.Rect(0, 0, 4, 4),
  377. Stride: 4 * 4,
  378. Pix: []uint8{
  379. 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
  380. 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
  381. 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
  382. 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
  383. },
  384. },
  385. },
  386. {
  387. "CropAnchor 4x4 1x100 BottomRight",
  388. &image.NRGBA{
  389. Rect: image.Rect(-1, -1, 3, 3),
  390. Stride: 4 * 4,
  391. Pix: []uint8{
  392. 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
  393. 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
  394. 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
  395. 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
  396. },
  397. },
  398. 1, 100,
  399. BottomRight,
  400. &image.NRGBA{
  401. Rect: image.Rect(0, 0, 1, 4),
  402. Stride: 1 * 4,
  403. Pix: []uint8{
  404. 0x0c, 0x0d, 0x0e, 0x0f,
  405. 0x1c, 0x1d, 0x1e, 0x1f,
  406. 0x2c, 0x2d, 0x2e, 0x2f,
  407. 0x3c, 0x3d, 0x3e, 0x3f,
  408. },
  409. },
  410. },
  411. {
  412. "CropAnchor 4x4 0x100 BottomRight",
  413. &image.NRGBA{
  414. Rect: image.Rect(-1, -1, 3, 3),
  415. Stride: 4 * 4,
  416. Pix: []uint8{
  417. 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
  418. 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
  419. 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
  420. 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
  421. },
  422. },
  423. 0, 100,
  424. BottomRight,
  425. &image.NRGBA{
  426. Rect: image.Rect(0, 0, 0, 0),
  427. Stride: 0,
  428. Pix: []uint8{},
  429. },
  430. },
  431. }
  432. for _, tc := range testCases {
  433. t.Run(tc.name, func(t *testing.T) {
  434. got := CropAnchor(tc.src, tc.w, tc.h, tc.anchor)
  435. if !compareNRGBA(got, tc.want, 0) {
  436. t.Fatalf("got result %#v want %#v", got, tc.want)
  437. }
  438. })
  439. }
  440. }
  441. func TestPaste(t *testing.T) {
  442. testCases := []struct {
  443. name string
  444. src1 image.Image
  445. src2 image.Image
  446. p image.Point
  447. want *image.NRGBA
  448. }{
  449. {
  450. "Paste 2x3 2x1",
  451. &image.NRGBA{
  452. Rect: image.Rect(-1, -1, 1, 2),
  453. Stride: 2 * 4,
  454. Pix: []uint8{
  455. 0x00, 0x11, 0x22, 0x33, 0xcc, 0xdd, 0xee, 0xff,
  456. 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
  457. 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
  458. },
  459. },
  460. &image.NRGBA{
  461. Rect: image.Rect(1, 1, 3, 2),
  462. Stride: 2 * 4,
  463. Pix: []uint8{
  464. 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
  465. },
  466. },
  467. image.Pt(-1, 0),
  468. &image.NRGBA{
  469. Rect: image.Rect(0, 0, 2, 3),
  470. Stride: 2 * 4,
  471. Pix: []uint8{
  472. 0x00, 0x11, 0x22, 0x33, 0xcc, 0xdd, 0xee, 0xff,
  473. 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
  474. 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
  475. },
  476. },
  477. },
  478. {
  479. "Paste 3x4 4x3 bottom right intersection",
  480. &image.NRGBA{
  481. Rect: image.Rect(-1, -1, 2, 3),
  482. Stride: 3 * 4,
  483. Pix: []uint8{
  484. 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b,
  485. 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b,
  486. 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
  487. 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b,
  488. },
  489. },
  490. &image.NRGBA{
  491. Rect: image.Rect(1, 1, 5, 4),
  492. Stride: 4 * 4,
  493. Pix: []uint8{
  494. 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
  495. 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
  496. 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
  497. },
  498. },
  499. image.Pt(0, 1),
  500. &image.NRGBA{
  501. Rect: image.Rect(0, 0, 3, 4),
  502. Stride: 3 * 4,
  503. Pix: []uint8{
  504. 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b,
  505. 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b,
  506. 0x30, 0x31, 0x32, 0x33, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
  507. 0x40, 0x41, 0x42, 0x43, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
  508. },
  509. },
  510. },
  511. {
  512. "Paste 3x4 4x3 top left intersection",
  513. &image.NRGBA{
  514. Rect: image.Rect(-1, -1, 2, 3),
  515. Stride: 3 * 4,
  516. Pix: []uint8{
  517. 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b,
  518. 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b,
  519. 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
  520. 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b,
  521. },
  522. },
  523. &image.NRGBA{
  524. Rect: image.Rect(1, 1, 5, 4),
  525. Stride: 4 * 4,
  526. Pix: []uint8{
  527. 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
  528. 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
  529. 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
  530. },
  531. },
  532. image.Pt(-3, -2),
  533. &image.NRGBA{
  534. Rect: image.Rect(0, 0, 3, 4),
  535. Stride: 3 * 4,
  536. Pix: []uint8{
  537. 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0x18, 0x19, 0x1a, 0x1b,
  538. 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0x28, 0x29, 0x2a, 0x2b,
  539. 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
  540. 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b,
  541. },
  542. },
  543. },
  544. {
  545. "Paste 3x4 4x3 no intersection",
  546. &image.NRGBA{
  547. Rect: image.Rect(-1, -1, 2, 3),
  548. Stride: 3 * 4,
  549. Pix: []uint8{
  550. 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b,
  551. 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b,
  552. 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
  553. 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b,
  554. },
  555. },
  556. &image.NRGBA{
  557. Rect: image.Rect(1, 1, 5, 4),
  558. Stride: 4 * 4,
  559. Pix: []uint8{
  560. 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
  561. 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
  562. 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
  563. },
  564. },
  565. image.Pt(-20, 20),
  566. &image.NRGBA{
  567. Rect: image.Rect(0, 0, 3, 4),
  568. Stride: 3 * 4,
  569. Pix: []uint8{
  570. 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b,
  571. 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b,
  572. 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
  573. 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b,
  574. },
  575. },
  576. },
  577. }
  578. for _, tc := range testCases {
  579. t.Run(tc.name, func(t *testing.T) {
  580. got := Paste(tc.src1, tc.src2, tc.p)
  581. if !compareNRGBA(got, tc.want, 0) {
  582. t.Fatalf("got result %#v want %#v", got, tc.want)
  583. }
  584. })
  585. }
  586. }
  587. func BenchmarkPaste(b *testing.B) {
  588. b.ReportAllocs()
  589. for i := 0; i < b.N; i++ {
  590. Paste(testdataBranchesJPG, testdataFlowersSmallPNG, image.Pt(100, 100))
  591. }
  592. }
  593. func TestPasteCenter(t *testing.T) {
  594. testCases := []struct {
  595. name string
  596. src1 image.Image
  597. src2 image.Image
  598. want *image.NRGBA
  599. }{
  600. {
  601. "PasteCenter 2x3 2x1",
  602. &image.NRGBA{
  603. Rect: image.Rect(-1, -1, 1, 2),
  604. Stride: 2 * 4,
  605. Pix: []uint8{
  606. 0x00, 0x11, 0x22, 0x33, 0xcc, 0xdd, 0xee, 0xff,
  607. 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
  608. 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
  609. },
  610. },
  611. &image.NRGBA{
  612. Rect: image.Rect(1, 1, 3, 2),
  613. Stride: 2 * 4,
  614. Pix: []uint8{
  615. 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
  616. },
  617. },
  618. &image.NRGBA{
  619. Rect: image.Rect(0, 0, 2, 3),
  620. Stride: 2 * 4,
  621. Pix: []uint8{
  622. 0x00, 0x11, 0x22, 0x33, 0xcc, 0xdd, 0xee, 0xff,
  623. 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
  624. 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
  625. },
  626. },
  627. },
  628. }
  629. for _, tc := range testCases {
  630. t.Run(tc.name, func(t *testing.T) {
  631. got := PasteCenter(tc.src1, tc.src2)
  632. if !compareNRGBA(got, tc.want, 0) {
  633. t.Fatalf("got result %#v want %#v", got, tc.want)
  634. }
  635. })
  636. }
  637. }
  638. func TestOverlay(t *testing.T) {
  639. testCases := []struct {
  640. name string
  641. src1 image.Image
  642. src2 image.Image
  643. p image.Point
  644. a float64
  645. want *image.NRGBA
  646. }{
  647. {
  648. "Overlay 2x3 2x1 1.0",
  649. &image.NRGBA{
  650. Rect: image.Rect(-1, -1, 1, 2),
  651. Stride: 2 * 4,
  652. Pix: []uint8{
  653. 0x00, 0x11, 0x22, 0x33, 0xcc, 0xdd, 0xee, 0xff,
  654. 0x60, 0x00, 0x90, 0xff, 0xff, 0x00, 0x99, 0x7f,
  655. 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
  656. },
  657. },
  658. &image.NRGBA{
  659. Rect: image.Rect(1, 1, 3, 2),
  660. Stride: 2 * 4,
  661. Pix: []uint8{
  662. 0x20, 0x40, 0x80, 0x7f, 0xaa, 0xbb, 0xcc, 0xff,
  663. },
  664. },
  665. image.Pt(-1, 0),
  666. 1.0,
  667. &image.NRGBA{
  668. Rect: image.Rect(0, 0, 2, 3),
  669. Stride: 2 * 4,
  670. Pix: []uint8{
  671. 0x00, 0x11, 0x22, 0x33, 0xcc, 0xdd, 0xee, 0xff,
  672. 0x40, 0x1f, 0x88, 0xff, 0xaa, 0xbb, 0xcc, 0xff,
  673. 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff,
  674. },
  675. },
  676. },
  677. {
  678. "Overlay 2x2 2x2 0.5",
  679. &image.NRGBA{
  680. Rect: image.Rect(-1, -1, 1, 1),
  681. Stride: 2 * 4,
  682. Pix: []uint8{
  683. 0xff, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff,
  684. 0x00, 0x00, 0xff, 0xff, 0x20, 0x20, 0x20, 0x00,
  685. },
  686. },
  687. &image.NRGBA{
  688. Rect: image.Rect(-1, -1, 1, 1),
  689. Stride: 2 * 4,
  690. Pix: []uint8{
  691. 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
  692. 0xff, 0xff, 0x00, 0xff, 0x20, 0x20, 0x20, 0xff,
  693. },
  694. },
  695. image.Pt(-1, -1),
  696. 0.5,
  697. &image.NRGBA{
  698. Rect: image.Rect(0, 0, 2, 2),
  699. Stride: 2 * 4,
  700. Pix: []uint8{
  701. 0xff, 0x7f, 0x7f, 0xff, 0x00, 0xff, 0x00, 0xff,
  702. 0x7f, 0x7f, 0x7f, 0xff, 0x20, 0x20, 0x20, 0x7f,
  703. },
  704. },
  705. },
  706. {
  707. "Overlay 2x2 2x2 0.5 no intersection",
  708. &image.NRGBA{
  709. Rect: image.Rect(-1, -1, 1, 1),
  710. Stride: 2 * 4,
  711. Pix: []uint8{
  712. 0xff, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff,
  713. 0x00, 0x00, 0xff, 0xff, 0x20, 0x20, 0x20, 0x00,
  714. },
  715. },
  716. &image.NRGBA{
  717. Rect: image.Rect(-1, -1, 1, 1),
  718. Stride: 2 * 4,
  719. Pix: []uint8{
  720. 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
  721. 0xff, 0xff, 0x00, 0xff, 0x20, 0x20, 0x20, 0xff,
  722. },
  723. },
  724. image.Pt(-10, 10),
  725. 0.5,
  726. &image.NRGBA{
  727. Rect: image.Rect(0, 0, 2, 2),
  728. Stride: 2 * 4,
  729. Pix: []uint8{
  730. 0xff, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff,
  731. 0x00, 0x00, 0xff, 0xff, 0x20, 0x20, 0x20, 0x00,
  732. },
  733. },
  734. },
  735. }
  736. for _, tc := range testCases {
  737. t.Run(tc.name, func(t *testing.T) {
  738. got := Overlay(tc.src1, tc.src2, tc.p, tc.a)
  739. if !compareNRGBA(got, tc.want, 0) {
  740. t.Fatalf("got result %#v want %#v", got, tc.want)
  741. }
  742. })
  743. }
  744. }
  745. func BenchmarkOverlay(b *testing.B) {
  746. b.ReportAllocs()
  747. for i := 0; i < b.N; i++ {
  748. Overlay(testdataBranchesJPG, testdataFlowersSmallPNG, image.Pt(100, 100), 0.5)
  749. }
  750. }
  751. func TestOverlayCenter(t *testing.T) {
  752. testCases := []struct {
  753. name string
  754. src1 image.Image
  755. src2 image.Image
  756. a float64
  757. want *image.NRGBA
  758. }{
  759. {
  760. "OverlayCenter 2x3 2x1",
  761. &image.NRGBA{
  762. Rect: image.Rect(-1, -1, 1, 2),
  763. Stride: 2 * 4,
  764. Pix: []uint8{
  765. 0x10, 0x10, 0x10, 0xff, 0x10, 0x10, 0x10, 0xff,
  766. 0x10, 0x10, 0x10, 0xff, 0x10, 0x10, 0x10, 0xff,
  767. 0x10, 0x10, 0x10, 0xff, 0x10, 0x10, 0x10, 0xff,
  768. },
  769. },
  770. &image.NRGBA{
  771. Rect: image.Rect(1, 1, 3, 2),
  772. Stride: 2 * 4,
  773. Pix: []uint8{
  774. 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  775. },
  776. },
  777. 0.5,
  778. &image.NRGBA{
  779. Rect: image.Rect(0, 0, 2, 3),
  780. Stride: 2 * 4,
  781. Pix: []uint8{
  782. 0x10, 0x10, 0x10, 0xff, 0x10, 0x10, 0x10, 0xff,
  783. 0x2c, 0x2c, 0x2c, 0xff, 0x2c, 0x2c, 0x2c, 0xff,
  784. 0x10, 0x10, 0x10, 0xff, 0x10, 0x10, 0x10, 0xff,
  785. },
  786. },
  787. },
  788. }
  789. for _, tc := range testCases {
  790. t.Run(tc.name, func(t *testing.T) {
  791. got := OverlayCenter(tc.src1, tc.src2, 0.5)
  792. if !compareNRGBA(got, tc.want, 0) {
  793. t.Fatalf("got result %#v want %#v", got, tc.want)
  794. }
  795. })
  796. }
  797. }