3

I'm currently looking for a way to crop an image, but on an angle. I don't think I can just rotate the image first as the script is supplied with specific x,y coordinates of each corner.

So if you can imaging this, image is uploaded, 1280x720. Along with the image it's supplied with x,x coordinates for the crop zone. However the top left and top right coordinates will not have the same y position.

Heres an examples

Before

Before

After

After

Any ideas ?

chip
  • 599
  • 1
  • 9
  • 20

1 Answers1

4

You'll still need to use trigonometry methods to rotate the image, but you can mimic a crop-at-an-angle by mixing opacity copying and trimming.

First. Create an Image Mask

If all the points are giving to you, and the image size is defined, simply draw the area that needs to be extract

WIDTH=819
HEIGHT=616
TOP_LEFT=669,117
TOP_RIGHT=784,155
BOTTOM_LEFT=544,495
BOTTOM_RIGHT=659,534
convert -size $WIDTHx$HEIGHT xc:black -fill white -stroke white \
        -draw "polyline $TOP_LEFT $TOP_RIGHT $BOTTOM_RIGHT $BOTTOM_LEFT" \
        mask.png

Image mask of area to crop

Masking and Background Removal

This method of masking will turn off the alpha-channel and set the background to transparent. When we compose the two images, the resulting image will only display what's within the area we defined in the mask. (note: you may need to adjust the -background to white, or transparent.)

convert source.jpg mask.png -alpha Off -compose CopyOpacity \
        -composite -background transparent copyOpacity.png

Opacity copied from composite mask

Calculate Degree to Rotate

If you have two points on a square angle, you should be able to follow the atan method. Most language will have an atan2 function. Other trigonometry questions "Rotating a rectangle" & "How to calculate the angle between two points relative to the horizontal axis?"

DELTA_Y=$(($HEIGHT-155-534))
DELTA_X=$((784-659))
DEGREE=`awk "BEGIN { pi=4.0*atan2(1.0,1.0)+90; print atan2($DELTA_Y,$DELTA_X)*180/pi; }"`
convert copyOpacity.png -rotate $DEGREE -trim final.png

enter image description here

Luckily, you can do everything in one step.

#!/bin/bash

WIDTH=819
HEIGHT=616
TOP_LEFT=669,117
TOP_RIGHT=784,155
BOTTOM_LEFT=544,495
BOTTOM_RIGHT=659,534
DELTA_Y=$(($HEIGHT-155-534))
DELTA_X=$((784-659))
DEGREE=`awk "BEGIN { pi=4.0*atan2(1.0,1.0)+90; print atan2($DELTA_Y,$DELTA_X)*180/pi; }"`

convert source.jpg \( -size $WIDTHx$HEIGHT xc:black -fill white -stroke white \
        -draw "polyline $TOP_LEFT $TOP_RIGHT $BOTTOM_RIGHT $BOTTOM_LEFT" \) \
        -alpha Off -compose CopyOpacity -composite \
        -background transparent -rotate $DEGREE -trim \
        final.png
Community
  • 1
  • 1
emcconville
  • 23,800
  • 4
  • 50
  • 66