PNG-24 中 PHP Imagick 颜色替换的更有效方法
我正在创建一个小型网络应用程序,人们可以在其中为赛车的不同部分选择颜色。我使用 ImageMagick 拍摄汽车每个部分的单独图像,重新着色(使用 clutImage 函数),并将它们叠加在一起以创建最终图像。
每个图像都是 PNG-24,具有 alpha 透明度。每个图像的尺寸完全相同,以便更容易组合它们。
大约有十层,其中六层正在重新着色。问题是性能有点差;每次颜色变化后渲染图像大约需要十秒钟。这是我的代码:
示例代码:
<?php
if(isSet($piece['color'])) {
//make a 1pixel image to replace color with
$clut = new Imagick();
$clut->newImage(1, 1, new ImagickPixel("#".$piece["color"]));
//change the color of the part
$car_part->clutImage($clut);
}
//now we need to add the part onto the car
$car->compositeImage($car_part, Imagick::COMPOSITE_DEFAULT, 0, 0);
clutImage 似乎对于这项任务来说可能有点过分了;我没有做渐变贴图,我只是用纯色替换所有彩色像素。然而,无论我使用什么函数,它可能仍然需要迭代总共数百万个像素。
有没有更有效的方法来实现这一点,或者这只是我想做的事情的本质?
I'm creating a little web app where people can choose colors for different parts of a race car. I'm using ImageMagick to take separate images of each part of the car, recolor them (with the clutImage function), and layer them on top of each other to create the final image.
Each image is PNG-24 with alpha transparency. Each image is exactly the same size to make it easier to combine them.
There are about ten layers, six of which are being recolored. The problem is that performance is a bit poor; it takes about ten seconds to render the image after each color change. Here's my code:
Sample code:
<?php
if(isSet($piece['color'])) {
//make a 1pixel image to replace color with
$clut = new Imagick();
$clut->newImage(1, 1, new ImagickPixel("#".$piece["color"]));
//change the color of the part
$car_part->clutImage($clut);
}
//now we need to add the part onto the car
$car->compositeImage($car_part, Imagick::COMPOSITE_DEFAULT, 0, 0);
clutImage seems like it might be overkill for this task; I'm not doing a gradient map, I'm simply replacing all colored pixels with a solid color. Yet no matter what function I use, it will probably still have to iterate over several million pixels total.
Is there a more efficient way to accomplish this, or is this just the nature of what I'm trying to do?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
AFAIK,这就是你正在做的事情的本质。归根结底,您只是更改多维数组的一堆索引的值。在某个时刻,将会出现循环。
还有colorFloodfillImage,但我从未实际使用过该方法。不过,这可能值得一试。
我猜想 clutImage 比迭代像素更好,因为它以 c 速度运行,而使用 php 构造(for/while/foreach)迭代像素可能会更慢。
真正提高性能的一种方法是缓存部件,这样具有给定颜色 y 的给定部件 x 仅生成一次。下次有人想要用颜色 y 绘制 x 部分时,您所要做的就是从缓存中提取渲染图像。您可以将图像存储为文件,或者在 clutImage 调用之后将 imagick 对象存储在内存对象缓存(apc/memcached/等)中,以便您可以将其与其他对象合成。
嗯。
AFAIK, that is the nature of what you are doing. When it really comes down to it, you are just changing the values of a bunch of indices of a multidimensional array. At some point or another, there will be a loop.
There is also colorFloodfillImage, but I have never actually used that method. It may be worth a shot though.
I would guess clutImage is better than iterating through the pixels, because it is running at c speeds, where as iterating through the pixels using a php construct (for/while/foreach) would likely be slower.
One way that you may be able to really increase performance would be to cache parts, so that a given part x with a given color y is only generated once. The next time someone wants to paint part x with the color y, all you have to do is pull the rendered image from the cache. You could either store the image as a file, or store the imagick object in a memory object cache (apc/memcached/etc.) right after the clutImage call, so you can composite it with other objects.
hth.