【问题标题】:PNG processing WITHOUT Image Magick and imagefrompng()没有 Image Magick 和 imagefrompng() 的 PNG 处理
【发布时间】:2016-11-08 06:37:23
【问题描述】:

我需要在具有透明度的 PNG 图像中将黄色的每个色调更改为蓝色,并将深灰色的每个色调更改为浅灰色。

问题是:

我不能使用 Photoshop,因为我有 100 张图像,而且我需要多次更改色调。 我不能使用 Image Magick,因为我需要比“-fx”更复杂的计算。 我不能使用 PHP imagefrompng(),因为这个讨厌的废话不适用于我的很多图像, 即使有所有建议的修复,例如:

$background = imagecolorallocate($png, 255, 255, 255);
// removing the black from the placeholder
imagecolortransparent($png, $background);
// turning off alpha blending (to ensure alpha channel information is preserved, rather than removed (blending with the rest of the image in the form of black))
imagealphablending($png, true);
// turning on alpha channel information saving (to ensure the full range of transparency is preserved)
imagesavealpha($png, true);

等等。它适用于某些图像,但不适用于其他图像。

我只需要一个 PNG 库(可能不在 PHP 中),它可以为我提供坐标 x、y 处像素的红色、绿色、蓝色和 alpha 分量,然后在计算后设置此像素,例如:

$rgba = getrgba($image, $x, $y);
$rgba = my_function($rgba);
setrgba($image, $x, $y, $rgba);

也许您可以推荐其他语言的库,而不仅仅是 PHP?

【问题讨论】:

  • 欢迎来到 Stack Overflow!请花些时间阅读介绍性的tour。要求我们推荐或查找书籍、工具、软件库、教程或其他场外资源的问题对于 Stack Overflow 来说是无关紧要的,因为它们往往会吸引固执己见的答案和垃圾邮件。另见Help centerWhat topics can I ask about here?

标签: php png rgb photoshop rgba


【解决方案1】:

如果您不介意使用 Python,请查看 Pillow,特别是它的 PixelAccess 类。这些线程(12)应该很有帮助,并且有一些代码示例。

【讨论】:

    【解决方案2】:

    方法一

    如果您只想获取 R、G、B 和 Alpha 的原始像素值而不用担心压缩和编码,请使用 ImageMagick 将图像转换为普通、未压缩、未编码的二进制和阅读并根据自己的内心进行处理。

    所以,如果我们用 RGBA(0,64,255,0.5) 制作一个 1x1 像素的 PNG 文件进行测试:

    convert -size 1x1 xc:"rgba(0,64,255,0.5)" a.png
    

    现在我们可以让 ImageMagick 制作一个原始的 RGBA 文件,您可以使用任何语言以任何复杂程度来读取和处理该文件:

    convert a.png rgba:data.bin
    

    现在我们可以查看该文件:

    xxd data.bin
    

    结果

    0000000: 0040 ff80                                .@..
    

    您可以在此处查看和读取所有 RGBA 像素。完成后,只需执行相反的操作即可取回 PNG - 请注意,您必须先告诉 ImageMagick 大小,因为它无法知道这一点:

    convert -size 1x1 rgba:data.bin new.png
    

    请注意,ImageMagick 是一个相当大的安装包,您可以使用更轻量级的vips 包来实现与上述相同的功能:

    vips VipsForeignSaveRaw a.png data.rgb
    

    方法二

    或者,如果您希望数据为未压缩、人类可读的 ASCII,请使用古老的 NetPBM 格式 PPM(便携式像素图)和 PGM(便携式灰图) - 请参阅 NetPBM on Wikipedia

    制作一个 4x1 图像并写为 PPM:

    convert -size 4x1 xc:"rgba(0,64,255,0.1)" -compress none ppm:-
    P3
    4 1
    65535
    0 16448 65535 0 16448 65535 0 16448 65535 0 16448 65535
    

    您希望可以在那里看到 4 个重复的 RGB 值。如果您想将其作为文件,只需将末尾的ppm:- 更改为someFile.ppm

    再次制作相同的图像并将Alpha通道提取到单独的文件中:

    convert -size 4x1 xc:"rgba(0,64,255,0.1)" -alpha extract -compress none pgm:-
    P2
    4 1
    65535
    6554 6554 6554 6554 
    

    希望您能看到65540.1,范围为0-65535。

    如果您只想要上述任何一个的 8 位数据,请添加 -depth 8

    方法3

    正如 Glenn 在 cmets 中建议的那样,另一个选项是在选项 2 上省略 -compress none,这将为您提供非常相似的文件格式,除了像素数据将是二进制的,在保留为 ASCII 的标头之后。这通常更快更小。

    【讨论】:

    • 还有方法 3,即原始 PPM。您可以获得原始 RGBA 的速度,但仍然有图像标题(使用 P6 而不是 P3)来记住尺寸。它与方法 1 相同,但在初始 convert 步骤中省略了 -compress none 选项。请注意,如果深度大于 8,则颜色样本中的字节将按 MSB、LSB 顺序排列。
    • @GlennRanders-Pehrson 是的,谢谢。我有点尝试做一个二进制和一个 ASCII 给 OP 一些选择/灵活性。我将编辑您的建议 - 谢谢。
    • @GlennRanders-Pehrson 方法 2 和 3 中的第二个 convert 命令专门提取 alpha 通道。
    • @GlennRanders-Pehrson 你是对的 - 我已经更正了。甚至不知道它是如何进入的,因为我实际上记得在我的终端中输入了 PGM。谢谢。
    猜你喜欢
    • 2019-04-09
    • 1970-01-01
    • 2011-01-06
    • 1970-01-01
    • 2011-01-09
    • 2017-11-09
    • 2013-08-26
    • 2019-09-10
    • 1970-01-01
    相关资源
    最近更新 更多