Calculating image size ratio for resizing
Here's code from my personal grab bag of image resizing code. First, data you need:
list($originalWidth, $originalHeight) = getimagesize($imageFile);
$ratio = $originalWidth / $originalHeight;
Then, this algorithm fits the image into the target size as best it can, keeping the original aspect ratio, not stretching the image larger than the original:
$targetWidth = $targetHeight = min($size, max($originalWidth, $originalHeight));
if ($ratio < 1) {
$targetWidth = $targetHeight * $ratio;
} else {
$targetHeight = $targetWidth / $ratio;
}
$srcWidth = $originalWidth;
$srcHeight = $originalHeight;
$srcX = $srcY = 0;
This crops the image to fill the target size completely, not stretching it:
$targetWidth = $targetHeight = min($originalWidth, $originalHeight, $size);
if ($ratio < 1) {
$srcX = 0;
$srcY = ($originalHeight / 2) - ($originalWidth / 2);
$srcWidth = $srcHeight = $originalWidth;
} else {
$srcY = 0;
$srcX = ($originalWidth / 2) - ($originalHeight / 2);
$srcWidth = $srcHeight = $originalHeight;
}
And this does the actual resizing:
$targetImage = imagecreatetruecolor($targetWidth, $targetHeight);
imagecopyresampled($targetImage, $originalImage, 0, 0, $srcX, $srcY, $targetWidth, $targetHeight, $srcWidth, $srcHeight);
In this case the $size
is just one number for both width and height (square target size). I'm sure you can modify it to use non-square targets. It should also give you an inspiration on what other resizing algorithms you can use.
How to smart resize a displayed image to original aspect ratio
If I'm interpreting your spec correctly, you want a result that is no larger than the one the end-user laid out originally; you want one of the two dimensions to shrink, and the other to stay the same. In other words, the new size should fill the designer space in one direction while shortening the size in the other direction to retain the original aspect ratio.
original_ratio = original_width / original_height
designer_ratio = designer_width / designer_height
if original_ratio > designer_ratio
designer_height = designer_width / original_ratio
else
designer_width = designer_height * original_ratio
Often you'll be working with integer coordinates, but the divisions to produce the ratios above need to be floating point. Here's a rearrangement of the formula to be more integer friendly. Make sure your integers have the range to handle the maximum width*height.
if original_width * designer_height > designer_width * original_height
designer_height = (designer_width * original_height) / original_width
else
designer_width = (designer_height * original_width) / original_height
Algorithm for scaling image based on another image size and also preserve its aspect ratio
If the two images don't have the same aspect ratio then it's mathematically impossible to scale both width and height by 20% and preserve the aspect ratio.
So, chose an axis that you will use to scale by, and scale the other one to the size that preserves the aspect ratio.
e.g, using width:
new_image1_width = 512 * (20 / 100) = 102.4
Then compute the new height to preserve the aspect ratio:
original_aspect_ratio = image2_width / image2_height = 256 / 256 = 1
new_image1_height = 102.4 / original_aspect_ratio = 102.4
Or do it the other way (this time multiplying by the ratio):
new_image1_height = 515 * (20 / 100) = 103
original_aspect_ratio = image2_width / image2_height = 256 / 256 = 1
new_image1_width = 103 * original_aspect_ratio = 103
If you have to handle arbitrary image sizes and arbitrary scale factors, you will need two switch between the two ways depending on what you want the rule to be. E.g. you could always go with the smaller of the two, or use a ratio-adjusted height unless this gives you a height larger than image 1 height, and in that case use the second way, or vice versa.
How to resize images proportionally / keeping the aspect ratio?
Have a look at this piece of code from http://ericjuden.com/2009/07/jquery-image-resize/
$(document).ready(function() {
$('.story-small img').each(function() {
var maxWidth = 100; // Max width for the image
var maxHeight = 100; // Max height for the image
var ratio = 0; // Used for aspect ratio
var width = $(this).width(); // Current image width
var height = $(this).height(); // Current image height
// Check if the current width is larger than the max
if(width > maxWidth){
ratio = maxWidth / width; // get ratio for scaling image
$(this).css("width", maxWidth); // Set new width
$(this).css("height", height * ratio); // Scale height based on ratio
height = height * ratio; // Reset height to match scaled image
width = width * ratio; // Reset width to match scaled image
}
// Check if current height is larger than max
if(height > maxHeight){
ratio = maxHeight / height; // get ratio for scaling image
$(this).css("height", maxHeight); // Set new height
$(this).css("width", width * ratio); // Scale width based on ratio
width = width * ratio; // Reset width to match scaled image
height = height * ratio; // Reset height to match scaled image
}
});
});
How to resize images without keeping the aspect ratio?
From the documenation on Image.thumbnail
:
This method calculates an appropriate thumbnail size to preserve the aspect of the image, [...]
So, why not using Image.resize
for that task?
from PIL import Image
img = Image.open('path/to/some/image.png')
print(img)
# ... size=400x400
img_thumb = img.copy()
img_thumb.thumbnail(size=(300, 200))
print(img_thumb)
# ... size=200x200
img_resize = img.resize((300, 200))
print(img_resize)
# ... size=300x200
Image.resize
will (forcefully) resize any image to the given size.
----------------------------------------
System information
----------------------------------------
Platform: Windows-10-10.0.16299-SP0
Python: 3.9.1
PyCharm: 2021.1.1
Pillow: 8.2.0
----------------------------------------
Related Topics
How to Create Optional Arguments in PHP
Accept Function as Parameter in PHP
Curl Error 18 - Transfer Closed With Outstanding Read Data Remaining
Check Whether or Not a Cidr Subnet Contains an Ip Address
Tell Bots Apart from Human Visitors for Stats
Woocommerce: Add Product to Cart with Price Override
Can't Install Laravel Installer via Composer
How to Get Beanstalkd Queue to Work for PHP
How to Check If There Is a There Is a Wget Instance Running
PHP - MySQL Access Denied Error - Works in Other Programs
Trouble Using Posix_Kill in PHP
PHP Failed to Open Stream: Is a Directory
Linux and Oracle Instant Client
Run Shell Command and Send Output to File
Centos 7/Apache/PHP - Mkdir(): Permission Denied
PHP and Mod_Fcgid: Ap_Pass_Brigade Failed in Handle_Request_Ipc Function