processing_test.go 25 KB

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