ImageMagick:如何将图像最小化为特定宽高比?

时间:2014-01-21 15:34:42

标签: imagemagick crop aspect-ratio

使用imagemagick,我想以最小的方式裁剪图像,使其符合给定的宽高比。

示例:给出3038 x 2014 px的图像,我想裁剪它的宽高比为3:2。然后生成的图像将是3021 x 2014 px,从原始图像的中心裁剪。

所以寻找类似convert in.jpg -gravity center -crop_to_aspect_ratio 3:2 out.jpg的命令。

5 个答案:

答案 0 :(得分:18)

1。特定目标分辨率

如果你最终的目标是拥有一定的分辨率(例如1920x1080),那么使用-geometry,即使用^,即使用-crop,也可以轻松实现这一目标。convert in.jpg -geometry 1920x1080^ -gravity center -crop 1920x1080+0+0 out.jpg )和for i in *jpg do convert "$i" -geometry 1920x1080^ -gravity center -crop 1920x1080+0+0 out-"$i" done

aw=16 #desired aspect ratio width...
ah=9 #and height
in="in.jpg"
out="out.jpg"

wid=`convert "$in" -format "%[w]" info:`
hei=`convert "$in" -format "%[h]" info:`

tarar=`echo $aw/$ah | bc -l`
imgar=`convert "$in" -format "%[fx:w/h]" info:`

if (( $(bc <<< "$tarar > $imgar") ))
then
  nhei=`echo $wid/$tarar | bc`
  convert "$in" -gravity center -crop ${wid}x${nhei}+0+0 "$out"
elif (( $(bc <<< "$tarar < $imgar") ))
then
  nwid=`echo $hei*$tarar | bc`
  convert "$in" -gravity center -crop ${nwid}x${hei}+0+0 "$out"
else
  cp "$in" "$out"
fi

循环遍历多个jpg文件:

1920x1080

2。仅宽高比裁剪

如果你想避免缩放,你必须计算Imagemagick之外的裁剪边的新长度。这更为复杂:

aw

我在示例中使用16:9,期望它对大多数读者比3:2更有用。更改解决方案1中的ah或解决方案2中的<fileSets> <fileSet filtered="true" packaged="true" encoding="UTF-8"> <directory>src/directory> <includes> <include>**/*.java</include> </includes> </fileSet> / -(UIImage*)removeColorFromImage:(UIImage*)sourceImage grayLevel:(int)grayLevel { int width = sourceImage.size.width * sourceImage.scale; int height = sourceImage.size.height * sourceImage.scale; CGFloat scale = sourceImage.scale; CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); CGContextRef context = CGBitmapContextCreate(NULL, width, height, 8, width * 4, colorSpace, kCGBitmapAlphaInfoMask & kCGImageAlphaPremultipliedFirst); CGColorSpaceRelease(colorSpace); CGContextDrawImage(context, CGRectMake(0, 0, width, height), sourceImage.CGImage); unsigned int *colorData = CGBitmapContextGetData(context); for (int i = 0; i < width * height; i++) { unsigned int color = *colorData; short a = color & 0xFF; short r = (color >> 8) & 0xFF; short g = (color >> 16) & 0xFF; short b = (color >> 24) & 0xFF; if ((r == grayLevel) && (g == grayLevel) && (b == grayLevel)) { a = r = g = b = 0; *colorData = (unsigned int)(r << 8) + ((unsigned int)(g) << 16) + ((unsigned int)(b) << 24) + ((unsigned int)(a)); } colorData++; } CGImageRef output = CGBitmapContextCreateImage(context); UIImage* retImage = [UIImage imageWithCGImage:output scale:scale orientation:UIImageOrientationUp]; CGImageRelease(output); CGContextRelease(context); return retImage; } 变量,以获得所需的宽高比。

答案 1 :(得分:11)

Imagemagick的最新版本(自6.9.9-34起)具有宽高比裁剪。所以你可以这样做:

输入:

enter image description here

convert barn.jpg -gravity center -crop 3:2 +repage barn_crop_3to2.png

enter image description here

输出为400x267 + 0 + 0。但请注意,需要+ repage才能删除400x299 + 0 + 16的虚拟画布,因为PNG输出支持虚拟画布。 JPG输出不需要+ repage,因为它不支持虚拟画布。

答案 2 :(得分:3)

随着ImageMagick 7的出现,您可以使用FX表达式在单个命令中根据宽高比实现最大图像尺寸裁剪。

唯一的诀窍是你需要在同一个命令的四个不同的地方输入所需的方面,所以我觉得最容易为那个位做一个变量。方面可以是十进制数,也可以是fx表达式可以解析的字符串。

aspect="16/9"

magick input.png -gravity center \
    -extent  "%[fx:w/h>=$aspect?h*$aspect:w]x" \
    -extent "x%[fx:w/h<=$aspect?w/$aspect:h]" \
    output.png

一旦方面正确,您可以使用-extent跟进两个-resize操作,以将完成的图像带到输出大小。上面的示例使其保持与输入图像一样大。

答案 3 :(得分:1)

您需要计算出所需尺寸,然后进行裁剪。这是一个函数,给定图像的widthheight加上所需的宽高比aspect_xaspect_y,将输出一个可以与Imagemagick一起使用的裁剪字符串。 / p>

def aspect(width, height, aspect_x, aspect_y)

  old_ratio = width.to_f / height
  new_ratio = aspect_x.to_f / aspect_y

  return if old_ratio == new_ratio

  if new_ratio > old_ratio
    height = (width / new_ratio).to_i # same width, shorter height
  else
    width = (height * new_ratio).to_i # shorter width, same height
  end

  "#{width}x#{height}#" # the hash mark gives centre-gravity

end

我在使用Dragonfly Gem的应用程序中使用类似的东西。

答案 4 :(得分:0)

我需要使用A4(1x1.414)纸张纵横比垂直分割非常长的图像。所以我提出了以下解决方案。假设图像文件名是ch1.jpg:

convert -crop $(identify -format "%w" ch1.jpg)x$(printf "%.0f" $(echo $(identify -format "%w" ch1.jpg) \* 1.414|bc)) +repage ch1.jpg ch1.jpg