Shortcut for resize() with upsize/aspect ratio constraints
Maybe it's just me, but most of the times I want to resize an image to max width/height, but keep the aspect ratio (because that ruins the photo) and no upsize (because that only leads to ugly pixelated pics), and don't want to crop because that cuts of important parts. So I end up adding the constraints all the time:
$image->resize(800, 800 , function ($constraint) {
$constraint->aspectRatio();
$constraint->upsize();
}
Is it possible to make this a dedicated function, or can I define my own Macro's or something?
You can use widen(), heighten() or fit().
http://image.intervention.io/api/widen http://image.intervention.io/api/heighten http://image.intervention.io/api/fit
Yes but fit() crops the image right? So I'd just use $image->widen(800)->heighten(800). But than I still need to add the upsize constraints to both calls?
Yes, fit() crops, but in an intelligent way.
To prevent upsizing you have to do this:
$callback = function ($constraint) { $constraint->upsize(); };
$image->widen(800, $callback)->heighten(800, $callback)
It's also possible to combine calls into filters and just run code like this:
$image->filter(new CustomResize(800, 800));
I'm thinking at the moment about a global configuration, where you not only can set driver, but also global defaults like output format, encoding quality etc. Maybe I can add default settings for constraints.
Would be cool. I can't really imagine a situation (for me) where I'd want images to be upsized or not keeping aspect ration.
I thought about this and think, that my "global default config" idea might bring more confusion than logic.
But I agree, the resize() method is quite verbose and it might be a good idea to have a shortcut for resizing with keeping aspect-ratio and prevent upsizing.
Any ideas on naming this shortcut?
Scale or downscale perhaps? Or perhaps scale does upsize and downscale doesn't. But I'm not sure, not really into photo editing terms.. Op 14 sep. 2014 13:59 schreef "Oliver Vogel" [email protected]:
I thought about this and think, that my "global default config" idea might bring more confusion than logic.
But I agree, the resize() method is quite verbose and it might be a good idea to have a shortcut for resizing with keeping aspect-ratio and prevent upsizing.
Any ideas on naming this shortcut?
— Reply to this email directly or view it on GitHub https://github.com/Intervention/image/issues/227#issuecomment-55523369.
I thought about scale too.
Hi,
This should really be called contain imho to keep with css bg-size terms
http://www.w3schools.com/cssref/css3_pr_background-size.asp
I think $image->widen(800, $callback)->heighten(800, $callback) is not optimal, for one, it may resize the image twice needlessly losing precious details and resources.
for now I did something like this:
public static function contain(&$image, $maxWidth, $maxHeight)
{
$currentWidth = $image->width(); $currentHeight = $image->height();
if (currentWidth > maxdWidth || currentHeight > maxHeight)
{
$ratioX = currentWidth / maxdWidth;
$ratioY = currentHeight / maxHeight;
if (ratioX > ratioY) $image->widen($maxWidth);
else $image->heighten($maxHeight);
}
}
@arthur-white isn't that similar to my example?
$image->resize($maxWidth, $maxHeight, function ($constraint) {
$constraint->aspectRatio();
$constraint->upsize();
}
I'm also fine with contain, or scale or whatever you like ;)
I don't really like contain. And in terms of CSS it is possible to get an upsized image, which is not wanted here.
I think a good way would be, to make the upsize prevention set by default. Because in almost every situation upsizing is not wanted. But this step would break the whole constraint naming concept and would be not backward compatible. So I guess this is not an option.
Okay, so scale it is? Do you need a PR or do you have in mind what the best way to do this is?
Sorry, I can't decide for a good and distinct name.
Okay new suggestion, use a string to define a shortcut for some callbacks. So if the third param is a string, use a predefined callback. Something similar to these fit options: http://glide.thephpleague.com/api/size/
$image->fit(800, 800, 'contain');
$image->fit(800, 800, 'stretch');
$image->fit(800, 800, 'crop');
$image->fit(800, 800, 'max');
Following the naming of Glide (which is based on intervention/image), the stretch is what currently is resize. contain is the resizing + aspect ratio and max is what I wanted to do in the OP, resize + keep ratio + don't upscale. crop is just the regular fit().
So following that, I could probably see the usage of 2 new functions:
$image->max($width, $height);
$image->contain($width, $height);
Imho both max and contain are more common then the stretch/resize, because that gives you distorted images..
And about the current fit, it probably doesn't make a lot of sense to add constraints because you usually want an exact fit (hence the name), and the 4th param is more useful sometimes. But I guess the interface can't be changed in the 2.x version.
/cc @reinink because he implemented all this :)
Thanks for including me @barryvdh. My naming for the fit feature may not be perfect, but as is always the case with naming, it's hard. I based it on what I've seen done in other libraries, with some tweaks of my own.
I liked contain instead of resize because all these functions are doing a resize, so why should this one be called that? In my mind I saw the image being contained to the target dimensions, but with nothing else happening (distorting or cropping). I've also seen this called clip, but for me that didn't immediately conjure up a visual of what was happening.
As for stretch, that was also something I came up with. Stretch gives the idea that the image is being distorted. I even considered distort as an option, which I don't think would have been terrible. I went with stretch because it had more of a sizing connotation to it. I've also seen scale used for this.
The max and crop settings I've seen used elsewhere, and both made sense to me right away.
While I'm here, I'd like to thank you @olivervogel. This library is really awesome, and works in a very straight forward and expected way. It really took all of the hard work out of creating Glide. Thanks! :clap:
Thanks for your suggestions guys. I like the thought of having distinct and easy methods for the three tasks:
- resize
- resize + aspect-ratio
- resize + aspect-ratio + no-upsize
I'm currently working on the next release of Intervention Image. This next version will introduce some minor but backward-incompatible API changes. This may be a chance to rename resize() and add new methods.
Currently these renamings are my favorites.
-
resize->stretch -
resize + aspect-ratio->resize -
resize + aspect-ratio + no-upscale-> maybemaxbut I'm not 100% happy
Could also be something like shrink to imply it only shrinks, not enlarges.
This is an alternative naming: https://github.com/Gregwar/Image#basic-handling
Which makes not-upsizing the default resize and has scaleResize to allow upsizing, forceResize instead of stretch (and cropResize instead of fit)
I'm just happy as the max equivalent becomes available under 1 easy call, I'll live with whatever name is chosen :)
@barryvdh I totally agree with the point you make in the first post. Would love to not have to do the closure for upsize and ratio.
@barryvdh your first solution doesnt work for me.. it takes the first param (width) only as a constraint. Is there any method to fit width and height, keeping the ratio, without cropping?
I'm just new to this library, and is looking for exactly what @barryvdh is asking for. Is there any update to this issue since it was created, though its still open?
I can see there is also the resizeCanvas - it kinda sounds like what I want to do, but having a hard time figurering it out from the documentation.
Thanks for otherwise what seems to be an awesome library!
Any updates on this? Still not 100% happy about max()?
Does this need to be on the nextVersion? Adding an alias to an existing function should break BC, just a minor version bump.
Any news on this issue? A short alias would be really nice for this.
contain should be something like this:
function($x, $y, $bgfillcolor) {
return $image->resize($x, $y, function($constraint) {
$constraint->aspectRatio();
$constraint->upsize();
})->resizeCanvas($x, $y, 'center', false, $bgfillcolor);
}
Thanks for all dalaos!
Seems this was discussed for 2 years and then the discussion stopped. When will the scale option be added?
@olivervogel what about the word fill?
@olivervogel or pad?
Is there an update on this? Whats the preferred way now to scale while keeping respect aspect ratio?
I totally agree with @barryvdh. I havent run into a scenario yet where I would like to upscale without aspect ratio. I'm using this everywhere.
$image->resize($maxWidth, $maxHeight, function ($constraint) {
$constraint->aspectRatio();
$constraint->upsize();
}
And for the naming, maybe you can find some inspiration here: https://developer.mozilla.org/en-US/docs/Web/CSS/object-fit