PHP将24位颜色转换为4位颜色

时间:2014-10-06 22:04:41

标签: php colors gd

背景,我正在将图像转换为ascii艺术。这非常有效,甚至可以使用24位颜色,将颜色转换为正确的rgb值。但是,我现在想要用4位调色板而不是24位渲染ascii艺术。

如何使用PHP将24位颜色转换为4位?

更具体地说,我有标准的IRC颜色托盘,我需要将任何给定的十六进制或RGB值转换为。当转换为4位颜色时,颜色最好尽可能匹配。

我对此的其他想法是将图像本身转换为4位调色板(使用GD,这是我现在用来读取颜色的颜色),然后再尝试抓取它的颜色。另一个想法可能是为以下每种颜色定义一个颜色范围,并检查给定的24位颜色是否在该范围内,但是我不知道如何将所有颜色的范围放入该调色板中

enter image description here

4 个答案:

答案 0 :(得分:1)

imagetruecolortopalette可以让你减少颜色,但结果可能会有很大差异,我不知道是否有一种“映射”的方法。正确的颜色或指定调色板。

测试图片(24位):

Bliss

减少到4位(没有抖动):

$img = imagecreatefrompng('Bliss.png');
imagetruecolortopalette($img, false, 16);
imagepng($img, 'Bliss2.png');

Bliss, without dithering

减少到4位(带抖动):

$img = imagecreatefrompng('Bliss.png');
imagetruecolortopalette($img, true, 16);
imagepng($img, 'Bliss3.png');

Bliss, with dithering

正如您所看到的,结果远非完美。但也许这对你来说是一个好的开始。

答案 1 :(得分:0)

我认为ImageMagick(或GraphicsMagick)可以使用-depth选项执行此操作。这里有一个讨论:http://www.imagemagick.org/discourse-server/viewtopic.php?f=1&t=15395

更新:我应该补充一点,ImageMagick不是一个PHP库,但在http://pecl.php.net/package/imagick有一个PECL包装器(imagick)。

答案 2 :(得分:0)

我认为你需要使用remap将图像中的颜色映射到样本中的颜色调色板。我在命令行这样做:

convert image.jpg -remap palette.jpg out.jpg

您可能或可能不想要dither选项 - 请查看。

原始图片在这里:

enter image description here 这是我的palette.jpg(你只需要一个非常小的图片,这太大了 - 我会尽快解决这个问题)

enter image description here

和结果 enter image description here

您还可以使用ImageMagick根据您想要的颜色创建调色板。我手动编码以下内容并没有太多关注,所以在假设它们是正确的之前你需要检查这里的RGB值:

#/bin/bash
cat<<EOF | convert txt:- palette.png
# ImageMagick pixel enumeration: 8,2,256,rgb
0,0: (255,255,255)
1,0: (0,0,0)
2,0: (0,0,255)
3,0: (255,255,0)
4,0: (255,0,0)
5,0: (128,128,128)
6,0: (255,105,180)
7,0: (173,216,230)
0,1: (50,205,50)
1,1: (139,0,0)
2,1: (255,165,0)
3,1: (128,0,128)
4,1: (0,0,139)
5,1: (0,128,128)
6,1: (0,128,0)
7,1: (211,211,211)
EOF

基本上,上面的脚本为ImageMagick提供了RGB值作为文本,并要求它生成小的8x2图像,如下所示:

enter image description here

然后,您可以将此调色板与remap操作一起使用。

答案 3 :(得分:0)

最后,尽管有关于imagemagick的精彩建议,我发现使用直接php的一个很好的解决方案。我能够通过使用delta E 2000计算最接近的颜色,并在github上找到修改后的php-color-difference库,这是我的分叉:https://github.com/nalipaz/php-color-difference

相关的例子是:

<?php
include('lib/color_difference.class.php');

$palette = array(
  '00' => array(255, 255, 255),
  '01' => array(0, 0, 0),
  '02' => array(0, 0, 139),
  '03' => array(0, 128, 0),
  '04' => array(255, 0, 0),
  '05' => array(139, 0, 0),
  '06' => array(128, 0, 128),
  '07' => array(255, 165, 0),
  '08' => array(255, 255, 0),
  '09' => array(50, 205, 50),
  '10' => array(0, 128, 128),
  '11' => array(173, 216, 230),
  '12' => array(0, 0, 255),
  '13' => array(255, 105, 180),
  '14' => array(128, 128, 128),
  '15' => array(211, 211, 211),
);

$color_rgb = array(255, 255, 128);
$color_delta_e = new color_difference($color_rgb);
$match_index = $color_delta_e->getClosestMatch($palette);
$color = $palette[$match_index];

我很满意这个解决方案和少量的开销。谢谢你的建议。