Четверг, 25.09.2025 19:22

Преобразуем SVG в PNG с помощью CMake

Преобразуем SVG в PNG с помощью CMake

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

Сегодня мы рассмотрим создание png изображения из svg изображения с помощью Inkscape и Cmake.

Установка Inkscape в Msys2

Для работы с SVG лучшим редактором на данный момент является Inkscape. Так же у него есть режим командной строки, позволяющий конвертировать файлы из формата svg  в любой растровый формат.

Обратите внимание! Мы будем устанавливать версию для ucrt (Universal C Runtime) чтобы избежать конфликтов между пакетами.

Установим inkscape:

pacman -S mingw-w64-ucrt-x86_64-inkscape

Inkscape будет установлен в папку:

C:\msys64\ucrt64\bin\

Настройка проекта

Начнем мы с проекта, размещенного в git-репозитории.

Если папка:

c:\project\colortable_msi_custom_png_gen

уже существует, переместите или удалите её:

cd c:\projects
rmdir /q/s colortable_msi_custom_png_gen

Мы будем использовать проект из git-репозитория:

cd c:\projects
rmdir /q/s articles_blog_altuninvv_ru
git clone https://gitflic.ru/project/vasiliyaltunin/articles_blog_altuninvv_ru.git --depth 1

Скопируем папку с проектом:

xcopy /y/e .\articles_blog_altuninvv_ru\qt6\colortable_msi_custom_png_gen\ .\colortable_msi_custom_png_gen\

Добавляем политику CMP0177

Ранее мы не обращали на это внимание, но сегодня пришла пора внести небольшую правку в конфигурацию.

Откроем папку с проектом:

cd c:\projects\colortable_msi_custom_png_gen
code .

Добавим политику CMP0177 чтобы избавится от надоедливых сообщений:

CMake Warning (dev) at cmake/install.cmake.in:8 (install):
  Policy CMP0177 is not set: install() DESTINATION paths are normalized.  Run
  "cmake --help-policy CMP0177" for policy details.  Use the cmake_policy
  command to set the policy and suppress this warning.
Call Stack (most recent call first):
  CMakeLists.txt:29 (include)
This warning is for project developers.  Use -Wno-dev to suppress it.

Откроем файл CMakeLists.txt и добавим после строки:

project(colorconsoleapp VERSION 0.1 LANGUAGES CXX)

Блок:

if(POLICY CMP0177)
    cmake_policy(SET CMP0177 NEW)
endif()

Запустим конфигурирование:

cmake -S . -B build

Сообщение больше не появляется!

Подготовка SVG файлов

Исходный код изображений в векторном формате у нас будет храниться в папке cmake\wix\source. При сборке png-файлы будут создаться в папке build.

Создадим папку для файлов:

mkdir cmake\wix\source
cd cmake\wix\source

Для этой статьи я создал простой фон.

Изображение удалено.

Загрузим файл с фоном:

curl -o mosaik_base_bg.svg https://blog.altuninvv.ru/img/mosaik_base_bg.svg

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

Создадим файлы для картинок:

type nul > welcome.svg
type nul > top_bg.svg

Добавим содержимое для файла welcome.svg:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->

<svg
   width="493"
   height="312"
   viewBox="0 0 130.43958 82.55"
   version="1.1"
   id="svg1"
   xml:space="preserve"
   xmlns:xlink="http://www.w3.org/1999/xlink"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:svg="http://www.w3.org/2000/svg"><defs
     id="defs1" /><g
     id="layer1"><image
       preserveAspectRatio="none"
       width="47.078339"
       height="47.078339"
       xlink:href="mosaik_base_bg.svg"
       id="use25"
       x="-3.8608522"
       y="-2.8283124"
       style="opacity:0.560636" /><use
       x="0"
       y="0"
       xlink:href="#use25"
       id="use1"
       transform="translate(-0.00292326,44.11862)" /></g></svg>

Добавим содержимое для файла top_bg.svg:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->

<svg
   width="493"
   height="58"
   viewBox="0 0 130.43958 15.345833"
   version="1.1"
   id="svg1"
   xml:space="preserve"
   xmlns:xlink="http://www.w3.org/1999/xlink"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:svg="http://www.w3.org/2000/svg"><defs
     id="defs1" /><g
     id="layer1"><g
       id="g1"
       transform="matrix(0.87658945,0,0,0.87658945,3.6538951,-3.206476)"><image
         preserveAspectRatio="none"
         width="48.669945"
         height="48.669945"
         xlink:href="mosaik_base_bg.svg"
         id="use25"
         x="-7.6686878"
         y="-16.212698"
         style="opacity:0.266402" /><use
         x="0"
         y="0"
         xlink:href="#use25"
         id="use1"
         transform="translate(46.988415,-0.01886454)" /><use
         x="0"
         y="0"
         xlink:href="#use1"
         id="use2"
         transform="translate(46.981607,-0.00781398)" /><use
         x="0"
         y="0"
         xlink:href="#use2"
         id="use3"
         transform="translate(47.015878,-0.05335697)" /></g></g></svg>

Проверим как работает преобразование svg в png запустим:

C:\msys64\ucrt64\bin\inkscape.exe --export-overwrite --export-type=png --export-filename=..\welcome.png welcome.svg
C:\msys64\ucrt64\bin\inkscape.exe --export-overwrite --export-type=png --export-filename=..\top_bg.png top_bg.svg

В папке mkdir cmake\wix будут созданы файлы:

welcome.png
top_bg.png
Изображение удалено.Изображение удалено.

Конвертация работает.

Конвертируем изображения с помощью CMake

Для конвертации фалов нам потребуется несколько настроек.

В файл cmake\settings.cmake.in добавим строки:

# Задаем пути для поиска файла inkscape.exe
set(MY_INKSCAPE_SEARCH_PATH
    C:/msys64/ucrt64/bin
    "C:/Program Files/Inkscape/bin"
)

# Задаем список файлов
set(MY_SVG_IMAGES_NAMES
    welcome
    top_bg
)
# Преобразуем список в формат CMake
set(MY_SVG_IMAGES "${MY_SVG_IMAGES_NAMES}")

Здесь мы задаем папки для поиска установленного CMake и имена файлов с изображениями.

Создадим файл для конфигурации svg:

cd c:\projects\colortable_msi_custom_png_gen
type nul > cmake/svg.cmake.in

Добавим содержимое:

# Задаем команды для сборки SVG

# Пытаемся найти установленный Inkscape в папках указанных в MY_INKSCAPE_SEARCH_PATH
find_file(MY_INKSCAPE_FILE inkscape.exe
    PATHS ${MY_INKSCAPE_SEARCH_PATH}
)

# Если Inkscape был найден то задаем правила сборки
if(MY_INKSCAPE_FILE)

    #Создаем папку для сборки изображений
    make_directory(${CMAKE_CURRENT_BINARY_DIR}/wix)

    set(MY_SVG_DEPENDS_LIST "")

    # Для каждого файла из списка добавляем команду и сам файл в список зависимостей
    foreach(SVGS ${MY_SVG_IMAGES})
       
        #Добавляем команды для сборки
        add_custom_command(
            OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/wix/${SVGS}.png
            COMMAND ${MY_INKSCAPE_FILE} --export-overwrite --export-type=png --export-filename=${CMAKE_CURRENT_BINARY_DIR}/wix/${SVGS}.png ${PROJECT_SOURCE_DIR}/cmake/wix/source/${SVGS}.svg
        )

        # Добавляем файл в список зависимостей
        list(APPEND MY_SVG_DEPENDS_LIST ${CMAKE_CURRENT_BINARY_DIR}/wix/${SVGS}.png)
    endforeach()

    # Задаем target для SVG он будет выполняться во время сборки проекта для каждого .png файла
    add_custom_target(
        SVGConvertTarget
        ALL
        DEPENDS ${MY_SVG_DEPENDS_LIST}
    )

    message("=== SVG converter setup complete")

else()
    # Если Inkscape не найден - выводим предупреждение
    message(WARNING "=== Inkscape not found! I will skip svg converter jobs!")
endif()

Откроем файл cmake\wix.cmake.in и заменим блок:

# Баннер отображаемый вверху каждой страницы установщика. Обязательные размеры 493x58 px
set(CPACK_WIX_UI_BANNER "${PROJECT_SOURCE_DIR}/cmake/wix/top_bg.png")

# Баннер отображаемый на странице приветствия и на последней странице установщика. Обязательные размеры 493x312px
set(CPACK_WIX_UI_DIALOG "${PROJECT_SOURCE_DIR}/cmake/wix/welcome.png")

На

# Если Inkscape был найден то используем папку с собранными изображениями
if(MY_INKSCAPE_FILE)

   # Баннер отображаемый вверху каждой страницы установщика. Обязательные размеры 493x58 px
   set(CPACK_WIX_UI_BANNER "${CMAKE_CURRENT_BINARY_DIR}/wix/top_bg.png")

   # Баннер отображаемый на странице приветствия и на последней странице установщика. Обязательные размеры 493x312px
   set(CPACK_WIX_UI_DIALOG "${CMAKE_CURRENT_BINARY_DIR}/wix/welcome.png")

# Если Inkscape не был найден используем старые изображения
else()

   # Баннер отображаемый вверху каждой страницы установщика. Обязательные размеры 493x58 px
   set(CPACK_WIX_UI_BANNER "${PROJECT_SOURCE_DIR}/cmake/wix/top_bg.png")

   # Баннер отображаемый на странице приветствия и на последней странице установщика. Обязательные размеры 493x312px
   set(CPACK_WIX_UI_DIALOG "${PROJECT_SOURCE_DIR}/cmake/wix/welcome.png")

endif()

Так как конвертация без установленного Inkscape невозможна, мы сначала пробуем его найти.

Если программа не найдена, то выводим предупреждение:

CMake Warning at cmake/svg.cmake.in:40 (message):
 === Inkscape not found! I will skip svg converter jobs!
Call Stack (most recent call first):
 CMakeLists.txt:14 (include)

Так как это не критичная ошибка сборка продолжиться.

Даже сборка дистрибутива пройдет успешно, так как на этот случай у нас есть старые файлы с картинками.

Если Inkscape найден, то начнется настройка:

- Будет создана папка wix в папке build для хранения наших .png файлов

- Для каждого файла указанного в списке MY_SVG_IMAGES будет создана команда для конвертирования а имя png файла с полным путем к нему добавлено в список MY_SVG_DEPENDS_LIST

- Будет создан target SVGConvertTarget вызываемый при сборке основной программы

В файле CMakeLists.txt после:

include(${PROJECT_SOURCE_DIR}/cmake/settings.cmake.in)

Добавим:

# Настраиваем конвертер SVG
include(${PROJECT_SOURCE_DIR}/cmake/svg.cmake.in)

Обновим файлы с картинками:

Удалим файлы

del cmake\wix\welcome.png
del cmake\wix\top_bg.png

Запустим конфигурирование

cmake -S . -B build

Запустим сборку

cmake --build build
[ 16%] Generating wix/welcome
[ 33%] Generating wix/top_bg
[ 33%] Built target SVGConvertTarget
[ 66%] Built target colorconsole
[ 83%] Building CXX object CMakeFiles/colorconsoleapp.dir/main.cpp.obj
[100%] Linking CXX executable colorconsoleapp.exe
[100%] Built target colorconsoleapp

Были сгенерированы файлы с изображениями и  собрана программа.

Скопируем собранные файлы в папку с конфигурацией cmake

xcopy /y/e build\wix\*.png  cmake\wix\

Это можно сделать всего один раз.

Запустим сборку установщика:

cmake --build build --target=package

Установщик будет собран, запустим его:

.\build\colorconsoleapp-0.1-win64.msi

Теперь установщик у нас выглядит следующим образом.

Изображение удалено.Изображение удалено.Изображение удалено.Изображение удалено.Изображение удалено.

Заключение

Сегодня мы рассмотрели создание png изображения из svg изображения с помощью Inkscape и Cmake:

Установили Inskcape с помощью MSYS2;

Загрузили фон изображения в формате SVG;

Добавили SVG файлы, использующие этот фон;

Вручную запустили конвертацию для проверки, что всё работает нормально;

Добавили в cmake\settings.cmake.in переменные для настройки конвертирования;

Добавили файл cmake/svg.cmake.in содержащий команды для сборки изображений;

Внесли изменения в файл cmake\wix.cmake.in чтобы быть уверенными, что сборка дистрибутива произойдёт и в том случае, если Inkscape не установлен;

Произвели сборку и убедились, что картинки создаются корректно;

Произвели сборку дистрибутива с новыми картинками.

Категория C++
Теги CMAKE inkscape svg

Добавить комментарий

Простой текст

  • HTML-теги не обрабатываются и показываются как обычный текст
  • Строки и абзацы переносятся автоматически.
  • Адреса веб-страниц и email-адреса преобразовываются в ссылки автоматически.
Просмотров: 94