如何在 PHP 中使用 Imagemagick 修剪图像的左侧和右侧?

发布于 2024-12-11 09:48:39 字数 960 浏览 0 评论 0原文

我正在尝试使用 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\">";
?>

I'm trying to trim a variable amount of whitespace in an image only the left and right side using ImageMagick and PHP. Does anyone know how to do this (perhaps using something other than imagemagick?)?

Here's an example.

I have these two images:
Test

Test Again
Each has a variable amount of text that is dynamically created in a fixed width image.
What I need to do is trim the background off the right and left side so the images come out like this:
TestResult
Test Again Result

If ImageMagick can't do it, I am willing to use something else, but I will need help on how exactly because I am not much of a programmer. Thanks!

Here's my current code that trims all sides of an image:

<?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\">";
?>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

滥情稳全场 2024-12-18 09:48:39

我认为您使用 ImageMagick-trim 运算符 1) 走在正确的轨道上,但诀窍是让它告诉您什么它不需要实际上这样做,然后修改它来做你真正想要的......

所以,要获得修剪框ImageMagick 计算你的第一张图像,你这样做

convert -fuzz 10% image.jpg -format "%@" info:
60x29+21+31

:是一个 60x29 像素的矩形,从左上角横向偏移 21,向下偏移 31。现在,我们希望将这些值放入 bash 变量中,因此我设置了 IFS(输入字段分隔符)以在空格、x 以及 +< 上分割字段。 /code> 标志:

#!/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

现在我可以忽略 2931 因为我们只对裁剪宽度感兴趣,并像这样裁剪:

convert image.jpg -crop "${a}x+${c}+0" out.jpg

所以,对于你的 2 个图像,我得到这些:

在此处输入图像描述
在此处输入图像描述

完整过程如下:

#!/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

注释

1) - format %@ 只是 -trim 运算符的简写,完整的就是这样的

convert image.jpg -trim info:
image.jpg JPEG 72x40 200x100+16+24 8-bit sRGB 0.000u 0:00.000

I think you are on the right track with ImageMagick's -trim operator 1), but the trick would be to get it tell you what it would do without actually doing it, and then modify that to do what you really want...

So, to get the trim-box ImageMagick calculates for your first image, you do this:

convert -fuzz 10% image.jpg -format "%@" info:
60x29+21+31

That is a 60x29 pixel rectangle, offset 21 across and 31 down from the top left corner. Now, we want to get these values into bash variables, so I set the IFS (Input Field Separator) to split fields on spaces, x and also + signs:

#!/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

Now I can ignore the 29 and the 31 because we are only interested in cropping the width, and crop like this:

convert image.jpg -crop "${a}x+${c}+0" out.jpg

So, for your 2 images, I get these:

enter image description here
enter image description here

and the full procedure is this:

#!/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

Notes

1) The -format %@ is just a shorthand for the -trim operator, which would be this in full

convert image.jpg -trim info:
image.jpg JPEG 72x40 200x100+16+24 8-bit sRGB 0.000u 0:00.000
浅沫记忆 2024-12-18 09:48:39

从我在 ImageMagick 文档中看到的裁剪和边框来看,它并没有似乎有可能。

您无法指定“智能”裁剪的边缘(在命令行上称为-trim),并且所有接受几何参数的裁剪方法都需要固定的裁剪数。

我想到的唯一想法是在单独的调用中获取剃须区域的颜色,运行 trimImage,然后使用 -border 添加丢失的区域。

编辑: IM 手册提出了类似的建议。查看仅修剪图像的一侧。我不熟悉 IM 的 PHP扩展将代码转换为 PHP 调用,但它应该是简单的。

From what I can see in the ImageMagick docs on cropping and borders, it doesn't seem to be possible.

you can't specify an edge for "intelligent" cropping (known as-trim on the command line), and all the cropping methods that accept a geometry argument need a fixed number for cropping.

The only idea that comes to mind is to get the colour of the shaved area in a separate call, run trimImage, and add the lost areas back using -border.

Edit: The IM manual is suggesting something similar. Check out Trimming Just One Side of an Image. I'm not familiar with IM's PHP extension to translate the code into PHP calls but it should be half-way straightforward.

尐籹人 2024-12-18 09:48:39

基于 GD 的库 WideImage 有类似的东西。它称为autoCrop,默认情况下它适用于所有四个侧面。

但是,您可以添加另一个参数,并基于它仅裁剪顶部/底部或左侧/右侧。

autoCrop 代码

有很好的文档记录。 $imgWideImage_Image 类型。还有一个 交互式在线演示

相关问题:删除视频缩略图上的黑条

The GD based library WideImage has something similar. It's called autoCrop, by default it works on all four sides.

However, you could just add another parameter and based on it only crop top/bottom or left/right.

autoCrop code

It's pretty well documented. $img is a WideImage_Image type. There is also an interactive online demo of it.

Related question: Removing black bars off video thumbnail.

也只是曾经 2024-12-18 09:48:39

使用 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;
}

这是我的非常旧的代码,所以可能不是最佳的,但它可以完成工作。

Using 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;
}

It's very old code of mine, so probably not optimal, but it does the job.

厌味 2024-12-18 09:48:39

这是一个两步过程,因为文本是动态生成的

  • 生成文本图像,确定宽度(图像)
  • 将文本图像覆盖到背景中,确定宽度(背景)
  • 使用上面提到的一种工具,裁剪(宽度(背景)-宽度(图像)/两边都是 2

诀窍是计算出宽度(图像)。 href="https://stackoverflow.com/questions/4485630/how-can-i-auto-adjust-the-width-of-a-gd- generated-image-to-fit-the-text">如何我自动调整 GD 生成的图像的宽度以适合文本?

然后,如果您知道宽度(图像),则可以在叠加之前先裁剪宽度(背景)

It is a two step process as text is dynamically generated

  • Generate the text image, determine width(image)
  • Overlay text image into background, determine width(background)
  • Use one tool mentioned above, crop (width(background)-width(image)/2 on either side

The trick is figuring out the width(image). See: How can I auto adjust the width of a GD-generated image to fit the text?

Then again, if you know width(image), you can crop the width(background) first before overlay

埖埖迣鎅 2024-12-18 09:48:39

请改用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);

Use cropImage() instead. Something like this, perhaps:

$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);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文