processing_test.go 26 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024
  1. package processing
  2. import (
  3. "context"
  4. "fmt"
  5. "os"
  6. "path/filepath"
  7. "testing"
  8. "github.com/stretchr/testify/suite"
  9. "github.com/imgproxy/imgproxy/v3/config"
  10. "github.com/imgproxy/imgproxy/v3/fetcher"
  11. "github.com/imgproxy/imgproxy/v3/ierrors"
  12. "github.com/imgproxy/imgproxy/v3/imagedata"
  13. "github.com/imgproxy/imgproxy/v3/logger"
  14. "github.com/imgproxy/imgproxy/v3/options"
  15. "github.com/imgproxy/imgproxy/v3/security"
  16. "github.com/imgproxy/imgproxy/v3/vips"
  17. )
  18. type ProcessingTestSuite struct {
  19. suite.Suite
  20. idf *imagedata.Factory
  21. pof *options.Factory
  22. }
  23. func (s *ProcessingTestSuite) SetupSuite() {
  24. config.Reset()
  25. config.MaxSrcResolution = 10 * 1024 * 1024
  26. config.MaxSrcFileSize = 10 * 1024 * 1024
  27. config.MaxAnimationFrames = 100
  28. config.MaxAnimationFrameResolution = 10 * 1024 * 1024
  29. s.Require().NoError(vips.Init())
  30. logger.Mute()
  31. fc := fetcher.NewDefaultConfig()
  32. f, err := fetcher.New(&fc)
  33. s.Require().NoError(err)
  34. s.idf = imagedata.NewFactory(f)
  35. scfg, err := security.LoadConfigFromEnv(nil)
  36. s.Require().NoError(err)
  37. security, err := security.New(scfg)
  38. s.Require().NoError(err)
  39. cfg, err := options.LoadConfigFromEnv(nil)
  40. s.Require().NoError(err)
  41. s.pof, err = options.NewFactory(cfg, security)
  42. s.Require().NoError(err)
  43. }
  44. func (s *ProcessingTestSuite) TearDownSuite() {
  45. logger.Unmute()
  46. }
  47. func (s *ProcessingTestSuite) openFile(name string) imagedata.ImageData {
  48. wd, err := os.Getwd()
  49. s.Require().NoError(err)
  50. path := filepath.Join(wd, "..", "testdata", name)
  51. imagedata, err := s.idf.NewFromPath(path)
  52. s.Require().NoError(err)
  53. return imagedata
  54. }
  55. func (s *ProcessingTestSuite) checkSize(r *Result, width, height int) {
  56. s.Require().NotNil(r)
  57. s.Require().Equal(width, r.ResultWidth, "Width mismatch")
  58. s.Require().Equal(height, r.ResultHeight, "Height mismatch")
  59. }
  60. func (s *ProcessingTestSuite) TestResizeToFit() {
  61. imgdata := s.openFile("test2.jpg")
  62. po := s.pof.NewProcessingOptions()
  63. po.ResizingType = options.ResizeFit
  64. testCases := []struct {
  65. width int
  66. height int
  67. outWidth int
  68. outHeight int
  69. }{
  70. {width: 50, height: 50, outWidth: 50, outHeight: 25},
  71. {width: 50, height: 20, outWidth: 40, outHeight: 20},
  72. {width: 20, height: 50, outWidth: 20, outHeight: 10},
  73. {width: 300, height: 300, outWidth: 200, outHeight: 100},
  74. {width: 300, height: 50, outWidth: 100, outHeight: 50},
  75. {width: 100, height: 300, outWidth: 100, outHeight: 50},
  76. {width: 0, height: 50, outWidth: 100, outHeight: 50},
  77. {width: 50, height: 0, outWidth: 50, outHeight: 25},
  78. {width: 0, height: 200, outWidth: 200, outHeight: 100},
  79. {width: 300, height: 0, outWidth: 200, outHeight: 100},
  80. }
  81. for _, tc := range testCases {
  82. s.Run(fmt.Sprintf("%dx%d", tc.width, tc.height), func() {
  83. po.Width = tc.width
  84. po.Height = tc.height
  85. result, err := ProcessImage(context.Background(), imgdata, po, nil)
  86. s.Require().NoError(err)
  87. s.Require().NotNil(result)
  88. s.checkSize(result, tc.outWidth, tc.outHeight)
  89. })
  90. }
  91. }
  92. func (s *ProcessingTestSuite) TestResizeToFitEnlarge() {
  93. imgdata := s.openFile("test2.jpg")
  94. po := s.pof.NewProcessingOptions()
  95. po.ResizingType = options.ResizeFit
  96. po.Enlarge = true
  97. testCases := []struct {
  98. width int
  99. height int
  100. outWidth int
  101. outHeight int
  102. }{
  103. {width: 50, height: 50, outWidth: 50, outHeight: 25},
  104. {width: 50, height: 20, outWidth: 40, outHeight: 20},
  105. {width: 20, height: 50, outWidth: 20, outHeight: 10},
  106. {width: 300, height: 300, outWidth: 300, outHeight: 150},
  107. {width: 300, height: 125, outWidth: 250, outHeight: 125},
  108. {width: 250, height: 300, outWidth: 250, outHeight: 125},
  109. {width: 0, height: 50, outWidth: 100, outHeight: 50},
  110. {width: 50, height: 0, outWidth: 50, outHeight: 25},
  111. {width: 0, height: 200, outWidth: 400, outHeight: 200},
  112. {width: 300, height: 0, outWidth: 300, outHeight: 150},
  113. }
  114. for _, tc := range testCases {
  115. s.Run(fmt.Sprintf("%dx%d", tc.width, tc.height), func() {
  116. po.Width = tc.width
  117. po.Height = tc.height
  118. result, err := ProcessImage(context.Background(), imgdata, po, nil)
  119. s.Require().NoError(err)
  120. s.Require().NotNil(result)
  121. s.checkSize(result, tc.outWidth, tc.outHeight)
  122. })
  123. }
  124. }
  125. func (s *ProcessingTestSuite) TestResizeToFitExtend() {
  126. imgdata := s.openFile("test2.jpg")
  127. po := s.pof.NewProcessingOptions()
  128. po.ResizingType = options.ResizeFit
  129. po.Extend = options.ExtendOptions{
  130. Enabled: true,
  131. Gravity: options.GravityOptions{
  132. Type: options.GravityCenter,
  133. },
  134. }
  135. testCases := []struct {
  136. width int
  137. height int
  138. outWidth int
  139. outHeight int
  140. }{
  141. {width: 50, height: 50, outWidth: 50, outHeight: 50},
  142. {width: 50, height: 20, outWidth: 50, outHeight: 20},
  143. {width: 20, height: 50, outWidth: 20, outHeight: 50},
  144. {width: 300, height: 300, outWidth: 300, outHeight: 300},
  145. {width: 300, height: 125, outWidth: 300, outHeight: 125},
  146. {width: 250, height: 300, outWidth: 250, outHeight: 300},
  147. {width: 0, height: 50, outWidth: 100, outHeight: 50},
  148. {width: 50, height: 0, outWidth: 50, outHeight: 25},
  149. {width: 0, height: 200, outWidth: 200, outHeight: 200},
  150. {width: 300, height: 0, outWidth: 300, outHeight: 100},
  151. }
  152. for _, tc := range testCases {
  153. s.Run(fmt.Sprintf("%dx%d", tc.width, tc.height), func() {
  154. po.Width = tc.width
  155. po.Height = tc.height
  156. result, err := ProcessImage(context.Background(), imgdata, po, nil)
  157. s.Require().NoError(err)
  158. s.Require().NotNil(result)
  159. s.checkSize(result, tc.outWidth, tc.outHeight)
  160. })
  161. }
  162. }
  163. func (s *ProcessingTestSuite) TestResizeToFitExtendAR() {
  164. imgdata := s.openFile("test2.jpg")
  165. po := s.pof.NewProcessingOptions()
  166. po.ResizingType = options.ResizeFit
  167. po.ExtendAspectRatio = options.ExtendOptions{
  168. Enabled: true,
  169. Gravity: options.GravityOptions{
  170. Type: options.GravityCenter,
  171. },
  172. }
  173. testCases := []struct {
  174. width int
  175. height int
  176. outWidth int
  177. outHeight int
  178. }{
  179. {width: 50, height: 50, outWidth: 50, outHeight: 50},
  180. {width: 50, height: 20, outWidth: 50, outHeight: 20},
  181. {width: 20, height: 50, outWidth: 20, outHeight: 50},
  182. {width: 300, height: 300, outWidth: 200, outHeight: 200},
  183. {width: 300, height: 125, outWidth: 240, outHeight: 100},
  184. {width: 250, height: 500, outWidth: 200, outHeight: 400},
  185. {width: 0, height: 50, outWidth: 100, outHeight: 50},
  186. {width: 50, height: 0, outWidth: 50, outHeight: 25},
  187. {width: 0, height: 200, outWidth: 200, outHeight: 100},
  188. {width: 300, height: 0, outWidth: 200, outHeight: 100},
  189. }
  190. for _, tc := range testCases {
  191. s.Run(fmt.Sprintf("%dx%d", tc.width, tc.height), func() {
  192. po.Width = tc.width
  193. po.Height = tc.height
  194. result, err := ProcessImage(context.Background(), imgdata, po, nil)
  195. s.Require().NoError(err)
  196. s.Require().NotNil(result)
  197. s.checkSize(result, tc.outWidth, tc.outHeight)
  198. })
  199. }
  200. }
  201. func (s *ProcessingTestSuite) TestResizeToFill() {
  202. imgdata := s.openFile("test2.jpg")
  203. po := s.pof.NewProcessingOptions()
  204. po.ResizingType = options.ResizeFill
  205. testCases := []struct {
  206. width int
  207. height int
  208. outWidth int
  209. outHeight int
  210. }{
  211. {width: 50, height: 50, outWidth: 50, outHeight: 50},
  212. {width: 50, height: 20, outWidth: 50, outHeight: 20},
  213. {width: 20, height: 50, outWidth: 20, outHeight: 50},
  214. {width: 300, height: 300, outWidth: 200, outHeight: 100},
  215. {width: 300, height: 50, outWidth: 200, outHeight: 50},
  216. {width: 100, height: 300, outWidth: 100, outHeight: 100},
  217. {width: 0, height: 50, outWidth: 100, outHeight: 50},
  218. {width: 50, height: 0, outWidth: 50, outHeight: 25},
  219. {width: 0, height: 200, outWidth: 200, outHeight: 100},
  220. {width: 300, height: 0, outWidth: 200, outHeight: 100},
  221. }
  222. for _, tc := range testCases {
  223. s.Run(fmt.Sprintf("%dx%d", tc.width, tc.height), func() {
  224. po.Width = tc.width
  225. po.Height = tc.height
  226. result, err := ProcessImage(context.Background(), imgdata, po, nil)
  227. s.Require().NoError(err)
  228. s.Require().NotNil(result)
  229. s.checkSize(result, tc.outWidth, tc.outHeight)
  230. })
  231. }
  232. }
  233. func (s *ProcessingTestSuite) TestResizeToFillEnlarge() {
  234. imgdata := s.openFile("test2.jpg")
  235. po := s.pof.NewProcessingOptions()
  236. po.ResizingType = options.ResizeFill
  237. po.Enlarge = true
  238. testCases := []struct {
  239. width int
  240. height int
  241. outWidth int
  242. outHeight int
  243. }{
  244. {width: 50, height: 50, outWidth: 50, outHeight: 50},
  245. {width: 50, height: 20, outWidth: 50, outHeight: 20},
  246. {width: 20, height: 50, outWidth: 20, outHeight: 50},
  247. {width: 300, height: 300, outWidth: 300, outHeight: 300},
  248. {width: 300, height: 125, outWidth: 300, outHeight: 125},
  249. {width: 250, height: 300, outWidth: 250, outHeight: 300},
  250. {width: 0, height: 50, outWidth: 100, outHeight: 50},
  251. {width: 50, height: 0, outWidth: 50, outHeight: 25},
  252. {width: 0, height: 200, outWidth: 400, outHeight: 200},
  253. {width: 300, height: 0, outWidth: 300, outHeight: 150},
  254. }
  255. for _, tc := range testCases {
  256. s.Run(fmt.Sprintf("%dx%d", tc.width, tc.height), func() {
  257. po.Width = tc.width
  258. po.Height = tc.height
  259. result, err := ProcessImage(context.Background(), imgdata, po, nil)
  260. s.Require().NoError(err)
  261. s.Require().NotNil(result)
  262. s.checkSize(result, tc.outWidth, tc.outHeight)
  263. })
  264. }
  265. }
  266. func (s *ProcessingTestSuite) TestResizeToFillExtend() {
  267. imgdata := s.openFile("test2.jpg")
  268. po := s.pof.NewProcessingOptions()
  269. po.ResizingType = options.ResizeFill
  270. po.Extend = options.ExtendOptions{
  271. Enabled: true,
  272. Gravity: options.GravityOptions{
  273. Type: options.GravityCenter,
  274. },
  275. }
  276. testCases := []struct {
  277. width int
  278. height int
  279. outWidth int
  280. outHeight int
  281. }{
  282. {width: 50, height: 50, outWidth: 50, outHeight: 50},
  283. {width: 50, height: 20, outWidth: 50, outHeight: 20},
  284. {width: 20, height: 50, outWidth: 20, outHeight: 50},
  285. {width: 300, height: 300, outWidth: 300, outHeight: 300},
  286. {width: 300, height: 125, outWidth: 300, outHeight: 125},
  287. {width: 250, height: 300, outWidth: 250, outHeight: 300},
  288. {width: 300, height: 50, outWidth: 300, outHeight: 50},
  289. {width: 100, height: 300, outWidth: 100, outHeight: 300},
  290. {width: 0, height: 50, outWidth: 100, outHeight: 50},
  291. {width: 50, height: 0, outWidth: 50, outHeight: 25},
  292. {width: 0, height: 200, outWidth: 200, outHeight: 200},
  293. {width: 300, height: 0, outWidth: 300, outHeight: 100},
  294. }
  295. for _, tc := range testCases {
  296. s.Run(fmt.Sprintf("%dx%d", tc.width, tc.height), func() {
  297. po.Width = tc.width
  298. po.Height = tc.height
  299. result, err := ProcessImage(context.Background(), imgdata, po, nil)
  300. s.Require().NoError(err)
  301. s.Require().NotNil(result)
  302. s.checkSize(result, tc.outWidth, tc.outHeight)
  303. })
  304. }
  305. }
  306. func (s *ProcessingTestSuite) TestResizeToFillExtendAR() {
  307. imgdata := s.openFile("test2.jpg")
  308. po := s.pof.NewProcessingOptions()
  309. po.ResizingType = options.ResizeFill
  310. po.ExtendAspectRatio = options.ExtendOptions{
  311. Enabled: true,
  312. Gravity: options.GravityOptions{
  313. Type: options.GravityCenter,
  314. },
  315. }
  316. testCases := []struct {
  317. width int
  318. height int
  319. outWidth int
  320. outHeight int
  321. }{
  322. {width: 50, height: 50, outWidth: 50, outHeight: 50},
  323. {width: 50, height: 20, outWidth: 50, outHeight: 20},
  324. {width: 20, height: 50, outWidth: 20, outHeight: 50},
  325. {width: 300, height: 300, outWidth: 200, outHeight: 200},
  326. {width: 300, height: 125, outWidth: 240, outHeight: 100},
  327. {width: 250, height: 500, outWidth: 200, outHeight: 400},
  328. {width: 300, height: 50, outWidth: 300, outHeight: 50},
  329. {width: 100, height: 300, outWidth: 100, outHeight: 300},
  330. {width: 0, height: 50, outWidth: 100, outHeight: 50},
  331. {width: 50, height: 0, outWidth: 50, outHeight: 25},
  332. {width: 0, height: 200, outWidth: 200, outHeight: 100},
  333. {width: 300, height: 0, outWidth: 200, outHeight: 100},
  334. }
  335. for _, tc := range testCases {
  336. s.Run(fmt.Sprintf("%dx%d", tc.width, tc.height), func() {
  337. po.Width = tc.width
  338. po.Height = tc.height
  339. result, err := ProcessImage(context.Background(), imgdata, po, nil)
  340. s.Require().NoError(err)
  341. s.Require().NotNil(result)
  342. s.checkSize(result, tc.outWidth, tc.outHeight)
  343. })
  344. }
  345. }
  346. func (s *ProcessingTestSuite) TestResizeToFillDown() {
  347. imgdata := s.openFile("test2.jpg")
  348. po := s.pof.NewProcessingOptions()
  349. po.ResizingType = options.ResizeFillDown
  350. testCases := []struct {
  351. width int
  352. height int
  353. outWidth int
  354. outHeight int
  355. }{
  356. {width: 50, height: 50, outWidth: 50, outHeight: 50},
  357. {width: 50, height: 20, outWidth: 50, outHeight: 20},
  358. {width: 20, height: 50, outWidth: 20, outHeight: 50},
  359. {width: 300, height: 300, outWidth: 100, outHeight: 100},
  360. {width: 300, height: 125, outWidth: 200, outHeight: 83},
  361. {width: 250, height: 300, outWidth: 83, outHeight: 100},
  362. {width: 0, height: 50, outWidth: 100, outHeight: 50},
  363. {width: 50, height: 0, outWidth: 50, outHeight: 25},
  364. {width: 0, height: 200, outWidth: 200, outHeight: 100},
  365. {width: 300, height: 0, outWidth: 200, outHeight: 100},
  366. }
  367. for _, tc := range testCases {
  368. s.Run(fmt.Sprintf("%dx%d", tc.width, tc.height), func() {
  369. po.Width = tc.width
  370. po.Height = tc.height
  371. result, err := ProcessImage(context.Background(), imgdata, po, nil)
  372. s.Require().NoError(err)
  373. s.Require().NotNil(result)
  374. s.checkSize(result, tc.outWidth, tc.outHeight)
  375. })
  376. }
  377. }
  378. func (s *ProcessingTestSuite) TestResizeToFillDownEnlarge() {
  379. imgdata := s.openFile("test2.jpg")
  380. po := s.pof.NewProcessingOptions()
  381. po.ResizingType = options.ResizeFillDown
  382. po.Enlarge = true
  383. testCases := []struct {
  384. width int
  385. height int
  386. outWidth int
  387. outHeight int
  388. }{
  389. {width: 50, height: 50, outWidth: 50, outHeight: 50},
  390. {width: 50, height: 20, outWidth: 50, outHeight: 20},
  391. {width: 20, height: 50, outWidth: 20, outHeight: 50},
  392. {width: 300, height: 300, outWidth: 300, outHeight: 300},
  393. {width: 300, height: 125, outWidth: 300, outHeight: 125},
  394. {width: 250, height: 300, outWidth: 250, outHeight: 300},
  395. {width: 0, height: 50, outWidth: 100, outHeight: 50},
  396. {width: 50, height: 0, outWidth: 50, outHeight: 25},
  397. {width: 0, height: 200, outWidth: 400, outHeight: 200},
  398. {width: 300, height: 0, outWidth: 300, outHeight: 150},
  399. }
  400. for _, tc := range testCases {
  401. s.Run(fmt.Sprintf("%dx%d", tc.width, tc.height), func() {
  402. po.Width = tc.width
  403. po.Height = tc.height
  404. result, err := ProcessImage(context.Background(), imgdata, po, nil)
  405. s.Require().NoError(err)
  406. s.Require().NotNil(result)
  407. s.checkSize(result, tc.outWidth, tc.outHeight)
  408. })
  409. }
  410. }
  411. func (s *ProcessingTestSuite) TestResizeToFillDownExtend() {
  412. imgdata := s.openFile("test2.jpg")
  413. po := s.pof.NewProcessingOptions()
  414. po.ResizingType = options.ResizeFillDown
  415. po.Extend = options.ExtendOptions{
  416. Enabled: true,
  417. Gravity: options.GravityOptions{
  418. Type: options.GravityCenter,
  419. },
  420. }
  421. testCases := []struct {
  422. width int
  423. height int
  424. outWidth int
  425. outHeight int
  426. }{
  427. {width: 50, height: 50, outWidth: 50, outHeight: 50},
  428. {width: 50, height: 20, outWidth: 50, outHeight: 20},
  429. {width: 20, height: 50, outWidth: 20, outHeight: 50},
  430. {width: 300, height: 300, outWidth: 300, outHeight: 300},
  431. {width: 300, height: 125, outWidth: 300, outHeight: 125},
  432. {width: 250, height: 300, outWidth: 250, outHeight: 300},
  433. {width: 300, height: 50, outWidth: 300, outHeight: 50},
  434. {width: 100, height: 300, outWidth: 100, outHeight: 300},
  435. {width: 0, height: 50, outWidth: 100, outHeight: 50},
  436. {width: 50, height: 0, outWidth: 50, outHeight: 25},
  437. {width: 0, height: 200, outWidth: 200, outHeight: 200},
  438. {width: 300, height: 0, outWidth: 300, outHeight: 100},
  439. }
  440. for _, tc := range testCases {
  441. s.Run(fmt.Sprintf("%dx%d", tc.width, tc.height), func() {
  442. po.Width = tc.width
  443. po.Height = tc.height
  444. result, err := ProcessImage(context.Background(), imgdata, po, nil)
  445. s.Require().NoError(err)
  446. s.Require().NotNil(result)
  447. s.checkSize(result, tc.outWidth, tc.outHeight)
  448. })
  449. }
  450. }
  451. func (s *ProcessingTestSuite) TestResizeToFillDownExtendAR() {
  452. imgdata := s.openFile("test2.jpg")
  453. po := s.pof.NewProcessingOptions()
  454. po.ResizingType = options.ResizeFillDown
  455. po.ExtendAspectRatio = options.ExtendOptions{
  456. Enabled: true,
  457. Gravity: options.GravityOptions{
  458. Type: options.GravityCenter,
  459. },
  460. }
  461. testCases := []struct {
  462. width int
  463. height int
  464. outWidth int
  465. outHeight int
  466. }{
  467. {width: 50, height: 50, outWidth: 50, outHeight: 50},
  468. {width: 50, height: 20, outWidth: 50, outHeight: 20},
  469. {width: 20, height: 50, outWidth: 20, outHeight: 50},
  470. {width: 300, height: 300, outWidth: 100, outHeight: 100},
  471. {width: 300, height: 125, outWidth: 200, outHeight: 83},
  472. {width: 250, height: 300, outWidth: 83, outHeight: 100},
  473. {width: 0, height: 50, outWidth: 100, outHeight: 50},
  474. {width: 50, height: 0, outWidth: 50, outHeight: 25},
  475. {width: 0, height: 200, outWidth: 200, outHeight: 100},
  476. {width: 300, height: 0, outWidth: 200, outHeight: 100},
  477. }
  478. for _, tc := range testCases {
  479. s.Run(fmt.Sprintf("%dx%d", tc.width, tc.height), func() {
  480. po.Width = tc.width
  481. po.Height = tc.height
  482. result, err := ProcessImage(context.Background(), imgdata, po, nil)
  483. s.Require().NoError(err)
  484. s.Require().NotNil(result)
  485. s.checkSize(result, tc.outWidth, tc.outHeight)
  486. })
  487. }
  488. }
  489. func (s *ProcessingTestSuite) TestResultSizeLimit() {
  490. imgdata := s.openFile("test2.jpg")
  491. po := s.pof.NewProcessingOptions()
  492. testCases := []struct {
  493. limit int
  494. width int
  495. height int
  496. resizingType options.ResizeType
  497. enlarge bool
  498. extend bool
  499. extendAR bool
  500. padding options.PaddingOptions
  501. rotate int
  502. outWidth int
  503. outHeight int
  504. }{
  505. {
  506. limit: 1000,
  507. width: 100,
  508. height: 100,
  509. resizingType: options.ResizeFit,
  510. outWidth: 100,
  511. outHeight: 50,
  512. },
  513. {
  514. limit: 50,
  515. width: 100,
  516. height: 100,
  517. resizingType: options.ResizeFit,
  518. outWidth: 50,
  519. outHeight: 25,
  520. },
  521. {
  522. limit: 50,
  523. width: 0,
  524. height: 0,
  525. resizingType: options.ResizeFit,
  526. outWidth: 50,
  527. outHeight: 25,
  528. },
  529. {
  530. limit: 100,
  531. width: 0,
  532. height: 100,
  533. resizingType: options.ResizeFit,
  534. outWidth: 100,
  535. outHeight: 50,
  536. },
  537. {
  538. limit: 50,
  539. width: 150,
  540. height: 0,
  541. resizingType: options.ResizeFit,
  542. outWidth: 50,
  543. outHeight: 25,
  544. },
  545. {
  546. limit: 100,
  547. width: 1000,
  548. height: 1000,
  549. resizingType: options.ResizeFit,
  550. outWidth: 100,
  551. outHeight: 50,
  552. },
  553. {
  554. limit: 100,
  555. width: 1000,
  556. height: 1000,
  557. resizingType: options.ResizeFit,
  558. enlarge: true,
  559. outWidth: 100,
  560. outHeight: 50,
  561. },
  562. {
  563. limit: 100,
  564. width: 1000,
  565. height: 2000,
  566. resizingType: options.ResizeFit,
  567. extend: true,
  568. outWidth: 50,
  569. outHeight: 100,
  570. },
  571. {
  572. limit: 100,
  573. width: 1000,
  574. height: 2000,
  575. resizingType: options.ResizeFit,
  576. extendAR: true,
  577. outWidth: 50,
  578. outHeight: 100,
  579. },
  580. {
  581. limit: 100,
  582. width: 100,
  583. height: 150,
  584. resizingType: options.ResizeFit,
  585. rotate: 90,
  586. outWidth: 50,
  587. outHeight: 100,
  588. },
  589. {
  590. limit: 100,
  591. width: 0,
  592. height: 0,
  593. resizingType: options.ResizeFit,
  594. rotate: 90,
  595. outWidth: 50,
  596. outHeight: 100,
  597. },
  598. {
  599. limit: 200,
  600. width: 100,
  601. height: 100,
  602. resizingType: options.ResizeFit,
  603. padding: options.PaddingOptions{
  604. Enabled: true,
  605. Top: 100,
  606. Right: 200,
  607. Bottom: 300,
  608. Left: 400,
  609. },
  610. outWidth: 200,
  611. outHeight: 129,
  612. },
  613. {
  614. limit: 1000,
  615. width: 100,
  616. height: 100,
  617. resizingType: options.ResizeFill,
  618. outWidth: 100,
  619. outHeight: 100,
  620. },
  621. {
  622. limit: 50,
  623. width: 100,
  624. height: 100,
  625. resizingType: options.ResizeFill,
  626. outWidth: 50,
  627. outHeight: 50,
  628. },
  629. {
  630. limit: 50,
  631. width: 1000,
  632. height: 50,
  633. resizingType: options.ResizeFill,
  634. outWidth: 50,
  635. outHeight: 13,
  636. },
  637. {
  638. limit: 50,
  639. width: 100,
  640. height: 1000,
  641. resizingType: options.ResizeFill,
  642. outWidth: 50,
  643. outHeight: 50,
  644. },
  645. {
  646. limit: 50,
  647. width: 0,
  648. height: 0,
  649. resizingType: options.ResizeFill,
  650. outWidth: 50,
  651. outHeight: 25,
  652. },
  653. {
  654. limit: 100,
  655. width: 0,
  656. height: 100,
  657. resizingType: options.ResizeFill,
  658. outWidth: 100,
  659. outHeight: 50,
  660. },
  661. {
  662. limit: 50,
  663. width: 150,
  664. height: 0,
  665. resizingType: options.ResizeFill,
  666. outWidth: 50,
  667. outHeight: 25,
  668. },
  669. {
  670. limit: 100,
  671. width: 1000,
  672. height: 1000,
  673. resizingType: options.ResizeFill,
  674. outWidth: 100,
  675. outHeight: 50,
  676. },
  677. {
  678. limit: 100,
  679. width: 1000,
  680. height: 1000,
  681. resizingType: options.ResizeFill,
  682. enlarge: true,
  683. outWidth: 100,
  684. outHeight: 100,
  685. },
  686. {
  687. limit: 100,
  688. width: 1000,
  689. height: 2000,
  690. resizingType: options.ResizeFill,
  691. extend: true,
  692. outWidth: 50,
  693. outHeight: 100,
  694. },
  695. {
  696. limit: 100,
  697. width: 1000,
  698. height: 2000,
  699. resizingType: options.ResizeFill,
  700. extendAR: true,
  701. outWidth: 50,
  702. outHeight: 100,
  703. },
  704. {
  705. limit: 100,
  706. width: 100,
  707. height: 150,
  708. resizingType: options.ResizeFill,
  709. rotate: 90,
  710. outWidth: 67,
  711. outHeight: 100,
  712. },
  713. {
  714. limit: 100,
  715. width: 0,
  716. height: 0,
  717. resizingType: options.ResizeFill,
  718. rotate: 90,
  719. outWidth: 50,
  720. outHeight: 100,
  721. },
  722. {
  723. limit: 200,
  724. width: 100,
  725. height: 100,
  726. resizingType: options.ResizeFill,
  727. padding: options.PaddingOptions{
  728. Enabled: true,
  729. Top: 100,
  730. Right: 200,
  731. Bottom: 300,
  732. Left: 400,
  733. },
  734. outWidth: 200,
  735. outHeight: 144,
  736. },
  737. {
  738. limit: 1000,
  739. width: 100,
  740. height: 100,
  741. resizingType: options.ResizeFillDown,
  742. outWidth: 100,
  743. outHeight: 100,
  744. },
  745. {
  746. limit: 50,
  747. width: 100,
  748. height: 100,
  749. resizingType: options.ResizeFillDown,
  750. outWidth: 50,
  751. outHeight: 50,
  752. },
  753. {
  754. limit: 50,
  755. width: 1000,
  756. height: 50,
  757. resizingType: options.ResizeFillDown,
  758. outWidth: 50,
  759. outHeight: 3,
  760. },
  761. {
  762. limit: 50,
  763. width: 100,
  764. height: 1000,
  765. resizingType: options.ResizeFillDown,
  766. outWidth: 5,
  767. outHeight: 50,
  768. },
  769. {
  770. limit: 50,
  771. width: 0,
  772. height: 0,
  773. resizingType: options.ResizeFillDown,
  774. outWidth: 50,
  775. outHeight: 25,
  776. },
  777. {
  778. limit: 100,
  779. width: 0,
  780. height: 100,
  781. resizingType: options.ResizeFillDown,
  782. outWidth: 100,
  783. outHeight: 50,
  784. },
  785. {
  786. limit: 50,
  787. width: 150,
  788. height: 0,
  789. resizingType: options.ResizeFillDown,
  790. outWidth: 50,
  791. outHeight: 25,
  792. },
  793. {
  794. limit: 100,
  795. width: 1000,
  796. height: 1000,
  797. resizingType: options.ResizeFillDown,
  798. outWidth: 100,
  799. outHeight: 100,
  800. },
  801. {
  802. limit: 100,
  803. width: 1000,
  804. height: 1000,
  805. resizingType: options.ResizeFillDown,
  806. enlarge: true,
  807. outWidth: 100,
  808. outHeight: 100,
  809. },
  810. {
  811. limit: 100,
  812. width: 1000,
  813. height: 2000,
  814. resizingType: options.ResizeFillDown,
  815. extend: true,
  816. outWidth: 50,
  817. outHeight: 100,
  818. },
  819. {
  820. limit: 100,
  821. width: 1000,
  822. height: 2000,
  823. resizingType: options.ResizeFillDown,
  824. extendAR: true,
  825. outWidth: 50,
  826. outHeight: 100,
  827. },
  828. {
  829. limit: 100,
  830. width: 1000,
  831. height: 1500,
  832. resizingType: options.ResizeFillDown,
  833. rotate: 90,
  834. outWidth: 67,
  835. outHeight: 100,
  836. },
  837. {
  838. limit: 100,
  839. width: 0,
  840. height: 0,
  841. resizingType: options.ResizeFillDown,
  842. rotate: 90,
  843. outWidth: 50,
  844. outHeight: 100,
  845. },
  846. {
  847. limit: 200,
  848. width: 100,
  849. height: 100,
  850. resizingType: options.ResizeFillDown,
  851. padding: options.PaddingOptions{
  852. Enabled: true,
  853. Top: 100,
  854. Right: 200,
  855. Bottom: 300,
  856. Left: 400,
  857. },
  858. outWidth: 200,
  859. outHeight: 144,
  860. },
  861. {
  862. limit: 200,
  863. width: 1000,
  864. height: 1000,
  865. resizingType: options.ResizeFillDown,
  866. padding: options.PaddingOptions{
  867. Enabled: true,
  868. Top: 100,
  869. Right: 200,
  870. Bottom: 300,
  871. Left: 400,
  872. },
  873. outWidth: 200,
  874. outHeight: 144,
  875. },
  876. }
  877. for _, tc := range testCases {
  878. name := fmt.Sprintf("%s_%dx%d_limit_%d", tc.resizingType, tc.width, tc.height, tc.limit)
  879. if tc.enlarge {
  880. name += "_enlarge"
  881. }
  882. if tc.extend {
  883. name += "_extend"
  884. }
  885. if tc.extendAR {
  886. name += "_extendAR"
  887. }
  888. if tc.rotate != 0 {
  889. name += fmt.Sprintf("_rot_%d", tc.rotate)
  890. }
  891. if tc.padding.Enabled {
  892. name += fmt.Sprintf("_padding_%dx%dx%dx%d", tc.padding.Top, tc.padding.Right, tc.padding.Bottom, tc.padding.Left)
  893. }
  894. s.Run(name, func() {
  895. po.SecurityOptions.MaxResultDimension = tc.limit
  896. po.Width = tc.width
  897. po.Height = tc.height
  898. po.ResizingType = tc.resizingType
  899. po.Enlarge = tc.enlarge
  900. po.Extend.Enabled = tc.extend
  901. po.ExtendAspectRatio.Enabled = tc.extendAR
  902. po.Rotate = tc.rotate
  903. po.Padding = tc.padding
  904. result, err := ProcessImage(context.Background(), imgdata, po, nil)
  905. s.Require().NoError(err)
  906. s.Require().NotNil(result)
  907. s.checkSize(result, tc.outWidth, tc.outHeight)
  908. })
  909. }
  910. }
  911. func (s *ProcessingTestSuite) TestImageResolutionTooLarge() {
  912. po := s.pof.NewProcessingOptions()
  913. po.SecurityOptions.MaxSrcResolution = 1
  914. imgdata := s.openFile("test2.jpg")
  915. _, err := ProcessImage(context.Background(), imgdata, po, nil)
  916. s.Require().Error(err)
  917. s.Require().Equal(422, ierrors.Wrap(err, 0).StatusCode())
  918. }
  919. func TestProcessing(t *testing.T) {
  920. suite.Run(t, new(ProcessingTestSuite))
  921. }