1
0

resize_test.go 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628
  1. package imaging
  2. import (
  3. "image"
  4. "testing"
  5. )
  6. func TestResize(t *testing.T) {
  7. td := []struct {
  8. desc string
  9. src image.Image
  10. w, h int
  11. f ResampleFilter
  12. want *image.NRGBA
  13. }{
  14. {
  15. "Resize 2x2 1x1 box",
  16. &image.NRGBA{
  17. Rect: image.Rect(-1, -1, 1, 1),
  18. Stride: 2 * 4,
  19. Pix: []uint8{
  20. 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff,
  21. 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
  22. },
  23. },
  24. 1, 1,
  25. Box,
  26. &image.NRGBA{
  27. Rect: image.Rect(0, 0, 1, 1),
  28. Stride: 1 * 4,
  29. Pix: []uint8{0x55, 0x55, 0x55, 0xc0},
  30. },
  31. },
  32. {
  33. "Resize 2x2 2x2 box",
  34. &image.NRGBA{
  35. Rect: image.Rect(-1, -1, 1, 1),
  36. Stride: 2 * 4,
  37. Pix: []uint8{
  38. 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff,
  39. 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
  40. },
  41. },
  42. 2, 2,
  43. Box,
  44. &image.NRGBA{
  45. Rect: image.Rect(0, 0, 2, 2),
  46. Stride: 2 * 4,
  47. Pix: []uint8{
  48. 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff,
  49. 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
  50. },
  51. },
  52. },
  53. {
  54. "Resize 3x1 1x1 nearest",
  55. &image.NRGBA{
  56. Rect: image.Rect(-1, -1, 2, 0),
  57. Stride: 3 * 4,
  58. Pix: []uint8{
  59. 0xff, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
  60. },
  61. },
  62. 1, 1,
  63. NearestNeighbor,
  64. &image.NRGBA{
  65. Rect: image.Rect(0, 0, 1, 1),
  66. Stride: 1 * 4,
  67. Pix: []uint8{0x00, 0xff, 0x00, 0xff},
  68. },
  69. },
  70. {
  71. "Resize 2x2 0x4 box",
  72. &image.NRGBA{
  73. Rect: image.Rect(-1, -1, 1, 1),
  74. Stride: 2 * 4,
  75. Pix: []uint8{
  76. 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff,
  77. 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
  78. },
  79. },
  80. 0, 4,
  81. Box,
  82. &image.NRGBA{
  83. Rect: image.Rect(0, 0, 4, 4),
  84. Stride: 4 * 4,
  85. Pix: []uint8{
  86. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff,
  87. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff,
  88. 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff,
  89. 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff,
  90. },
  91. },
  92. },
  93. {
  94. "Resize 2x2 4x0 linear",
  95. &image.NRGBA{
  96. Rect: image.Rect(-1, -1, 1, 1),
  97. Stride: 2 * 4,
  98. Pix: []uint8{
  99. 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff,
  100. 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
  101. },
  102. },
  103. 4, 0,
  104. Linear,
  105. &image.NRGBA{
  106. Rect: image.Rect(0, 0, 4, 4),
  107. Stride: 4 * 4,
  108. Pix: []uint8{
  109. 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x40, 0xff, 0x00, 0x00, 0xbf, 0xff, 0x00, 0x00, 0xff,
  110. 0x00, 0xff, 0x00, 0x40, 0x6e, 0x6d, 0x25, 0x70, 0xb0, 0x14, 0x3b, 0xcf, 0xbf, 0x00, 0x40, 0xff,
  111. 0x00, 0xff, 0x00, 0xbf, 0x14, 0xb0, 0x3b, 0xcf, 0x33, 0x33, 0x99, 0xef, 0x40, 0x00, 0xbf, 0xff,
  112. 0x00, 0xff, 0x00, 0xff, 0x00, 0xbf, 0x40, 0xff, 0x00, 0x40, 0xbf, 0xff, 0x00, 0x00, 0xff, 0xff,
  113. },
  114. },
  115. },
  116. {
  117. "Resize 0x0 1x1 box",
  118. &image.NRGBA{
  119. Rect: image.Rect(-1, -1, -1, -1),
  120. Stride: 0,
  121. Pix: []uint8{},
  122. },
  123. 1, 1,
  124. Box,
  125. &image.NRGBA{},
  126. },
  127. {
  128. "Resize 2x2 0x0 box",
  129. &image.NRGBA{
  130. Rect: image.Rect(-1, -1, 1, 1),
  131. Stride: 2 * 4,
  132. Pix: []uint8{
  133. 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff,
  134. 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
  135. },
  136. },
  137. 0, 0,
  138. Box,
  139. &image.NRGBA{},
  140. },
  141. {
  142. "Resize 2x2 -1x0 box",
  143. &image.NRGBA{
  144. Rect: image.Rect(-1, -1, 1, 1),
  145. Stride: 2 * 4,
  146. Pix: []uint8{
  147. 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff,
  148. 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
  149. },
  150. },
  151. -1, 0,
  152. Box,
  153. &image.NRGBA{},
  154. },
  155. }
  156. for _, d := range td {
  157. got := Resize(d.src, d.w, d.h, d.f)
  158. want := d.want
  159. if !compareNRGBA(got, want, 0) {
  160. t.Errorf("test [%s] failed: %#v", d.desc, got)
  161. }
  162. }
  163. for i, filter := range []ResampleFilter{
  164. NearestNeighbor,
  165. Box,
  166. Linear,
  167. Hermite,
  168. MitchellNetravali,
  169. CatmullRom,
  170. BSpline,
  171. Gaussian,
  172. Lanczos,
  173. Hann,
  174. Hamming,
  175. Blackman,
  176. Bartlett,
  177. Welch,
  178. Cosine,
  179. } {
  180. src := image.NewNRGBA(image.Rect(-1, -1, 2, 3))
  181. got := Resize(src, 5, 6, filter)
  182. want := image.NewNRGBA(image.Rect(0, 0, 5, 6))
  183. if !compareNRGBA(got, want, 0) {
  184. t.Errorf("test [Resize all filters #%d] failed: %#v", i, got)
  185. }
  186. if filter.Kernel != nil {
  187. x := filter.Kernel(filter.Support + 0.0001)
  188. if x != 0 {
  189. t.Errorf("test [ResampleFilter edge cases #%d] failed: %f", i, x)
  190. }
  191. }
  192. }
  193. bcs2 := bcspline(2, 1, 0)
  194. if bcs2 != 0 {
  195. t.Errorf("test [bcspline 2] failed: %f", bcs2)
  196. }
  197. }
  198. func TestResizeGolden(t *testing.T) {
  199. src, err := Open("testdata/lena_512.png")
  200. if err != nil {
  201. t.Errorf("Open: %v", err)
  202. }
  203. for name, filter := range map[string]ResampleFilter{
  204. "out_resize_nearest.png": NearestNeighbor,
  205. "out_resize_linear.png": Linear,
  206. "out_resize_catrom.png": CatmullRom,
  207. "out_resize_lanczos.png": Lanczos,
  208. } {
  209. got := Resize(src, 128, 0, filter)
  210. want, err := Open("testdata/" + name)
  211. if err != nil {
  212. t.Errorf("Open: %v", err)
  213. }
  214. if !compareNRGBA(got, toNRGBA(want), 0) {
  215. t.Errorf("resulting image differs from golden: %s", name)
  216. }
  217. }
  218. }
  219. func TestFit(t *testing.T) {
  220. td := []struct {
  221. desc string
  222. src image.Image
  223. w, h int
  224. f ResampleFilter
  225. want *image.NRGBA
  226. }{
  227. {
  228. "Fit 2x2 1x10 box",
  229. &image.NRGBA{
  230. Rect: image.Rect(-1, -1, 1, 1),
  231. Stride: 2 * 4,
  232. Pix: []uint8{
  233. 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff,
  234. 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
  235. },
  236. },
  237. 1, 10,
  238. Box,
  239. &image.NRGBA{
  240. Rect: image.Rect(0, 0, 1, 1),
  241. Stride: 1 * 4,
  242. Pix: []uint8{0x55, 0x55, 0x55, 0xc0},
  243. },
  244. },
  245. {
  246. "Fit 2x2 10x1 box",
  247. &image.NRGBA{
  248. Rect: image.Rect(-1, -1, 1, 1),
  249. Stride: 2 * 4,
  250. Pix: []uint8{
  251. 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff,
  252. 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
  253. },
  254. },
  255. 10, 1,
  256. Box,
  257. &image.NRGBA{
  258. Rect: image.Rect(0, 0, 1, 1),
  259. Stride: 1 * 4,
  260. Pix: []uint8{0x55, 0x55, 0x55, 0xc0},
  261. },
  262. },
  263. {
  264. "Fit 2x2 10x10 box",
  265. &image.NRGBA{
  266. Rect: image.Rect(-1, -1, 1, 1),
  267. Stride: 2 * 4,
  268. Pix: []uint8{
  269. 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff,
  270. 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
  271. },
  272. },
  273. 10, 10,
  274. Box,
  275. &image.NRGBA{
  276. Rect: image.Rect(0, 0, 2, 2),
  277. Stride: 2 * 4,
  278. Pix: []uint8{
  279. 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff,
  280. 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
  281. },
  282. },
  283. },
  284. {
  285. "Fit 0x0 1x1 box",
  286. &image.NRGBA{
  287. Rect: image.Rect(-1, -1, -1, -1),
  288. Stride: 0,
  289. Pix: []uint8{},
  290. },
  291. 1, 1,
  292. Box,
  293. &image.NRGBA{},
  294. },
  295. {
  296. "Fit 2x2 0x0 box",
  297. &image.NRGBA{
  298. Rect: image.Rect(-1, -1, 1, 1),
  299. Stride: 2 * 4,
  300. Pix: []uint8{
  301. 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff,
  302. 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
  303. },
  304. },
  305. 0, 0,
  306. Box,
  307. &image.NRGBA{},
  308. },
  309. {
  310. "Fit 2x2 -1x0 box",
  311. &image.NRGBA{
  312. Rect: image.Rect(-1, -1, 1, 1),
  313. Stride: 2 * 4,
  314. Pix: []uint8{
  315. 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff,
  316. 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
  317. },
  318. },
  319. -1, 0,
  320. Box,
  321. &image.NRGBA{},
  322. },
  323. }
  324. for _, d := range td {
  325. got := Fit(d.src, d.w, d.h, d.f)
  326. want := d.want
  327. if !compareNRGBA(got, want, 0) {
  328. t.Errorf("test [%s] failed: %#v", d.desc, got)
  329. }
  330. }
  331. }
  332. func TestFill(t *testing.T) {
  333. td := []struct {
  334. desc string
  335. src image.Image
  336. w, h int
  337. a Anchor
  338. f ResampleFilter
  339. want *image.NRGBA
  340. }{
  341. {
  342. "Fill 4x4 2x2 Center Nearest",
  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. 2, 2,
  354. Center,
  355. NearestNeighbor,
  356. &image.NRGBA{
  357. Rect: image.Rect(0, 0, 2, 2),
  358. Stride: 2 * 4,
  359. Pix: []uint8{
  360. 0x14, 0x15, 0x16, 0x17, 0x1c, 0x1d, 0x1e, 0x1f,
  361. 0x34, 0x35, 0x36, 0x37, 0x3c, 0x3d, 0x3e, 0x3f,
  362. },
  363. },
  364. },
  365. {
  366. "Fill 4x4 1x4 TopLeft Nearest",
  367. &image.NRGBA{
  368. Rect: image.Rect(-1, -1, 3, 3),
  369. Stride: 4 * 4,
  370. Pix: []uint8{
  371. 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
  372. 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
  373. 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
  374. 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
  375. },
  376. },
  377. 1, 4,
  378. TopLeft,
  379. NearestNeighbor,
  380. &image.NRGBA{
  381. Rect: image.Rect(0, 0, 1, 4),
  382. Stride: 1 * 4,
  383. Pix: []uint8{
  384. 0x00, 0x01, 0x02, 0x03,
  385. 0x10, 0x11, 0x12, 0x13,
  386. 0x20, 0x21, 0x22, 0x23,
  387. 0x30, 0x31, 0x32, 0x33,
  388. },
  389. },
  390. },
  391. {
  392. "Fill 4x4 8x2 Bottom Nearest",
  393. &image.NRGBA{
  394. Rect: image.Rect(-1, -1, 3, 3),
  395. Stride: 4 * 4,
  396. Pix: []uint8{
  397. 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
  398. 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
  399. 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
  400. 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
  401. },
  402. },
  403. 8, 2,
  404. Bottom,
  405. NearestNeighbor,
  406. &image.NRGBA{
  407. Rect: image.Rect(0, 0, 8, 2),
  408. Stride: 8 * 4,
  409. Pix: []uint8{
  410. 0x30, 0x31, 0x32, 0x33, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x3c, 0x3d, 0x3e, 0x3f,
  411. 0x30, 0x31, 0x32, 0x33, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x3c, 0x3d, 0x3e, 0x3f,
  412. },
  413. },
  414. },
  415. {
  416. "Fill 4x4 2x8 Top Nearest",
  417. &image.NRGBA{
  418. Rect: image.Rect(-1, -1, 3, 3),
  419. Stride: 4 * 4,
  420. Pix: []uint8{
  421. 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
  422. 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
  423. 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
  424. 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
  425. },
  426. },
  427. 2, 8,
  428. Top,
  429. NearestNeighbor,
  430. &image.NRGBA{
  431. Rect: image.Rect(0, 0, 2, 8),
  432. Stride: 2 * 4,
  433. Pix: []uint8{
  434. 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
  435. 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
  436. 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b,
  437. 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b,
  438. 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b,
  439. 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b,
  440. 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
  441. 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
  442. },
  443. },
  444. },
  445. {
  446. "Fill 4x4 4x4 TopRight Box",
  447. &image.NRGBA{
  448. Rect: image.Rect(-1, -1, 3, 3),
  449. Stride: 4 * 4,
  450. Pix: []uint8{
  451. 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
  452. 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
  453. 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
  454. 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
  455. },
  456. },
  457. 4, 4,
  458. TopRight,
  459. Box,
  460. &image.NRGBA{
  461. Rect: image.Rect(0, 0, 4, 4),
  462. Stride: 4 * 4,
  463. Pix: []uint8{
  464. 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
  465. 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
  466. 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
  467. 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
  468. },
  469. },
  470. },
  471. {
  472. "Fill 4x4 0x4 Left Box",
  473. &image.NRGBA{
  474. Rect: image.Rect(-1, -1, 3, 3),
  475. Stride: 4 * 4,
  476. Pix: []uint8{
  477. 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
  478. 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
  479. 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
  480. 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
  481. },
  482. },
  483. 0, 4,
  484. Left,
  485. Box,
  486. &image.NRGBA{},
  487. },
  488. {
  489. "Fill 0x0 4x4 Right Box",
  490. &image.NRGBA{},
  491. 4, 4,
  492. Right,
  493. Box,
  494. &image.NRGBA{},
  495. },
  496. }
  497. for _, d := range td {
  498. got := Fill(d.src, d.w, d.h, d.a, d.f)
  499. want := d.want
  500. if !compareNRGBA(got, want, 0) {
  501. t.Errorf("test [%s] failed: %#v", d.desc, got)
  502. }
  503. }
  504. }
  505. func TestThumbnail(t *testing.T) {
  506. td := []struct {
  507. desc string
  508. src image.Image
  509. w, h int
  510. f ResampleFilter
  511. want *image.NRGBA
  512. }{
  513. {
  514. "Thumbnail 6x2 1x1 box",
  515. &image.NRGBA{
  516. Rect: image.Rect(-1, -1, 5, 1),
  517. Stride: 6 * 4,
  518. Pix: []uint8{
  519. 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  520. 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  521. },
  522. },
  523. 1, 1,
  524. Box,
  525. &image.NRGBA{
  526. Rect: image.Rect(0, 0, 1, 1),
  527. Stride: 1 * 4,
  528. Pix: []uint8{0x55, 0x55, 0x55, 0xc0},
  529. },
  530. },
  531. {
  532. "Thumbnail 2x6 1x1 box",
  533. &image.NRGBA{
  534. Rect: image.Rect(-1, -1, 1, 5),
  535. Stride: 2 * 4,
  536. Pix: []uint8{
  537. 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  538. 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  539. 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff,
  540. 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
  541. 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  542. 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  543. },
  544. },
  545. 1, 1,
  546. Box,
  547. &image.NRGBA{
  548. Rect: image.Rect(0, 0, 1, 1),
  549. Stride: 1 * 4,
  550. Pix: []uint8{0x55, 0x55, 0x55, 0xc0},
  551. },
  552. },
  553. {
  554. "Thumbnail 1x3 2x2 box",
  555. &image.NRGBA{
  556. Rect: image.Rect(-1, -1, 0, 2),
  557. Stride: 1 * 4,
  558. Pix: []uint8{
  559. 0x00, 0x00, 0x00, 0x00,
  560. 0xff, 0x00, 0x00, 0xff,
  561. 0xff, 0xff, 0xff, 0xff,
  562. },
  563. },
  564. 2, 2,
  565. Box,
  566. &image.NRGBA{
  567. Rect: image.Rect(0, 0, 2, 2),
  568. Stride: 2 * 4,
  569. Pix: []uint8{
  570. 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff,
  571. 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff,
  572. },
  573. },
  574. },
  575. }
  576. for _, d := range td {
  577. got := Thumbnail(d.src, d.w, d.h, d.f)
  578. want := d.want
  579. if !compareNRGBA(got, want, 0) {
  580. t.Errorf("test [%s] failed: %#v", d.desc, got)
  581. }
  582. }
  583. }
  584. func BenchmarkResizeLanczosUp(b *testing.B) {
  585. benchmarkResize(b, "testdata/lena_128.png", 512, Lanczos)
  586. }
  587. func BenchmarkResizeLinearUp(b *testing.B) {
  588. benchmarkResize(b, "testdata/lena_128.png", 512, Linear)
  589. }
  590. func BenchmarkResizeNearestNeighborUp(b *testing.B) {
  591. benchmarkResize(b, "testdata/lena_128.png", 512, NearestNeighbor)
  592. }
  593. func BenchmarkResizeLanczosDown(b *testing.B) {
  594. benchmarkResize(b, "testdata/lena_512.png", 128, Lanczos)
  595. }
  596. func BenchmarkResizeLinearDown(b *testing.B) {
  597. benchmarkResize(b, "testdata/lena_512.png", 128, Linear)
  598. }
  599. func BenchmarkResizeNearestNeighborDown(b *testing.B) {
  600. benchmarkResize(b, "testdata/lena_512.png", 128, NearestNeighbor)
  601. }
  602. func benchmarkResize(b *testing.B, filename string, size int, f ResampleFilter) {
  603. b.StopTimer()
  604. img, err := Open(filename)
  605. if err != nil {
  606. b.Fatalf("Open: %v", err)
  607. }
  608. b.StartTimer()
  609. for i := 0; i < b.N; i++ {
  610. Resize(img, size, size, f)
  611. }
  612. }