processing_test.go 27 KB

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