Чтобы изменить плотность, чтобы изображение печаталось с указанным размером печати в дюймах

Следующий скрипт создает копию входного изображения и изменяет его плотность так, чтобы копия была напечатана с указанным размером печати в дюймах. Например, если у вас есть изображение размером 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

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
66
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Мне кажется, что в 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

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

Не могли бы вы объяснить, что вы имеете в виду? Входные изображения уже находятся в моем репозитории GitHub, и вы уже протестировали test3.png, не так ли? И я уже опубликовал тестовую команду, и она возвращает ту же плотность и размер печати для test3.png, что и ваш первый фрагмент, не так ли?

user25418595 03.07.2024 20:15

Вы сказали, что это не помогает создать желаемый вывод PrintSize = "2x3". Поэтому я не знаю точно, как вы создали входные данные такого размера, который ожидаете. Поэтому я попросил простую команду для тестирования и входные данные для этой команды. Я не хочу читать и пытаться понять ваш длинный набор кода. Итак, есть ли простая команда, которую вы можете показать, которая не работает, или вы можете объяснить, как вы создали ввод и установили его плотность в простой командной строке? То есть я получаю 4,44546x1,90321, а это не то, чего вы говорите, чего пытаетесь достичь, т. е. вам нужно меньше 2x3.

fmw42 03.07.2024 20:27

«Как создать минимальный воспроизводимый пример (stackoverflow.com/help/minimal-reproducible-example)

fmw42 03.07.2024 20:30

Ваша проблема может исходить из этой строки outputDensityX=$(( inputDensityX / outputPrintW * inputPrintW )). Плотность не рассчитывается по площади. Вы должны вычислить плотность отдельно для W и H или взять максимум или минимум двух результатов или, возможно, диагональное значение между двумя результатами. Итак outputDensityX=$(( inputDensityX / outputPrintW )) и аналогично для Y и H.

fmw42 03.07.2024 20:38
Ответ принят как подходящий

Ответ в том, что

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

Другие вопросы по теме