2

I am using ImageMagick for Perl

use Image::Magick;

I have written functional code to perform all necessary tasks like resize, thumbnail, read dimensions, crop, crop to center.

I do have a requirement that all photos are landscape so I toss out any images with a height greater than or equal to the width.

The issue I am struggling with is cropping before resizing. The photos need to be 4:3 aspect ratio. Some photos come in the new 16:9 format or may have been cropped before sent to the server, which causes a skewed on-screen display. Before I resize I would like to crop the image so it's closest 4:3 equivalent. For example, 800/600 is ok but 802/600 would crop center to 800/600.

I will be resizing all photos, regarless of cropped size to a max stored image of 800/600 but that is fairy irrelevant. Since I can read the height and width dimensions ahead of time perhaps there is an algorithm available to calculate the closest match. I really just need help with obtaining the new dimensions to crop to, not ImageMagick unless there is a function within ImageMagick that can do this for me.

However, I have been unsuccessful locating one that does.

brian d foy
  • 129,424
  • 31
  • 207
  • 592
chrisrth
  • 1,182
  • 3
  • 15
  • 36
  • You mean something like: if width > 4.0/3.0*height then newWidth = 4.0/3.0 height else newHeight = 3.0/4.0*width? – vmpstr Feb 24 '12 at 14:10
  • This is something I've been meaning to do with the photos I loaded onto a digital photo frame. One of my fancy cameras takes 16x9 pics, which are great, but don't look nice in the frame. The crop size isn't the only problem: you need to decide where to slice off the extra: equally on both sides, somewhere else, and so on. – brian d foy Feb 24 '12 at 17:20
  • to do that you just find the center, then measure out until you hit the cropping dimensions. $image->Crop('800x600+$x+$y'); where $x=1/2 of your original image width and $y is 1/2 of your original image height. – chrisrth Feb 24 '12 at 21:54

1 Answers1

8

Worked for me:

my $image_width  = 800; # play with this when testing
my $image_height = 600;

my $target_aspect  = 4 / 3; 
my $current_aspect = $image_width / $image_height;

given ($current_aspect <=> $target_aspect) {
  when (1) { $image_width = int($image_height * $target_aspect); }
  when (-1)  { $image_height = int($image_width / $target_aspect); }
}
raina77ow
  • 103,633
  • 15
  • 192
  • 229