【问题标题】:Is it possible to detect unique colours inside an SVG?是否可以检测 SVG 中的独特颜色?
【发布时间】:2018-11-05 13:16:49
【问题描述】:

我想访问 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;
}

【问题讨论】:

标签: svg vector imagemagick inkscape


【解决方案1】:

如果我们查看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 提取颜色属性。但正如 cmets 中正确提到的,您将无法识别 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

【讨论】:

  • 感谢@emcconville 的快速回复我对如何解释回复有点茫然。对于简单的黑色/灰色向量,我得到的响应有限,例如:i.imgur.com/NYCfHQ2.png 但对于更多彩色向量,我得到 700 多行响应
  • 然后这个没有定义填充或描边的,也回复了行数:s3-us-west-2.amazonaws.com/app.local.getstencil.com/…
  • 正确。以不同尺寸渲染的相同矢量图形将极大地改变独特颜色的数量。主要是由于渲染器的抗锯齿和颜色混合。我将用一个可能有效的示例更新我的答案,但您将负责构建一个适合您本地化业务需求的解决方案。
【解决方案2】:

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

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

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

【讨论】:

  • 您能更详细地了解它的作用吗?我问是因为 Inkscape 有一个命令行 (CLI) 版本,所以如果这完全符合我的要求,我也许可以研究它的 CLI 等价物。
  • 目前无法调用从命令行导出 gimp 调色板文件的输出扩展。这就是为什么我写它不会帮助你。如果您可以编写一点 Python,您可能可以将其转换为普通扩展,并从 cli 使用它(但需要 GUI)。它遍历文档并收集它找到的所有颜色值,然后保存为 .gpl 文件。代码:gitlab.com/inkscape/extensions/blob/master/…
  • 有趣;好的,我有很多研究要做:) 感谢您的帮助。一旦我尝试过,就会跟进。
猜你喜欢
  • 2014-05-01
  • 2020-04-28
  • 2020-08-31
  • 1970-01-01
  • 2020-12-23
  • 2015-06-27
  • 2021-05-26
  • 1970-01-01
  • 2011-07-17
相关资源
最近更新 更多