Resize image using 'auto' in width or height not working

Well the error we were having is gone but I now have this
stack: “Error: Expected integer for top but received -120 of type number↵ at Object.invalidParameterError (/opt/node_app/node_modules/sharp/lib/is.js:101:10)↵ at Sharp. (/opt/node_app/node_modules/sharp/lib/resize.js:375:16)↵ at Array.forEach ()↵ at Sharp.extract (/opt/node_app/node_modules/sharp/lib/resize.js:370:38)↵ at App.crop (/opt/node_app/lib/modules/image.js:191:21)↵ at App._exec (/opt/node_app/lib/core/app.js:427:57)↵ at App._exec (/opt/node_app/lib/core/app.js:398:28)↵ at async App.exec (/opt/node_app/lib/core/app.js:367:9)↵ at async App.define (/opt/node_app/lib/core/app.js:357:9)”

This is with an image of 1920w x 1000h, so I would need it to upscale the 1000h to 1080 first, then crop to a final 1920w x 1080h

Then I tried a file of 2000w x 708h, similar error
stack: “Error: Expected integer for top but received -558 of type number↵ at Object.invalidParameterError (/opt/node_app/node_modules/sharp/lib/is.js:101:10)↵ at Sharp. (/opt/node_app/node_modules/sharp/lib/resize.js:375:16)↵ at Array.forEach ()↵ at Sharp.extract (/opt/node_app/node_modules/sharp/lib/resize.js:370:38)↵ at App.crop (/opt/node_app/lib/modules/image.js:191:21)↵ at App._exec (/opt/node_app/lib/core/app.js:427:57)↵ at App._exec (/opt/node_app/lib/core/app.js:398:28)↵ at async App.exec (/opt/node_app/lib/core/app.js:367:9)↵ at async App.define (/opt/node_app/lib/core/app.js:357:9)”

So i tried an image larger in both dimensions 2016w x 1512h and got this

  1. {status: “500”, message: “extract_area: bad extract area↵”,…}
  2. message: “extract_area: bad extract area↵”
  3. stack: “Error: extract_area: bad extract area↵”
  4. status: “500”

EDIT: If i disable the crop step after the resize step, it resizes perfectly, then I have to redeploy to refresh the cache, and can see all the images at the correct sizes.

EDIT 2: If I then disable the resize step and save, redeploy, then crop works too, on redeploy i can see all 3 images now at 1920 x 1080.
Doing one more test as something went strange with image 4, so just testing again.

EDIT 3: Ok image 4 makes sense, it starts off at 2016w x 1512h so once the resize takes the height down to 1080h, the width drops way below the 1920w, and then the crop fails.
Going to have to try add some conditions or something to check if the width is not going to drop too much, its like height is 1080px if min-width doesnt go under 1920px.

Anyway so final result is that, they both work, just not together, I am going to go out on a limb here and say its because of the cache, I can clear cache, or disable it in dev tools, etc. but the only way this shows the new sizes is to redeploy and then refresh, so maybe its unaware of the new image parameters. Lol, I try be clever.

Thanks PSWEB for re-addressing this issue.
I havent looked into this myself yet and now just following your comments and tests :wink:

1 Like

So the resize is fixed now, but the crop is giving problems. If you have only the crop step without the resize, does it work then? Will try some tests here and post an update later.

Resize works if its
Load
Resize
Save

And crop works if its
Load
Crop
Save

But if I try with
Load
Resize
Crop
Save

Then i get this error

{status: "500", message: "Expected integer for top but received -558 of type number",…}
message: "Expected integer for top but received -558 of type number"
stack: "Error: Expected integer for top but received -558 of type number↵    at Object.invalidParameterError (/opt/node_app/node_modules/sharp/lib/is.js:101:10)↵    at Sharp.<anonymous> (/opt/node_app/node_modules/sharp/lib/resize.js:375:16)↵    at Array.forEach (<anonymous>)↵    at Sharp.extract (/opt/node_app/node_modules/sharp/lib/resize.js:370:38)↵    at App.crop (/opt/node_app/lib/modules/image.js:191:21)↵    at App._exec (/opt/node_app/lib/core/app.js:427:57)↵    at App._exec (/opt/node_app/lib/core/app.js:398:28)↵    at async App.exec (/opt/node_app/lib/core/app.js:367:9)↵    at async App.define (/opt/node_app/lib/core/app.js:357:9)"
status: "500"

I am convinced it is something to do with a cache or data store or something like that not telling it the image has new dimensions.

I remove everything from my docker user uploads folder
rm -r /var/lib/docker/volumes/sitefolder__sitename_user_uploads/_data/mymedia

Confirm the entire folder is gone with
ls -lar /var/lib/docker/volumes/sitefolder__sitename_user_uploads/_data/mymedia

Folder no longer exists.

I created 2 server actions and 2 buttons, one only does resize, the other only does crop.
I fresh save everything, deploy, refresh my browser.

Upload an image of 2000w x 708h, the page refreshes and shows the new image and its size.
ls -lar shows a single image of 142395 size.

I go back to my browser click the resize button, the action runs without error, i refresh, hard refresh, rerun the folder list action for new content, and no matter what the size remains as 2000w x 708h in the browser, clicking the second crop button gives an error that the crop height is larger than the image and giving a negative number.
ls -lar shows the size has altered to 251634.

I redeploy without making any alterations, refresh my browser and now it shows the resized image of 3051w x 1080h. I click the crop button, and the error from before is gone, it runs through.
Again refreshing or anything i like does not show the new image preview nor dimensions.
ls -lar shows it is done and now a size of 157676.

I redeploy, without making any changes again, refresh my browser and now the view updates and the size is 1920w x 1080h correctly. The preview image also reflects the long skinny image is now more like a 16x9 aspect ratio.

So after running the resize, then redeploy, then run the crop, then redeploy, then the result is correct. Going to try install the latest as I know there was some cache update as far as I read, so maybe it fixes it. Will let you know.

Good research, I think you are correct that it doesn’t use the correct size after the resize, it still uses the original size for the crop step and that causes calculations to return wrong values. We need to have the new size for the next step. I made some changes that you may also test.

image.zip (2.1 KB)

1 Like

Getting this on just the resize step

{status: "500", message: "image is not defined",…}
message: "image is not defined"
stack: "ReferenceError: image is not defined↵    at App.resize (/opt/node_app/lib/modules/image.js:180:32)↵    at App._exec (/opt/node_app/lib/core/app.js:427:57)↵    at App._exec (/opt/node_app/lib/core/app.js:398:28)↵    at async App.exec (/opt/node_app/lib/core/app.js:367:9)↵    at async App.define (/opt/node_app/lib/core/app.js:357:9)"
status: "500"

Oh yes, did a bit too many copy/paste.

image.zip (2.1 KB)

1 Like

Both together does the same

{status: "500", message: "Expected integer for top but received -558 of type number",…}
message: "Expected integer for top but received -558 of type number"
stack: "Error: Expected integer for top but received -558 of type number↵    at Object.invalidParameterError (/opt/node_app/node_modules/sharp/lib/is.js:101:10)↵    at Sharp.<anonymous> (/opt/node_app/node_modules/sharp/lib/resize.js:375:16)↵    at Array.forEach (<anonymous>)↵    at Sharp.extract (/opt/node_app/node_modules/sharp/lib/resize.js:370:38)↵    at App.crop (/opt/node_app/lib/modules/image.js:192:21)↵    at App._exec (/opt/node_app/lib/core/app.js:427:57)↵    at App._exec (/opt/node_app/lib/core/app.js:398:28)↵    at async App.exec (/opt/node_app/lib/core/app.js:367:9)↵    at async App.define (/opt/node_app/lib/core/app.js:357:9)"
status: "500"

Resize works by itself.

Crop after resize throws same error as above, unless i redeploy first, then crop also works on its own.

Is there any difference in caching or datastorage related to target setting from Development to Production to Staging?

For the image component it doesn’t matter. There goes something not correct with the calculations. It probably will work if you use 0 in crop for x and y. I’m checking the calculations at this moment.

1 Like

Well as you already told me, but I had to try, I am now on the latest 3.7.2, with Node updated from 14.5.3 to 14.5.4 and Docker updated from 20.10.0 to 20.10.2 and the problem is still there, as you said, lol.

Can’t blame a guy for trying, hehe. Next I am going to go put more air in my car tires and try again, just incase.

I think that I have found a workaround for the invalid metadata the steps where getting. Crop will still return an error when the image is smaller then the crop size.

image.zip (2.1 KB)

Ok, made sure I ran it with an image I know works after crop.
Original dimensions 2000w x 708h
Upscale to 1080h - New dimension will be 3051w x 1080h
Crop to 1920w x 1080h should work

With new file I get the same when trying to run both together.

stack: "Error: Expected integer for top but received -558 of type number↵    at Object.invalidParameterError (/opt/node_app/node_modules/sharp/lib/is.js:101:10)↵    at Sharp.<anonymous> (/opt/node_app/node_modules/sharp/lib/resize.js:375:16)↵    at Array.forEach (<anonymous>)↵    at Sharp.extract (/opt/node_app/node_modules/sharp/lib/resize.js:370:38)↵    at App.crop (/opt/node_app/lib/modules/image.js:192:21)↵    at App._exec (/opt/node_app/lib/core/app.js:427:57)↵    at App._exec (/opt/node_app/lib/core/app.js:398:28)↵    at async App.exec (/opt/node_app/lib/core/app.js:367:9)↵    at async App.define (/opt/node_app/lib/core/app.js:357:9)"

This error is correct if the resize never happened and the file was still its original dimensions, but if i look at the docker terminal, the file has definitely resized already.

I PM’d you the page link Patrick, please feel free to test as much as you like there, I am starting to wonder if it may be having a folder list then a repeat with the load image step.

I mean i resize the image, it updates some page data, like the filesize as an example but not the image preview nor the dimensions, both of those come from the load image step inside the repeat.

even in the docker terminal i can go and replace the file name of the image with
mv fileA.jpg fileB.jpg and that change returns on the page with a folderlist load, and because i altered the name, then the dimensions change too, and that is without a redeploy.

I changed the crop action a bit, here the update.

image.zip (2.1 KB)

While we await this fix, I was thinking about the best solution to figure out the problem of cropping the image when the resize is not large enough because of a strange aspect ratio from the source image.

Lets take a few scenarios
ImageA source dimensions are 2000w by 700h
ImageB source dimensions are 2000w by 1000h
ImageC source dimensions are 2000w by 1600h

Those could be very likely scenarios of a client uploading images, so let’s start with our first simple check. Is the file Landscape or is it Portrait. I will write this to make it easy to understand but obviously need to replicate it in the server action, well the concept anyway.

What are the fixed parameters, we know that the final dimensions must be 1920w by 1080h and regardless of source being landscape or portrait we will crop to always achieve a landscape result.

if (source.image.width > source.image.height) {
    //image is landscape
        Resize - width="auto", height="1080", upscale="true"
        Crop - width="1920", height="1080"
    //test the math for the 3 scenario images (target.height/source.height)
        ImageA - 700h upscales to 1080h, width increases from 2000w to 3085w, good for crop
        ImageB - 1000h upscales to 1080h, width increases from 2000w to 2160w, good for crop
        ImageC - 1600h downscales to 1080h, width decreases from 2000w to 1350w, bad for crop
} else {
    //image is portrait, therefore this is false for our 3 scenarios, but the resize/crop parameters would be
        Resize - width="1920", height="auto", upscale="true"
        Crop - width="1920", height="1080"
}

So testing for Landscape vs Portrait is not enough, we need to check inside the landscape and portrait check for a second condition of aspect ratio by first knowing the aspect ratio of the target dimensions, in our case 1920w by 1080h, so target.image.width / target.image.height = 1.77777777778 which i will round down to 1.77 for the nested then condition.

if (source.image.width > source.image.height) {
    //image is landscape
    if (source.image.width / source.image.height <= 1.77 {
        //test the math for the 3 scenario images
            ImageA - 2000w/700h = 2.85714285714 (false) so use else
            ImageB - 2000w/1000h = 2 (false) so use else
            ImageC - 2000w/1600h = 1.25 (true) so run this

        Resize - width="1920", height="auto", upscale="true"
        Crop - width="1920", height="1080"
        //test the true scenario ImageC
            ImageC - 2000w downscales to 1920w, height decreases from 1600h to 1536h, good for crop
    } else {
        Resize - width="auto", height="1080", upscale="true"
        Crop - width="1920", height="1080"
        //test the true scenarios, ImageA & ImageB
            ImageA - 700h upscales to 1080h, width increases from 2000w to 3085w, good for crop
            ImageB - 1000h upscales to 1080h, width increases from 2000w to 2160w, good for crop
    }
} else {
    //image is portrait, therefore this is false for our 3 scenarios, but the resize/crop parameters would be
        Resize - width="1920", height="auto", upscale="true"
        Crop - width="1920", height="1080"
        //Test 3 random scenarios where must be portrait or the above would be handling it
            ImageD is 3798w by 4747h, will become 1920w by 2399h, good for crop
            ImageE is 4016w by 4048h, will become 1920w by 1935h, good for crop
            ImageF is 1668w by 2774h, will become 1920w by 3193h, good for crop
}

So this looks like a workable solution to always make landscape images on my site regardless of source orientation nor size, it should always work in my mind.
Anyone got any suggestions, improvements, optimisations, arguments, please let me know as maybe I have missed something.

The core problem about the resize should be fixed with the latest file I send. Also the crop after a resize should work correctly. So I will set the but as fixed for the next update.

About your last reply, to get the correct parameters for the resize and crop can be difficult. Perhaps an extra option should be added to the resize and/or crop to handle these different cases.

1 Like

A post was split to a new topic: Make duplicate handling smarter

The resize bug is fixed in Wappler 3.7.3.

1 Like