The stupid question is the question not asked PerlMonks

Rotated Cropping in ImageMagick?

 on Nov 09, 2008 at 23:24 UTC Need Help??

renegadex has asked for the wisdom of the Perl Monks concerning the following question:

Hi! I wanted to crop a certain area in a picture using ImageMagick, but the area I wanted to crop is rotated. So what I did is that I first rotate the whole image, then, I cropped the image. I do get what I wanted, but if I have a big image, and I only need to crop a very small portion of it, I still have to rotate the whole image.. This takes a lot of time. I have tried to define a boundary, but I am having trouble determining the boundary since the area to be cropped is rotated and the boundary should always be a rectangle. Is there another way of doing it?

Replies are listed 'Best First'.
Re: Rotated Cropping in ImageMagick?
by kennethk (Abbot) on Nov 10, 2008 at 03:17 UTC
Assuming you are feeling too lazy to code the right trig, the easiest shortcut would be to crop a square centered on your final image with sides equal to the diagonal of your final image. Pythagoras tells us that's the square root of the sum of the squares of your final dimensions. Maybe +10% just in case.
Re: Rotated Cropping in ImageMagick?
by RatKing (Acolyte) on Nov 10, 2008 at 10:15 UTC
Ok, what I understand is that you have a large image say 4000x7500. You want to crop to a 300x200 selection but the croped area needs to be rotated.

What I would do is crop first and then rotate... or am I thinking to simple today?

I think the OP was having trouble cropping the rotated image because it was...erm...rotated.

I'm so adjective, I verb nouns!

chomp; # nom nom nom

Here's what I am planning to use.. This is to get the coordinates of the corners of the cropping box..
```#!/usr/bin/perl -w
use strict;
use Math::Complex;

# box1 is the image
my @box1 = (-150,-150,150,-150,150,150,-150,150);

#box 2 is the cropping box
my @box2 = (-300,-75,0,-75,0,75,-300,75);

my @box2r = save_rotate_points(undef,45,@box2);
print "Rotate BOX 2\n";
foreach my \$x (@box2r) {
print \$x , "\n";
}

my (\$x1,\$y1,\$x2,\$y2) = get_rotation_box(undef,@box2r);
my @points = (\$x1,\$y1,\$x2,\$y1,\$x2,\$y2,\$x1,\$y2);
print "Bounding Box:\n";
foreach my \$x (@points) {
print \$x , "\n";
}

sub save_rotate_points {
my (\$widget,\$angle,@points) = @_;
my \$count = @points;
my (@x, @y);
\$angle = \$angle * pi() / 180;
for(my \$i = 0; \$i < \$count ; \$i+=2){
my \$xp = (\$points[\$i] * cos(\$angle)) - (\$points[\$i+1] * sin(\$a
+ngle));
my \$yp = (\$points[\$i] * sin(\$angle)) + (\$points[\$i+1] * cos(\$a
+ngle));
push @x, \$xp;
push @y, \$yp;
}
@points = (\$x[0],\$y[0],\$x[1],\$y[1],\$x[2],\$y[2],\$x[3],\$y[3]);
return @points;
}

sub get_center_rectangle {
my (\$widget,@points) = @_;
my \$deltax = (\$points[0]+\$points[2]+\$points[4]+\$points[6])/4;
my \$deltay = (\$points[1]+\$points[3]+\$points[5]+\$points[7])/4;
return \$deltax,\$deltay;
}

sub get_rotation_box {
my (\$widget,@points) = @_;
# get smallest value
my \$i = 0;
my (\$smallx,\$smally,\$bigx,\$bigy) = (0,0,0,0);
foreach my \$x (@points) {
if(\$i == 0){
if(\$x <= \$smallx){
\$smallx = \$x;
}
if(\$x >= \$bigx){
\$bigx = \$x;
}
}else{
if(\$x <= \$smally){
\$smally = \$x;
}
if(\$x >= \$bigy){
\$bigy = \$x;
}
\$i = -1;
}
\$i++;
}
return \$smallx,\$smally,\$bigx,\$bigy;
}

sub move_points {
my (\$widget,\$mx,\$my,@points) = @_;
my \$i = 0;
my @new_points;
print \$mx," ",\$my,"\n";
foreach my \$x (@points) {
if(\$i == 0){
print \$x , "+" , \$mx , "\n";
\$x+=\$mx;
}else{
\$x+=\$my;
\$i = -1;
}
push @new_points, \$x;
\$i++;
}
return @new_points;
}

Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://722531]
Approved by ww
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others chanting in the Monastery: (5)
As of 2022-05-22 11:08 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?
Do you prefer to work remotely?

Results (80 votes). Check out past polls.

Notices?