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

问题描述 投票:0回答:3

我想访问 SVG 可能使用的所有颜色。我玩过

convert
,但想要一些关于如何找出 SVG 可能包含的独特颜色的指导。

这是我编写的 PHP 代码,用于与

convert
交谈,尝试确定位图是否包含颜色,但它非常有限:

/**
 * 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;
}
svg vector imagemagick inkscape
3个回答
1
投票

如果我们查看格式和打印图像属性文档,我们应该能够使用

-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


0
投票

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

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

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


0
投票

如果您不需要考虑滤镜和颜色混合,那么下面的代码效果很好。

它可能找不到黑色,因为它通常没有声明,因为如果没有指定,它就是标准颜色。

这只是为了查找 SVG 代码本身中声明的颜色,不考虑 CSS。对 CSS 做同样的事情会很容易。它仅查找十六进制代码,但可以轻松扩展以搜索其他颜色选项。

$colors=array();
if(preg_match_all("/(?:color|fill)\s*[=]\s*[\"]?[#]([a-z0-9]+)/i",$html,$matches)){
    $colors=$matches[1];
    $colors=array_unique($colors);
}
© www.soinside.com 2019 - 2024. All rights reserved.