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

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

This topic was automatically closed after 3 days. New replies are no longer allowed.