是否可以检测SVG内部的独特颜色?

时间:2018-11-05 13:16:49

标签: svg vector imagemagick inkscape

我想访问SVG可能正在使用的所有颜色。我玩过convert,但想了解如何确定SVG可能包含的独特颜色的一些指导。

这是我编写的与convert交谈的PHP代码,试图确定位图是否包含颜色,但是它非常有限:

/**
 * containsColor
 * 
 * @see     https://www.imagemagick.org/discourse-server/viewtopic.php?t=19580&start=15
 * @see     https://superuser.com/questions/508472/how-to-recognize-black-and-white-images
 * @see     https://www.imagemagick.org/discourse-server/viewtopic.php?t=19580
 * @access  public
 * @static
 * @param   string $path
 * @return  bool
 */
public static function containsColor(string $path): bool
{
    $commands = array(
        'convert ' .
            ($path) .' ' .
            '-format "%[colorspace]" info:'
    );
    $command = implode(' && ', $commands);
    $response = exec($command);
    $color = strtolower($response) !== 'gray';
    return $color;
}

2 个答案:

答案 0 :(得分:0)

如果我们查看Format and Print Image Properties文档,则应该能够使用-format %k识别唯一的颜色计数。

public static function containsColor(string $path): int
{
    $commands = array(
        'convert ' .
            ($path) .' ' .
            '-format "%k" info:'
    );
    $command = implode(' && ', $commands);
    $response = exec($command);
    return (int)$response;
}

如果要评估SVG渲染后使用的所有颜色,可以使用-unique-colors运算符。

convert input.svg -depth 8 -unique-colors txt:-

将输出哪些内容可以通过PHP轻松解析。

# ImageMagick pixel enumeration: 403,1,65535,srgba
0,0: (0,0,0,65535)  #000000FF  black
1,0: (257,0,0,65535)  #010000FF  srgba(1,0,0,1)
2,0: (257,257,257,65535)  #010101FF  srgba(1,1,1,1)
3,0: (257,257,0,65535)  #010100FF  srgba(1,1,0,1)
4,0: (514,257,0,65535)  #020100FF  srgba(2,1,0,1)
5,0: (771,771,771,65535)  #030303FF  grey1
...

请记住,SVG实际上只是XML,因此可以将其加载到DOMDocument类中,并使用DOMXPath提取颜色属性。但是正如评论中正确提到的那样,您将无法识别CSS3滤镜或高级色彩渲染和混合。

使用工作示例进行更新

public static function containsColor(string $input) : bool
{
    $pixelInfoList = [];
    exec(sprintf('convert "%s" -depth 8 -alpha Off --colors 255 -unique-colors txt:-', $input), $pixelInfoList);
    // ... Insert error handling here ...
    for($index = 1; $index < count($pixelInfoList); $index++) {
        preg_match('/\((\d+),(\d+),(\d+)\)/', $pixelInfoList[$index], $colorParts);
        if ($colorParts[1] == $colorParts[2] && $colorParts[2] == $colorParts[3]) {
            // Color is gray. Do nothing?
        } else {
            // Non-gray color. Stop search, and return.
            return true;
        }
    }
    return false;
}

不是完美的,但是是一个开始。

这可以评估txt:-输出的色彩通道。如果红色,绿色和蓝色通道相同,我们可以将其声明为灰色并继续下一行,否则我们可以声明存在非灰色的颜色并停止迭代。我还将使用-alpha Off -colors 255来处理其他数据。

YMMV

答案 1 :(得分:0)

这可能无济于事,因为您似乎想将其用于服务器应用程序,但可能会帮助其他有相同问题的人。

如果您使用的是Inkscape,也可以将其导出为.gpl。 文件>保存副本:GIMP调色板(* .gpl)

但是,这不会保存渐变中显示的所有颜色,只会保存文件中实际使用的颜色。