Page 1 of 1

Looking for a smart crop

Posted: 2009-05-26T16:34:15-07:00
by riegel
If I have an image that is 120x60 pixels then this code...

Code: Select all

-gravity center -crop 60x60+0+0
Will basically remove the sides from the image leaving a 60x60 square. Very cool.

The problem I have is I want to generalize this and instead of telling it 60x60 I want to say 1x1 or 4x3 or 16x9 and have it crop the imgae to that aspect ratio.

I have a script that solves this problem but I would like a one liner that I can send to convert to do this.

Is it possible?

Terry Riegel

Re: Looking for a smart crop

Posted: 2009-05-26T17:26:18-07:00
by riegel
just to give some additional iformation. This is how I am doing it with a script currently.

w - The width of the image
h - The height of the image

w and h are derived from an identify operation. What I would like to do is not have the identify operation happen before I do the crop.

Code: Select all

 if (w/h)<ratio then
   # Portrait or square like /#
   w=round(w)  h=round(w/ratio)
 else
   # Long landscape like /#
   h=round(h)  w=round(h*ratio)
 /if 
 cmdopt="-gravity center -crop "+w+"x"+h+"+0+0" 
 

Re: Looking for a smart crop

Posted: 2009-05-26T17:31:26-07:00
by fmw42
I don't think -crop allows fx computations for arguments like -distort or some other functions now do. However, you can make some long complex variables that have fx calculations.

For example:

This works to get the center half image:

infile="logo:"
outfile="logo_crop.jpg"
ww=`convert $infile -format "%[fx:w/2]" info:`
hh=`convert $infile -format "%[fx:h/2]" info:`
convert $infile -gravity center -crop ${ww}x${hh}+0+0 +repage $outfile

And this does, but is really no better:

infile="logo:"
outfile="logo_crop.jpg"
convert $infile -gravity center \
-crop $(convert $infile -format "%[fx:w/2]" info:)x$(convert $infile -format "%[fx:h/2]" info:)+0+0 \
+repage $outfile


But you cannot do the following as it ignores the fx calcs and gives the output same size as input. But it would be a nice enhancement to -crop or better yet to geometry in general.

infile="logo:"
outfile="logo_crop.jpg"
convert $infile -gravity center -crop %[fx:w/2]x%[fx:h/2]+0+0 +repage $outfile

But this works. see http://www.imagemagick.org/Usage/distor ... t_viewport

infile="logo:"
outfile="logo_crop.jpg"
convert $infile -set option:distort:viewport %[fx:w/2]x%[fx:h/2]+%[fx:w/4]+%[fx:w/4] \
-distort SRT 0 +repage $outfile

(Too bad viewport does not seem to be -gravity sensitive, so you have to provide the offsets)

You can fill in with your ratio comparison calculation in place of my simply taking half the image.


Also, depending upon your system, you may have to quote the expressions as either:

convert $infile -set option:distort:viewport '%[fx:w/2]x%[fx:h/2]+%[fx:w/4]+%[fx:w/4]' \
-distort SRT 0 +repage $outfile

or

convert $infile -set option:distort:viewport '%[fx:w/2]'x'%[fx:h/2]'+'%[fx:w/4]'+'%[fx:w/4]' \
-distort SRT 0 +repage $outfile

My system does not seem to need it. But Anthony can give more advice about using fx calcs with viewport

Re: Looking for a smart crop

Posted: 2009-05-31T18:13:39-07:00
by anthony
fmw42 wrote:I don't think -crop allows fx computations for arguments like -distort or some other functions now do. However, you can make some long complex variables that have fx calculations.
convert $infile -set option:distort:viewport '%[fx:w/2]'x'%[fx:h/2]'+'%[fx:w/4]'+'%[fx:w/4]' \
-distort SRT 0 +repage $outfile

My system does not seem to need it. But Anthony can give more advice about using fx calcs with viewport
ASIDE:-
No, -crop does not allow 'percent escapes' at this time.

One of the main problems is that 'geometry' argument type options uses '%' as a flag. If precent escapes were allowed then the arguments could have two interpretations...
For example -crop '100%x50+0+0' may be interpreted as haveing a '%x' escape in it rather than it normal meaning of '100% x 50% +0+0'

One proposed solution to this was that 'percent escapes' be only allowed in set/annotate/label strings and in arguments starting with a equal '=' sign. (That would also mean a change to 'distort' percent handling too)

Back to the problem
Now while Fred is right in that you can use a %[fx:...] expression within a -distortion 'viewport', as an alternative method of doing a crop (add -filter point as a speedup).
http://www.imagemagick.org/Usage/distor ... t_viewport
This option controls what part of the distorted output image space is to be 'viewed'. However each number will become a very very VERY complex expression to allow it to handle what you are wanting.

For example a 'centered square crop'... will require a least one 'w>h' test for each and every number you need to calculate. just remember that distort does not NOT understand gravity!

Code: Select all

   size='%[fx:w>h?h:w]x%[fx:w>h?h:w]'
   offset='+%[fx:w>h?(w-h)/2:0]+%[fx:w>h?0:(h-w)/2]'

   convert $infile   -set option:distort:viewport "$size$offset" \
       -filter point -distort SRT 0 +repage $outfile
A perfect 1:1 aspect crop, regardless of the image being landscape or portrait in orientation.

I am adding this to the 'viewport' examples in IM Examples (see link above)

Doing a 1:2 aspect crop is only a little harder to get the expression right, but you can just replace the viewport string variables with the right expression. But once you have the expression for one non-square aspect ratio, you should have it for ANY aspect ratio.

Anyone like to give it a go, and contribute :D

Re: Looking for a smart crop

Posted: 2009-05-31T18:42:52-07:00
by fmw42
Anthony wrote:ASIDE:-
No, -crop does not allow 'percent escapes' at this time.

One of the main problems is that 'geometry' argument type options uses '%' as a flag. If precent escapes were allowed then the arguments could have two interpretations...
For example -crop '100%x50+0+0' may be interpreted as haveing a '%x' escape in it rather than it normal meaning of '100% x 50% +0+0'

One proposed solution to this was that 'percent escapes' be only allowed in set/annotate/label strings and in arguments starting with a equal '=' sign. (That would also mean a change to 'distort' percent handling too)
How about the use of quotes to help offset the % escapes from the % flag? Would that be possible?

-crop '%[fx:w]'x'%[fx:h]'+10+20

Also why can you not distinguish simply by parsing the brackets and the fx?

Re: Looking for a smart crop

Posted: 2009-05-31T19:26:09-07:00
by anthony
fmw42 wrote:How about the use of quotes to help offset the % escapes from the % flag? Would that be possible?

-crop '%[fx:w]'x'%[fx:h]'+10+20

Also why can you not distinguish simply by parsing the brackets and the fx?
You misunderstand the use of quotes here. The quotes are not for ImageMagick. It is for the shell to stop it handling meta-charcaters such as [ ] ? * > < and so on, in its on special ways. Usally for file name selection, or IO (EG: standard input/ouput) streams.

In fact IM doesn't even see the quotes!!!! Not unless you 'quote or escape' the quotes ;-)

If percent escapes are allowed in geometry-like arguments, then a percent sign will either need to NOT be followed by a letter, OR be doubled.. EG: %% Of course for windows which already requires doubling, then that will become qudrupled!!!! '%%%%'

You can see the problem!

This problem does needs to be resolved as part of IM v7 discussion, when I want to see a re-write of "convert" to allow things like
  • one-pass argment handling to permit operations being given as a data-stream,
  • almost all arguments with escape handling done in a 'consistant' way.
    -format, -comment and -label, (and its equivelent '-set' methods) may need to be an exception, as it argument have to be done when the value is processed (per image) rather that at the time it is set.
  • macros, and macro loops and conditionals

Re: Looking for a smart crop

Posted: 2009-05-31T19:39:07-07:00
by fmw42
OK, Seems like there ought to be an interim way around it, but if it needs to wait until IM 7, then I think it will be very useful.

Re: Looking for a smart crop

Posted: 2009-05-31T20:54:29-07:00
by anthony
fmw42 wrote:OK, Seems like there ought to be an interim way around it, but if it needs to wait until IM 7, then I think it will be very useful.
It can be fixed faster if a solution can be found.

As I mentioned one suggestion is that... all arguments are saved and used AS IS.
BUT if it started with a '@' then it is read from a file (literially). If it started with a '=' it is
immediatally parsed for percent escapes, AT THAT POINT.

Remember -label -comment etc normally get saved the string AS IS without escaping.

It is only when those settings (or strings) are actually applied in operations such as -annotate and la that the string could be expanded.

This could be implemented immediately in the current "convert", though it means each operation would have to get its argument first through a function, rather than directly from the command line.

Re: Looking for a smart crop

Posted: 2009-05-31T21:02:46-07:00
by fmw42
I understand. But I don't want for it to be too much work or make IM less efficient. So it can wait until IM 7.