我想访问 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;
}
如果我们查看格式和打印图像属性文档,我们应该能够使用
-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;
}
-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
这可能不会帮助您,因为您似乎想将其用于服务器应用程序,但它可能会帮助其他人解决相同的问题。
如果您使用 Inkscape,您也可以仅导出为 .gpl。 文件 > 保存副本:GIMP 调色板 (*.gpl)
但是,这不会保存渐变中显示的所有颜色,只会保存文件中实际使用的颜色。
如果您不需要考虑滤镜和颜色混合,那么下面的代码效果很好。
它可能找不到黑色,因为它通常没有声明,因为如果没有指定,它就是标准颜色。
这只是为了查找 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);
}