Следующий скрипт создает копию входного изображения и изменяет его плотность так, чтобы копия была напечатана с указанным размером печати в дюймах. Например, если у вас есть изображение размером 100x200 пикселей и вы хотите, чтобы оно было напечатано так, чтобы оно поместилось в коробку размером 2x3 дюйма, вам нужно указать outputPrintSize = "2x3"
, а затем запустить script.sh input.jpg output.jpg
.
outputPrintSize = "2x3" # In inches. E. g., 1x2, 1x, or x2.
# Currently, both width and height must be specified
IFS='x' read -rA ADDR <<< "$outputPrintSize"
outputPrintW=${ADDR[1]}
outputPrintH=${ADDR[2]}
units=$(magick identify -format %U $1)
if [[ $units = "Undefined" ]]; then
input=$(mktemp ./$1~)
cp $1 $input
inputDensity=$( magick identify -format %xx%y $input )
magick $input -units PixelsPerInch -density $inputDensity $input
else
input=$1
fi
inputPrintW=$(magick identify -format "%[fx:w/resolution.x]" $input)
inputPrintH=$(magick identify -format "%[fx:h/resolution.y]" $input)
if [[ $inputPrintW -gt $inputPrintH ]]; then
inputDensityX=$(magick identify -format %x $input)
# https://math.stackexchange.com/q/4936540
outputDensityX=$(( inputDensityX / outputPrintW * inputPrintW ))
magick $input -units PixelsPerInch -density $outputDensityX $2
else
inputDensityY=$(magick identify -format %y $input)
outputDensityY=$(( inputDensityY / outputPrintH * inputPrintH ))
magick $input -units PixelsPerInch -density $outputDensityY $2
fi
if [[ $units = "Undefined" ]]; then rm $input; fi
Проблема, которую я пытаюсь решить, заключается в том, что в некоторых случаях плотность выходного файла и, следовательно, размер его печати неверны: поскольку outputPrintSize = "2x3"
ширина печати не должна превышать 2 дюйма, а высота печати не должна превышать 3 дюйма. Почему это так?
Тестовая команда:
magick identify -format "density: %xx%y-%U\nprint size: %[fx:w/resolution.x]x%[fx:h/resolution.y]" $TestFile
Полученные результаты:
| input file | output file | works correctly? |
|-------------------------|-------------------------|------------------|
| test1.jpg | test1_.jpg | yes |
| 72x72-PixelsPerInch | 159x159-PixelsPerInch | |
| 4.44444x1.90278 | 2.01258x0.861635 | |
|- - - - - - - - - - - - -| - - - - - - - - - - - - |- - - - - - - - - |
| test2.jpg | test2_.jpg | yes |
| 72x72-PixelsPerInch | 106x106-PixelsPerInch | |
| 1.90278x4.44444 | 1.29245x3.01887 | |
|- - - - - - - - - - - - -| - - - - - - - - - - - - |- - - - - - - - - |
| test3.png | test3_.png | no |
| 28.34x28.34-PixelsPerCm | 62.99x62.99-PixelsPerCm | |
| 11.2915x4.83416 | 5.08017x2.1749 | |
|- - - - - - - - - - - - -| - - - - - - - - - - - - |- - - - - - - - - |
| test4.png | test4_.png | no |
| 72x72-Undefined | 62.99x62.99-PixelsPerCm | |
| 3.2e+14x1.37e+14 | 5.08017x2.17495 | |
|- - - - - - - - - - - - -| - - - - - - - - - - - - |- - - - - - - - - |
| test5.jpg | test5_.jpg | yes |
| 72x72-Undefined | 16x16-PixelsPerInch | |
| 4.8e+13x4.8e+13 | 3x3 | |
|- - - - - - - - - - - - -| - - - - - - - - - - - - |- - - - - - - - - |
Тестовые файлы: https://github.com/jsx97/test/blob/main/density.zip
ImageMagick 7.1.1
Мне кажется, что в Imagemagick это соответствует размеру вашего ввода. Я добавил альтернативные методы расчета размера отпечатка (в сантиметрах). Если вы хотите перевести его в дюймы, разделите на 2,54.
В сантиметрах:
magick identify -format "size: %wx%h\ndensity: %xx%y\ndensity: %[resolution.x]x%[resolution.y]\nunits: %U\nprint size (cm): %[fx:w/resolution.x]x%[fx:h/resolution.y]\nprint size (cm): %[printsize.x]x%[printsize.y]\n" test3.png
size: 320x137
density: 28.339999999999999858x28.339999999999999858
density: 28.34x28.34
units: PixelsPerCentimeter
print size (cm): 11.2915x4.83416
print size (cm): 11.2915x4.83416
В дюймах:
magick identify -format "size: %wx%h\ndensity: %xx%y\ndensity: %[resolution.x]x%[resolution.y]\nunits: %U\nprint size (in): %[fx:(w/resolution.x)/2.54]x%[fx:(h/resolution.y)/2.54]\nprint size (in): %[fx:printsize.x/2.54]x%[fx:printsize.y/2.54]\n" test3.png
size: 320x137
density: 28.339999999999999858x28.339999999999999858
density: 28.34x28.34
units: PixelsPerCentimeter
print size (in): 4.44546x1.90321
print size (in): 4.44546x1.90321
Можете ли вы дать простую команду, чтобы я мог проверить, как вы вычислили входной размер, плотность и используемые вами единицы измерения? Также входное изображение.
Вы сказали, что это не помогает создать желаемый вывод PrintSize = "2x3". Поэтому я не знаю точно, как вы создали входные данные такого размера, который ожидаете. Поэтому я попросил простую команду для тестирования и входные данные для этой команды. Я не хочу читать и пытаться понять ваш длинный набор кода. Итак, есть ли простая команда, которую вы можете показать, которая не работает, или вы можете объяснить, как вы создали ввод и установили его плотность в простой командной строке? То есть я получаю 4,44546x1,90321, а это не то, чего вы говорите, чего пытаетесь достичь, т. е. вам нужно меньше 2x3.
«Как создать минимальный воспроизводимый пример (stackoverflow.com/help/minimal-reproducible-example)
Ваша проблема может исходить из этой строки outputDensityX=$(( inputDensityX / outputPrintW * inputPrintW ))
. Плотность не рассчитывается по площади. Вы должны вычислить плотность отдельно для W и H или взять максимум или минимум двух результатов или, возможно, диагональное значение между двумя результатами. Итак outputDensityX=$(( inputDensityX / outputPrintW ))
и аналогично для Y и H.
Ответ в том, что
inputPrintW=$(magick identify -format "%[fx:w/resolution.x]" $input)
inputPrintH=$(magick identify -format "%[fx:h/resolution.y]" $input)
следует заменить на
if [[ $(magick identify -format %m $input) == PNG ]]; then
inputPrintW=$(magick identify -format "%[fx:(w/resolution.x)*2.54]" $input)
inputPrintH=$(magick identify -format "%[fx:(h/resolution.y)*2.54]" $input)
else
inputPrintW=$(magick identify -format "%[fx:w/resolution.x]" $input)
inputPrintH=$(magick identify -format "%[fx:h/resolution.y]" $input)
fi
Полная версия; у меня отлично работает:
outputPrintSize=2x3 # In inches. E. g., 1x2, 1x, or x2.
# Currently, both width and height must be specified
# -----------------------
IFS=x read -rA ADDR <<< $outputPrintSize
outputPrintW=${ADDR[1]}
outputPrintH=${ADDR[2]}
units=$(magick identify -format %U $1)
if [[ $units == Undefined ]]; then
input=$(mktemp ./$1~)
cp $1 $input
inputDensity=$(magick identify -format %xx%y $input)
magick $input -units PixelsPerInch -density $inputDensity $input
else
input=$1
fi
if [[ $(magick identify -format %m $input) == PNG ]]; then
inputPrintW=$(magick identify -format "%[fx:(w/resolution.x)*2.54]" $input)
inputPrintH=$(magick identify -format "%[fx:(h/resolution.y)*2.54]" $input)
else
inputPrintW=$(magick identify -format "%[fx:w/resolution.x]" $input)
inputPrintH=$(magick identify -format "%[fx:h/resolution.y]" $input)
fi
if [[ $inputPrintW -gt $inputPrintH ]]; then
inputDensityX=$(magick identify -format %x $input)
outputDensityX=$(( inputDensityX / outputPrintW * inputPrintW ))
magick $input -units PixelsPerInch -density $outputDensityX $2
else
inputDensityY=$(magick identify -format %y $input)
outputDensityY=$(( inputDensityY / outputPrintH * inputPrintH ))
magick $input -units PixelsPerInch -density $outputDensityY $2
fi
# To test whether the script works properly
magick identify -format "%[fx:w/resolution.x]x%[fx:h/resolution.y]" $2
if [[ $units == Undefined ]]; then rm $input; fi
Не могли бы вы объяснить, что вы имеете в виду? Входные изображения уже находятся в моем репозитории GitHub, и вы уже протестировали
test3.png
, не так ли? И я уже опубликовал тестовую команду, и она возвращает ту же плотность и размер печати дляtest3.png
, что и ваш первый фрагмент, не так ли?