processing_test.go 26 KB

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