Форум русскоязычного сообщества Ubuntu


Хотите сделать посильный вклад в развитие Ubuntu и русскоязычного сообщества?
Помогите нам с документацией!

Автор Тема: Нужно массовое, пакетное изменение размера svg картинок  (Прочитано 1309 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн ase66

  • Автор темы
  • Участник
  • *
  • Сообщений: 156
    • Просмотр профиля
Нужно массовое, пакетное изменение размера svg картинок с 256х256 на 22х22.
Нужен качественный скрипт, желательно для Inkscape. Такой же как например svgtopng.sh или типа того.
Можно и CLI, но там качество не то. Хотя нужно только размер корректно изменить.

Оффлайн ReNzRv

  • Старожил
  • *
  • Сообщений: 2648
    • Просмотр профиля
convert из пакета ImageMagick:
convert SOURCE_IMAGE.svg -geometry 22x22 OUT_IMAGE.svg

Оффлайн victor00000

  • Старожил
  • *
  • Сообщений: 15568
  • Глухонемой (Deaf)
    • Просмотр профиля
Цитировать
svgtopng.sh "file1.svg" "file2.png"
#!/bin/bash
convert "$1" "$2"
Wars ~.o

Оффлайн ase66

  • Автор темы
  • Участник
  • *
  • Сообщений: 156
    • Просмотр профиля
К сожалению у меня несколько тысяч картинок. По одной штуке их не перебрать. Я могу все svg экспортировать в png идеальным  по качеству скриптом svgtopng.sh. Проблема в том, что тема распухнет на несколько сотен мегабайт.

Должен быть способ трансформировать svg в svg меньшего размера, пакетно. По крайней мере во многих темах иконок в svg есть размерные папки.

Гляньте на красоту svgtopng

#!/bin/sh
#################################################################################
#                                                                               #
# Если Программа 'optipng' на данный момент не установлена.                     #
# Вы можете установить её, выполнив: sudo apt-get install optipng               #
#                                                                               #
# Очень медленно работает optipng -o9 *.png но уменьшает картинку на 3-10-20%   #
#    это можно отключить вот так #optipng -o9 *.png                             #
#                                                                               #
#    This program is free software: you can redistribute it and/or modify       #
#    it under the terms of the GNU General Public License as published by       #
#    the Free Software Foundation, either version 3 of the License, or          #
#    (at your option) any later version.                                        #
#                                                                               #
#    This program is distributed in the hope that it will be useful,            #
#    but WITHOUT ANY WARRANTY; without even the implied warranty of             #
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              #
#    GNU General Public License for more details.                               #
#                                                                               #
#    You should have received a copy of the GNU General Public License          #
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.      #
#                                                                               #
#################################################################################
#
# By Thomas Bourcey <sckyzo@gmail.com>
#
# Script for exporting SVGs to PNGs with Inkscape.
# Optimize png with optipng
# sort png by size
# Debug mode :)
# set -x
 
 
## CHANGE ONLY THIS VARIABLES ##
################################
 
ICON_FOLDER="path_to_the_destination"
SIZE="16 22 24 32 48 64 96 256"
 
 
## DO NOT TOUCH AFTER ##
########################
 
# for each file ending with .svg
# для svgz можно заменить на *.svgz но это добавляет к картинкам - z.png потом можно переименовать все сразу в Thunar на .png
for file in *.svg
do
        # strip the .svg part and save output as $filename
        filename=`echo "${file}" | sed s/.svg//`
 
        # Generate PNG
        for WIDTH in $SIZE; do
                # export current file to .png
                /usr/bin/inkscape -z -f "${file}" -w $WIDTH -e "$filename.png"
 
                # optipng
                optipng -o9 *.png
 
                # move files
                for PNG in *.png*
                do
                        if [ -f $PNG ]; then
                        format=`identify -format '%w' $PNG`
                                # Create directory
                                if [ ! -f ${ICON_FOLDER}/${format}x${format}/apps ]; then
                                        mkdir -p ${ICON_FOLDER}/${format}x${format}/apps
                                fi
                                # Move files
                                mv -i $PNG ${ICON_FOLDER}/${format}x${format}/apps/${PNG}
                        else
                                # If no icons
                                echo "There are no PNG files"
                        fi
                done
        done
done


Можно что ни будь похожие? Я что-то не могу найти ничего подобного для svg-svg.
« Последнее редактирование: 15 Февраля 2017, 12:55:00 от ase66 »

Оффлайн peregrine

  • FSM
  • СуперМодератор
  • Старожил
  • *
  • Сообщений: 7203
  • Gentoo x64 Ubuntu 16.04.1 x64
    • Просмотр профиля
ase66, svg - векторная графика, у неё строго говоря нет разрешения (точнее оно есть (в каком-то смысле), но не особо важно, по крайней мере для темы иконок). Если важно уменьшить вес иконок, есть замечательная (мне понравилась) программа от пользователя ЛОР-а RazrFalcon. Вот тут я решал свою проблему, где она была мне предложена. Ссылка на гитхаб есть в той теме. Но надо помнить, что не смотря на то, что его программа не портит (в моем случае по крайней мере) отображение иконок, она может усложнить дальнейшее редактирование иконки в Inkscape, т.е. есть смысл оставлять исходники. А конвертированные в PNG файлы можешь пожать моим скриптом, на многое не рассчитывай, но около 30% обычно жмет.
Код: (bash) [Выделить]
#!/bin/bash
#Функции обработки
opt_optipng ()
{
input="$1"
echo -e "\e[01;34mОбрабатывается\e[00m \e[01;31m(optipng):\e[00m \e[01;32m$input\e[00m"
optipng -o3 "$input" >/dev/null 2>&1
}

opt_advpng ()
{
input="$1"
echo -e "\e[01;34mОбрабатывается\e[00m \e[01;31m(advpng):\e[00m \e[01;32m$input\e[00m"
advpng -z -4 "$input">/dev/null 2>&1
}

opt_advdef ()
{
input="$1"
echo -e "\e[01;34mОбрабатывается\e[00m \e[01;31m(advdef):\e[00m \e[01;32m$input\e[00m"
advdef -z -4 "$input">/dev/null 2>&1
}

opt_jpegtran ()
{
input="$1"
echo -e "\e[01;34mОбрабатывается\e[00m \e[01;31m(jpegtran):\e[00m \e[01;32m$input\e[00m"
jpegtran -optimize -progressive -copy none -outfile "$input" "$input" 2>&1
#jpegtran -arithmetic -copy none -outfile "$input" "$input" 2>&1
}

opt_gifsicle ()
{
input="$1"
echo -e "\e[01;34mОбрабатывается\e[00m \e[01;31m(gifsicle):\e[00m \e[01;32m$input\e[00m"
gifsicle --batch --optimize=3 "$input" >/dev/null 2>&1
}
#Очистка экрана и поиск файлов для обработки
clear
SIZEPNG=$(find . -type f \( -iname '*.png' -o -iname '*.PNG' \) -printf '%s\n' | tee >(numpng=$(wc -l)) | awk '{SUM+=$1} END {print SUM}');
SIZEGIF=$(find . -type f \( -iname '*.gif' -o -iname '*.GIF' \) -printf '%s\n' | tee >(numgif=$(wc -l)) | awk '{SUM+=$1} END {print SUM}');
SIZEJPG=$(find . -type f \( -iname '*.JPG' -o -iname '*.jpg' -o -iname '*.jpeg' -o -iname '*.JPEG' \) -printf '%s\n' | tee >(numjpg=$(wc -l)) | awk '{SUM+=$1} END {print SUM}')
SIZE=$[SIZEPNG+SIZEGIF+SIZEJPG]

#Рабочая часть скрипта
export -f opt_optipng
find  -type f | cut -c 3- | grep -ie '.png$' | sort | parallel --no-notice opt_optipng '{}'
export -f opt_advpng
find  -type f | cut -c 3- | grep -ie '.png$' | sort | parallel --no-notice opt_advpng '{}'
export -f opt_advdef
find  -type f | cut -c 3- | grep -ie '.png$' | sort | parallel --no-notice opt_advdef '{}'
export -f opt_jpegtran
find  -type f | cut -c 3- | grep -e '.JPG$' -e '.jpg$' -e '.jpeg$' -e '.JPEG$' | sort | parallel --no-notice opt_jpegtran '{}'
export -f opt_gifsicle
find  -type f | cut -c 3- | grep -ie '.gif$' | parallel --no-notice opt_gifsicle '{}'

#Оформление информации для вывода
echo -e "\e[01;33mГотово!\e[00m"
SIZEPNG2=$(find . -type f \( -iname '*.png' -o -iname '*.PNG' \) -printf '%s\n' | awk '{SUM+=$1} END {print SUM}');
SIZEGIF2=$(find . -type f \( -iname '*.gif' -o -iname '*.GIF' \) -printf '%s\n' | awk '{SUM+=$1} END {print SUM}');
SIZEJPG2=$(find . -type f \( -iname '*.JPG' -o -iname '*.jpg' -o -iname '*.jpeg' -o -iname '*.JPEG' \) -printf '%s\n' | awk '{SUM+=$1} END {print SUM}')
SIZE2=$[SIZEPNG2+SIZEGIF2+SIZEJPG2]
if [ $SIZEPNG ]; then
PERCENTPNG=$[100-SIZEPNG2*100/SIZEPNG]
fi
if [ $SIZEGIF ]; then
PERCENTGIF=$[100-SIZEGIF2*100/SIZEGIF]
fi
if [ $SIZEJPG ]; then
PERCENTJPG=$[100-SIZEJPG2*100/SIZEJPG]
fi
if [ $SIZE ]; then
PERCENT=$[100-SIZE2*100/SIZE]
echo -e "Исходный размер всех обрабатываемых файлов был \e[01;31m$SIZE\e[00m байт а после обработки составил \e[01;31m$SIZE2\e[00m байт. Среднее сжатие на \e[01;31m$PERCENT%\e[00m
Из них:"
fi
if [ $SIZEPNG ]; then
echo -e "PNG: было: \e[01;31m$SIZEPNG\e[00m байт, стало \e[01;31m$SIZEPNG2\e[00m байт, сжалось на \e[01;31m$PERCENTPNG%\e[00m"
fi
if [ $SIZEGIF ]; then
echo -e "GIF: было: \e[01;31m$SIZEGIF\e[00m байт, стало \e[01;31m$SIZEGIF2\e[00m байт, сжалось на \e[01;31m$PERCENTGIF%\e[00m"
fi
if [ $SIZEJPG ]; then
echo -e "JPG: было: \e[01;31m$SIZEJPG\e[00m байт, стало \e[01;31m$SIZEJPG2\e[00m байт, сжалось на \e[01;31m$PERCENTJPG%\e[00m"
fi
Программы, используемые в функциях и GNU parallel поставь из репозитория.
PS
Про то что в скрипте есть говнокод в виде SIZEPNG2=$(find . -type f \( -iname '*.png' -o -iname '*.PNG' \) -printf '%s\n' | awk '{SUM+=$1} END {print SUM}'); я знаю, но мне лень исправлять это на более красивый вариант, т.к. работает и многократно использовалось.
« Последнее редактирование: 15 Февраля 2017, 13:41:05 от peregrine »

Оффлайн ReNzRv

  • Старожил
  • *
  • Сообщений: 2648
    • Просмотр профиля
К сожалению у меня несколько тысяч картинок
find -type f -iname '*.svg' | \
while read f ; do file="${f##*/}"; dir="${f%/*}"; \
convert "$f" -geometry 22x22 "${dir}/resized_${file}" && \
mv "${dir}/resized_${file}" "$f"; done

Оффлайн ase66

  • Автор темы
  • Участник
  • *
  • Сообщений: 156
    • Просмотр профиля
Скрипт от renzrv под convert сработал, но качество ужасающее. Всё размазано, искажены цвета, прозрачный фон стал белым. Похоже convertу это не по зубам.

К peregrine - мне оптимизация не особо нужна, optipng -o9 *.png решает все проблемы. А вот скрипт svgtopng.sh по сравнению с экспортом svg в png того же phatch, просто идеален. Особенно это заметно при экспорте из маленьких картинок в большие. Phatch их просто размазывает, а inkscape в этом скрипте масштабирует их очень чисто.

По поводу размеров иконок в svg - у меня все иконки 256х256, и я был уверен, что уж в низ то они масштабируются нормально.

Но тут мне указали на Evolution. Часть иконок, нормальных размеров, а часть прямо в одном окне, - 256х256!

Иконки из одной папки, т.е. ошибки в index.theme быть не может. Я даже эталонные иконки из профессиональных тем переименовал и подставил для проверки. И вот что выяснил. Оказывается, что иногда некоторым программам надо дать иконку фиксированного размера. По непонятным причинам они отказываются масштабировать svg или png. Хотя с другими программами проблем нет. Те же самые иконки нормально масштабируются, как в верх, так и вниз буквально повсюду.

Мне всё же хочется именно svg отресизеть, там много ссылок, а в png их придётся все заново писать. Это на несколько десятков часов лишней работы.

Оффлайн ReNzRv

  • Старожил
  • *
  • Сообщений: 2648
    • Просмотр профиля
convert сработал, но качество ужасающее. Всё размазано, искажены цвета, прозрачный
Читай man convert, там есть куча опций чтобы получить нужный результат ресайза.

Оффлайн ase66

  • Автор темы
  • Участник
  • *
  • Сообщений: 156
    • Просмотр профиля
Я уже ковырялся с convert, дело глухо. Очень тугая и грубая программа по отношению к svg.

Есть ещё скрипт svgscale. Но я не могу задать size, на 22х22 или 22px не реагирует. Может прямо в скрипт где прописать?

#!/bin/bash
size="$1"
which rsvg-convert > /dev/null 2>&1
if [[ ! $? -eq 0 ]]; then
    echo "rsvg-convert not installed."
    exit 1
elif [[ -z "$size" ]]; then
    echo "Please specify a size."
    exit 1
else
    rm -rf "$size"
    mkdir -p "$size"
    find . -maxdepth 1 -type f -name "*.svg" -print0 | while IFS= read -r -d '' file; do
        if [[ ! -h "$file" ]]; then
            comments=$(grep -o "<!--.*-->" "$file")
            rsvg-convert "$file" -w "$size" -h "$size" -f svg -o "$size/$file"
            sed -i -e "s/<[?]\?xml[^>]*>//g" -e "s/${size}pt/${size}px/g" -e "1s/^/${comments}/" "$size/$file"
        else
            cp -rdf "$file" "$size/"
        fi
    done
fi

Оффлайн ReNzRv

  • Старожил
  • *
  • Сообщений: 2648
    • Просмотр профиля
ase66,
В этом скрипте размер картинки указывается одним числом в первом аргументе скрипта:
bash script.sh 22

Оффлайн ase66

  • Автор темы
  • Участник
  • *
  • Сообщений: 156
    • Просмотр профиля
Скрипт работает быстро и чисто, но часть иконок 22х22, а часть 28х28. Все исходные строго 256х256. В терминале серия вот таких сообщений:

sed: -e выражение #3, символ 40: неизвестный модификатор к `s'
sed: -e выражение #3, символ 40: неизвестный модификатор к `s'
sed: -e выражение #3, символ 40: неизвестный модификатор к `s'

Повторное применение скрипта svgscale выровняло размеры, теперь все 22!
« Последнее редактирование: 16 Февраля 2017, 19:10:55 от ase66 »

 

Страница сгенерирована за 0.033 секунд. Запросов: 23.