Как извлечь картинка из файла SVG?

У меня есть SVG-файл, который содержит по крайней мере одно встроенное изображение JPG/PNG внутри. Я хочу извлечь изображения JPG / PNG из этого SVG-файла и сохранить их на диске.

Я добавляю inkscape tag, поскольку это программа, которую я использую для редактирования SVG-файлов, но я также принимаю решения, используя другие инструменты.

13
задан Denilson Sá Maia
07.04.2023 23:01 Количество просмотров материала 2467
Распечатать страницу

6 ответов

мое собственное решение (или... временное решение):

  1. Выберите изображение в Inkscape
  2. открыть встроенный XML Editor (Shift+Ctrl+X)
  3. выберите xlink:href атрибут, который будет содержать изображение как данные: URI
  4. скопировать data: URI
  5. вставить data: URI в браузер и сохраните его оттуда.

альтернативно, я могу раскрыть SVG-файл в любом текстовом редакторе, найдите data: URI и скопируйте его оттуда.

хотя это решение работает, это немного громоздким, и я хотел бы узнать получше.

23
отвечен Denilson Sá Maia 2023-04-09 06:49

вместо этого есть лучшее решение:

на Extensions -> Images -> Extract Image..., здесь вы можете сохранить выбранное растровое изображение в файл. Однако это расширение работает странно и почему-то работает довольно медленно (но отлично).

еще одно замечание: это расширение является громоздким и тихо умирает на больших изображений. Кроме того, с большим количеством растровых изображений он может увеличить использование памяти inkscape до ужасающих уровней (например, 3 ГБ после извлечения только нескольких изображений).

потому что я получил около 20 svg-файлов с около 70 растровыми изображениями в каждом, каждое изображение размером не менее 1 МБ, мне нужно было другое решение. После короткой проверки с помощью Denilson Sá tip Я разработал следующий php скрипт, который извлекает изображения из svg файлов:

#!/usr/bin/env php
<?php

$svgs = glob('*.svg');

$existing = array();

foreach ($svgs as $svg){
    mkdir("./{$svg}.images");
    $lines = file($svg);
    $img = 0;
    foreach ($lines as $line){
        if (preg_match('%xlink:href="data:([a-z0-9-/]+);base64,([^"]+)"%i', $line, $regs)) {
            $type = $regs[1];
            $data = $regs[2];
            $md5 = md5($data);
            if (!in_array($md5, $existing)) {
                $data = str_replace(' ', "\r\n", $data);
                $data = base64_decode($data);
                $type = explode('/', $type);
                $save = "./{$svg}.images/{$img}.{$type[1]}";
                file_put_contents($save, $data);
                $img++;
                $existing[] = $md5;
            }
        } else {
            $result = "";
        }
    }
}

echo count($existing);

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

бьюсь об заклад, должен быть другой способ, который намного проще, но это зависит от разработчиков inkscape лучше.

12
отвечен Johnny_Bit 2023-04-09 09:06

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

http://bitbucket.org/denilsonsa/small_scripts/src/tip/extract_embedded_images_from_svg.py

этот скрипт написан для Python 2.7, но его довольно легко преобразовать в Python 3. Даже лучше, около 50 строк могут быть удалены после преобразования в Python 3.4, из-за новых функций, введенных в этом версия.

6
отвечен Denilson Sá Maia 2023-04-09 11:23

Как еще один обходной путь, вы можете сохранить как PDF, а затем открыть этот документ с Inkscape.

снимите флажок "вставлять изображения", и бинго, все pngs/jpeg будут выброшены в ваш домашний каталог.

грязный, но быстрее, чем дурачиться с данными: URL.

4
отвечен Nicholas Wilson 2023-04-09 13:40

открыть файл в Inkscape и выберите растровое изображение, которое вы хотите экспортировать. Выберите Файл- > Экспортировать растровое изображение (Ctrl+Shift+E) и экспортируйте только выбранное растровое изображение.

0
отвечен Chris 2023-04-09 15:57

Я улучшить php-скрипт @Johnny_Bit. Новый релиз скрипта может использовать svg с новыми строками. Он извлекает несколько изображений из svg-файла и сохраняет их во внешних png-файлах. Svg и png файлы находятся в каталоге' svg', но вы можете изменить их в константе 'SVG_DIR'.

<?php

define ( 'SVG_DIR', 'svg/' );
define ( 'SVG_PREFIX', 'new-' );

$svgs = glob(SVG_DIR.'*.svg');
$external = array();
$img = 1;

foreach ($svgs as $svg) {
    echo '<p>';
    $svg_data = file_get_contents( $svg );
    $svg_data = str_replace( array("\n\r","\n","\r"), "", $svg_data);
    $svg_file = substr($svg, strlen(SVG_DIR) );
    echo $svg_file.': '.strlen($svg_data).' ????';

    if ( preg_match_all( '|<image[^>]+>|', $svg_data, $images, PREG_SET_ORDER) ) {
        foreach ($images as $image_tag) {

            if ( preg_match('%xlink:href="data:([a-z0-9-/]+);base64,([^"]+)"%i', $image_tag[0], $regs) ) {
                echo '<br/>Embeded image has benn saved to file: ';

               $type = $old_type = $regs[1];
               $data = $old_data = $regs[2];
               $md5 = md5($data);
               if ( array_key_exists($md5, $external) ) {
                $image_file = $external[$md5];
               } else {
                    $data = str_replace(" ", "\r\n", $data);
                    $data = base64_decode($data);
                    $type = explode('/', $type);
                    $image_file = substr( $svg_file, 0, strlen($svg_file)-4 ) . '-' . ($img++) . '.png';
                    file_put_contents(SVG_DIR.$image_file, $data);
                    $external[$md5] = $image_file;
               }
               echo $image_file;
               $svg_data = str_replace('xlink:href="data:'.$old_type.';base64,'.$old_data.'"', 'xlink:href="'.$image_file.'"', $svg_data);
            }
        }
        file_put_contents(SVG_DIR.SVG_PREFIX.'.svg', $svg_data);
    }

   echo '</p>';
}

?>
0
отвечен Ivan Z 2023-04-09 18:14

Постоянная ссылка на данную страницу: [ Скопировать ссылку | Сгенерировать QR-код ]

Ваш ответ

Опубликуйте как Гость или авторизуйтесь

Имя
Вверх