在 PHP 中从图像中裁剪空白
PHP 中是否可以删除图像周围的空白?
注意:澄清一下,我指的是 Photoshop 修剪功能之类的东西。
谢谢。
Is it possible to remove the whitespace surrounding an image in PHP?
NOTE: to clarify I mean something like photoshops trim feature.
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
要修剪图像中有趣部分周围的所有空白(如您所说),首先我们要找出“空白”停止的位置,然后复制这些边界内的所有内容。
我的旧示例,假设图像的所有侧面都有相同的“边框”,只是为了澄清注释:)
To trim all whitespace, as you call it, surrounding the interesting part of the image, first we find out where the "whitespace" stops, and then we copy everything inside of those borders.
My old example, that assumes an identical "border" on all sides of the image, just to clarify the comments :)
Gnud 的脚本冗余地调用imagex 和imagesy。它还会迭代每一侧的每个像素,即使角重叠时也是如此。这个改进的版本消除了冗余的函数调用,并且仅检查每个像素一次,从而显着提高了速度。如果每个像素都被修剪,则该函数返回等于 2 的状态 ($result['#'])。
Gnud's script redundantly calls imagesx and imagesy. It also iterates every pixel on every side, even when the corners overlap. This improved version eliminates redundant function calls and checks every pixel only once, granting a significant increase in speed. The function returns a status ($result['#']) equal to 2 if every pixel is the trimmed.
PHP的gd库有
imagecropauto
函数(PHP版本5.5+):默认情况下,
imagecropauto
将尝试使用透明度进行裁剪,然后使用图像的 4 个角来尝试检测要裁剪的背景;我还成功地使用以下常量代替了上面示例中的IMG_CROP_AUTO
:IMG_CROP_BLACK
- 对于黑色背景的图像很有用IMG_CROP_WHITE
-对于白色背景的图像很有用IMG_CROP_THRESHOLD
- 允许您设置裁剪时使用的颜色和阈值PHP's gd library has the
imagecropauto
function (PHP version 5.5+):By default
imagecropauto
will try to crop using transparency, and then fall back on using the 4 corners of the image to attempt to detect the background to crop; I have also had success with the following constants in place ofIMG_CROP_AUTO
in the example above:IMG_CROP_BLACK
- Useful for images with a black backgroundIMG_CROP_WHITE
- Useful for images with a white backgroundIMG_CROP_THRESHOLD
- Allows you to set a colour and threshold to use when cropping我知道这已经很老了,但是如果您启用了 ImageMagick,则可以使用此方法
修剪图像
I know this is pretty old but if you have ImageMagick enabled you can use this method
Trim Image
我意识到这已经很老了,但我对通过 GD 修剪图像的看法略有不同。不要一次只做一侧,而是做全部四侧。在某些方面,它的 CPU 速度更快、成本更低。但是,如果您在找到上下左右两侧时停止 FOR 循环 - 这会比这更快。
所以首先是:
然后是:
在这两种情况下, $color 变量包含图像中的第一个颜色点:
这是因为在 GIF 图像中 - 第一个点 99% 的时间是透明(或背景)颜色。另外,$offset(对我来说)是一种表达我知道图像只会如此宽和如此高的方式。因此,如果我绘制的东西最大仅为 256 x 256,但我将其放在 1024 x 1024 背景上,我可以去掉其中一些背景并进行 255 的偏移,从而使 FOR 循环仅从 255 到 (1024 -255) 或 769.
好的 - 在有人问之前 - 为什么我会做这样的事情 - 因为某些字体(如 Bastarda)中没有正确的字体信息,并且字母“z”的 256pt 输出会生成图像“z”的底部超过 256(下降到 512 之类的),因此为了获得整个图像,您必须开始(或结束)比您认为字体会走得更远。所以我将差异分开并从两端去掉 255 个像素。这是在实际看到巴斯塔达这样做之后。
一些附加说明:
1. 您可以将 PNG 图像设置为类似于 GIF 图像,但通常您必须指定背景颜色。
2. JPEG 图像每次解压缩的方式并不完全相同。因此,即使比较您加载两次的同一图像也可能效果不一样,并且可能会给出不同的尺寸。
3. 这些例程最适合简单的黑白(或两种颜色)图像。多种颜色可以打破这些惯例。特别是如果您决定使用公差。
4. 要使用容差来确定是否找到图像的边缘,您所要做的就是预先计算高容差和低容差(即:如果红色分量的容差为五 (5)) ,那么您可以将公差计算为 X-5-to-x+5 或 x-2.5-to-x+2.5,具体取决于您希望公差是整个范围还是只是 +/- 范围)。您可以对颜色的红色、绿色、蓝色和 ALPHA 部分或整个颜色本身有一个容差。因此,如果您愿意,您可以计算几种不同的容差,并且根据您的需要,所有这些都是正确的方法。
I realize this is quite old but I have a slightly different take on trimming an image via GD. Instead of doing just one side at a time - do all four. It is faster and less expensive cpu-wise in some ways. However, if you stop the FOR loops the moment you find the top-bottom-left-right sides - that is faster than this.
So first there is:
and then there is:
In both cases, the $color variable contains the first color dot in the image:
This is because in GIF images - the first dot is 99% of the time the transparent (or background) color. Also, the $offset is (for me) a way to say I know the image is only going to be so wide and so high. So if I draw something that is only a maximum of 256 by 256 but I put it on a 1024 x 1024 background I can whack off some of that background and make an offset of 255 thus making the FOR loops only go from 255 to (1024-255) or 769.
Ok - before someone asks - WHY I would do such a thing - Because some fonts (like Bastarda) don't have the correct font information in them and a 256pt output of the letter "z" produces an image where the bottom of the "z" goes past 256 (down to something like 512) so in order to get the entire image you have to start (or end) farther down than what you'd think the font would go. So I split the difference and whack off 255 pixels from either end. This was after actually seeing that Bastarda does this.
Some additional notes:
1. PNG images you CAN set up to be like GIF images but normally you will have to specify what the background color is going to be.
2. JPEG images do NOT uncompress the exact same way each time. So even comparing the same image you loaded twice might not work the same and may give different sizes.
3. These routines work best on simple black and white (or two color) images. Multiple colors can throw these routines off. Especially if you decide to use tolerances.
4. To use tolerances to determine if you have found the edge of an image, all you have to do is to pre-compute both the high and low tolerance (ie: if you have a tolerance of five(5) on the red component, then you can compute the tolerance as EITHER X-5-to-x+5 OR x-2.5-to-x+2.5 depending upon if you want the tolerance to be the WHOLE range or just the +/- range). You can have a tolerance for the RED, GREEN, BLUE, and ALPHA parts of the color or the entire color itself. So there are several different tolerances you can compute if you want and all of them are the correct way to do it depending upon your needs.
查看 PHP 中的 ImageMagick 库。它具有处理和操作图像的良好方法(包括 crop)。
您必须弄清楚图像周围的“空白”在哪里。这可能具有挑战性,因为“空白”可能是白色、其他颜色、透明度等......
Check out the ImageMagick library in PHP. It has good methods of working with and manipulating images (including crop).
You'll have to figure out where the "whitespace" is around the image. It could be challenging, since "whitespace" could be the color white, some other color, transparency, etc...
假设您有边框颜色为 0x212121 的图像。
您想使用 PHP 自动修剪此边框。
你可以用这样的代码来做到这一点:
Lets say you have image with border color 0x212121.
You want to automatically trim this border with PHP.
You can do it with such code:
我使用 gnud 策略,但重写逻辑,因为在我的情况下它不起作用。
我的版本:
I use strategy of gnud, but rewrite logic because in my case it doesn't work.
My version: