Можно ли обнаружить уникальные цвета внутри SVG? - PullRequest
0 голосов
/ 05 ноября 2018

Я хочу получить доступ ко всем цветам, которые может использовать 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;
}

Ответы [ 2 ]

0 голосов
/ 06 ноября 2018

Это, вероятно, не поможет вам, потому что вы, кажется, хотите использовать это для серверного приложения, но это может помочь другим с тем же вопросом.

Если вы используете Inkscape, вы также можете просто экспортировать как .gpl. Файл> Сохранить копию: Палитра GIMP (* .gpl)

Это, однако, не сохранит все цвета, отображаемые в градиенте, а только те, которые фактически используются в файле.

0 голосов
/ 05 ноября 2018

Если мы рассмотрим Формат и печать изображения Свойства документа, мы сможем определить уникальный счетчик цветов с -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

...