If a user uploads an image 5000 pixels wide, and I want the minimum width of a cropped image to be 2000 pixels, the only built-in way I know of to do this with default options is to use minContainerWidth set to 2000 pixels, which requires that the cropper tool be 2000+ pixels wide in order for it to fit.
Another way to enforce a minimum image size was brought up in #339 - this involves getting the width from getCropBoxData and reverting the crop if it fell below the minimum pixel width. However, this ignores the zoom ratio.
So my solution to do this was to get the width from getCropBoxData and divide it by the zoom ratio to get the calculated real cropped image size.
(edited for clarification and better Fiddle) Here is the JSFiddle I put together that almost works for my purposes. Without this extra logic, the webpage would need to be at least 3000 pixels wide plus margins and whatever else if you wanted to ensure a real, non-upscaled image dimensions after cropping.
The use case for this extends beyond simply having huge images - it would allow something like cropping an image that is 1920px wide with a required cropped width of 700 pixels while using a browser that is taking up half a monitor without worrying about horizontal scrolling.
Editing large images while enforcing large minimum dimensions at a minimum resolution seems like a fairly reasonable thing to want to do with this library. I was disappointed when @fengyuanchen said in #339 that he didn't feel this was needed. It took me (admittedly no JS pro) many hours to figure this out and create that JSFiddle.
Is there some other way to do this that I haven't thought of? If not, It would be really nice if there could be a minImageWidth option that handled all of this for future developers. @fengyuanchen, are you open to the idea of accepting a pull request adding this, having seen a reasonable use case for it demonstrating the need?
@fengyuanchen cleared up a misconception I had about wanting a zoomend event, so I removed those references.
Use $().cropper('getCroppedCanvas', {width: 3000}), you can always get an image with 3000 pixels width no matter what the real width of the original image width!!!
@fengyuanchen the point is to prevent upscaling of an image, I don't think your solution would prevent that.
Still use the zoom event is enough as #574:
var minWidth = 3000;
$().on('zoom.cropper', function (e) {
// This data is based on actual image size
var data = $(this).cropper('getData');
// Zoom out
if (e.ratio < e.oldRatio) {
// Prevent zoom out again
if (data.width < minWidth) {
e.preventDefault();
}
}
});
@fengyuanchen I updated JSFiddle to use what you posted: http://jsfiddle.net/9r6czo65/137/
Ignoring zooming, there is still the issue of enforcing a minimum size when cropping. As you can tell with the Fiddle, it refuses to ever to be less than the maximum width and height. This is because the cropper is only actually a few hundred pixels wide and it's trying to be thousands of pixels wide. Hence the webpage would have to be thousands of pixels wide to accommodate this.
Maybe I don't really understand the prevent upscaling of an image. What is the mean?
Let's say we start with an image that is 100px wide. The user cropped it down to these 50 pixels:

You said I can use $().cropper('getCroppedCanvas', {width: 500}) and always get an image that's 500 pixels. If you do that with an image that's starting off as 100px, this is what it looks like:

It simply takes the 100px image, crops the 50px part that the user specified (the first image above), and blows it up to 500px.
This doesn't solve the problem of requiring the user to crop an image that is truly 500px (at a zoomRatio of 1).
So why don't you filter the original image first as you know it is not like SVG?
For example, if the images come from user upload, then when a user chosen a small image (width < 500px), then alert the user that you app requires an image which width great than 500 pixels.
I was just posting that to explain what I meant by upscaling. Even requiring a 500px image, the user can crop it down to 50px. The only way to prevent this is to use minContainerWidth which requires the webpage be at least that wide, which means it isn't feasible when requiring large image dimensions. The same sort of function that would check to make sure the true image output is 500px in that example is the same function that would be required for this:
AND
Here's an example: http://jsfiddle.net/9r6czo65/139/
Zoom out in your browser as much as possible to make it somewhat fit (may or may not work depending on your monitor resolution) and make the output panel as big as possible. This is what is needed to crop a 6000px image down to a guaranteed non-upscaled image 2000px wide. The webpage has to be enormous, super zoomed out, or have huge horizontal scroll bars.
...
On the your demo: http://jsfiddle.net/9r6czo65/137/, just remove minCropBoxWidth/Height options, then you will find everything works fine!!!
Also, please return after this line $(this).cropper('zoomTo', 1)
Here's the update as you suggested: http://jsfiddle.net/9r6czo65/141/
The user can still crop the image to only be 100px by 100px or any very small size. If I take that cropped image and use $().cropper('getCroppedCanvas', {width: 2000}) it will be upscaled, just like the kitten. This is what I am trying to avoid. I don't want to allow users to create poor quality images that have been upscaled like the kitten.
Thanks for your patience in helping me out.
After so many explanation, I find that you really don't understand how the Cropper works.
Why not read the documentation carefully first?
In short:
getData outputs absolute position and size pixels based on natural image sizegetCanvasData and getCropBoxData outputs relative position and size pixels based on webpageThanks for your responses. I still do not believe what I want is possible with the default options, but I made the JSFiddle that handles it much more simply and (I think) bug free: http://jsfiddle.net/9r6czo65/152/ (It's been an 16 hour work day with very little sleep for me so please forgive any mistakes!)
Hopefully my fiddle helps anyone else who comes across this looking for a solution to enforce minimum image sizes when dealing with large images while also preventing upscaling.
The way this is being handled in my JSFIddle is different from how Cropper usually handles stuff, so I understand if it is not a feature you feel is appropriate for the Cropper project. Thanks again for all your work on Cropper and enduring my sleep deprived questions!
@brynnb thanks for your fiddle. However I note that with this fiddle, once you zoom out, you are unable to zoom in again. It would be better if it upsized the crop box to match (as long as it's possible...) rather than rejecting the zoom altogether. I will let you know if I have any luck with that, I think your code is very close to what I need. Thanks!
Most helpful comment
Thanks for your responses. I still do not believe what I want is possible with the default options, but I made the JSFiddle that handles it much more simply and (I think) bug free: http://jsfiddle.net/9r6czo65/152/ (It's been an 16 hour work day with very little sleep for me so please forgive any mistakes!)
Hopefully my fiddle helps anyone else who comes across this looking for a solution to enforce minimum image sizes when dealing with large images while also preventing upscaling.
The way this is being handled in my JSFIddle is different from how Cropper usually handles stuff, so I understand if it is not a feature you feel is appropriate for the Cropper project. Thanks again for all your work on Cropper and enduring my sleep deprived questions!