我正在尝试使用ImageMagick和PHP在左侧和右侧的图像中修剪可变数量的空白。有谁知道怎么做(也许使用imagemagick以外的东西?)?
这是一个例子。
我有这两张图片:
每个都有一个可变数量的文本,在固定宽度的图像中动态创建。
我需要做的是修剪右侧和左侧的背景,使图像如下所示:
如果ImageMagick无法做到,我愿意使用别的东西,但我需要帮助的确切原因,因为我不是一个程序员。谢谢!
这是我当前的代码修剪图像的所有边:
<?php
/* Create the object and read the image in */
$i = '3';
$im = new Imagick("test".$i.".png");
/* Trim the image. */
$im->trimImage(0);
/* Ouput the image */
//header("Content-Type: image/" . $im->getImageFormat());
//echo $im;
/*** Write the trimmed image to disk ***/
$im->writeImage(dirname(__FILE__) . '/test'.$i.'.png');
/*Display Image*/
echo $img = "<img src=\"test".$i.".png\">";
?>
答案 0 :(得分:15)
我认为你与ImageMagick
的{{1}}运算符 1)走在正确的轨道上,但诀窍是让它告诉你它是什么 没有实际这样做,然后修改它来做你真正想要的......
因此,要为第一张图片计算修剪框-trim
,请执行以下操作:
ImageMagick
这是一个60x29像素的矩形,从左上角偏移21和31。现在,我们希望将这些值转换为convert -fuzz 10% image.jpg -format "%@" info:
60x29+21+31
变量,因此我将IFS(输入字段分隔符)设置为在空格上分割字段,bash
以及x
符号:
+
现在我可以忽略#!/bin/bash
IFS=" x+" read a b c d < <(convert -fuzz 10% image.jpg -format "%@" info:)
echo $a $b $c $d
60 29 21 31
和29
,因为我们只对裁剪宽度感兴趣,并且像这样裁剪:
31
所以,对于你的2张图片,我得到了这些:
完整的程序是这样的:
convert image.jpg -crop "${a}x+${c}+0" out.jpg
备注强>
1)#!/bin/bash
IFS=" x+" read a b c d < <(convert -fuzz 10% image.jpg -format "%@" info:)
convert image.jpg -crop "${a}x+${c}+0" out.jpg
只是-format %@
运算符的简写,这将是完整的
-trim
答案 1 :(得分:5)
基于GD的库WideImage有类似的东西。它被称为autoCrop
,默认情况下它适用于所有四个方面。
但是,您可以添加另一个参数,并根据它仅裁剪上/下或左/右。
记录非常好。 $img
是WideImage_Image
类型。还有interactive online demo of it。
答案 2 :(得分:4)
从我在cropping and borders上的ImageMagick文档中看到的内容,似乎不可能。
您不能为“智能”裁剪指定边缘(在命令行上称为-trim
),并且所有接受几何参数的裁剪方法都需要固定数字才能裁剪。
想到的唯一想法是在单独的调用中获取剃光区域的颜色,运行trimImage
,然后使用-border
添加丢失的区域。
编辑:IM手册提示类似的内容。查看Trimming Just One Side of an Image.我不熟悉IM的PHP扩展,将代码转换为PHP调用,但它应该是中途直截了当。
答案 3 :(得分:1)
使用GD:
function imageautocrop( &$img) {
$emptycol = function ( $img, $x, $min, $max) {
for( $y=$min; $y<$max; $y++) {
$col = imagecolorsforindex( $img, imagecolorat( $img, $x, $y));
if( $col['alpha'] != 127) return false;
}
return true;
}
$trim = Array('top'=>0,'bot'=>0,'lft'=>0,'rgt'=>0);
$size = Array('x'=>imagesx($img)-1,'y'=>imagesy($img)-1);
// code for affecting rows removed due to question asked
while( $emptycol( $img, $trim['lft'], $trim['top'], $size['y']-$trim['bot'])) $trim['lft']++;
while( $emptycol( $img, $size['x']-$trim['rgt'], $trim['top'], $size['y']-$trim['bot'])) $trim['rgt']++;
$newimg = imagecreate( $size['x']-$trim['lft']-$trim['rgt']+1, $size['y']-$trim['top']-$trim['bot']+1);
imagecopy( $newimg, $img, 0, 0, $trim['lft'], $trim['top'], imagesx($newimg)+1, imagesy($newimg)+1);
imagedestroy($img);
$img = $newimg;
}
这是我的旧代码,所以可能不是最优的,但它确实起作用。
答案 4 :(得分:0)
请改用cropImage()。这样的事情,也许是:
$img_x_size = 800; // Set these to relevant values
$img_y_size = 600;
$crop_pixels = 20; // How many pixels to crop
// cropImage(XsizeOfCrop, YsizeOfCrop, CropXPos, CropYPos)
$im->cropImage($img_x_size - $crop_pixels, $img_y_size, 0, $crop_pixels / 2);
答案 5 :(得分:0)
这是一个两步过程,因为文本是动态生成的
诀窍是找出宽度(图像)。请参阅:How can I auto adjust the width of a GD-generated image to fit the text?
然后,如果您知道宽度(图像),则可以在叠加
之前先裁剪宽度(背景)