Calculating Image Size Ratio for Resizing

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



Leave a reply



Submit