Imagemagick - как получить самый большой слой и сжать? - PullRequest
2 голосов
/ 22 апреля 2019

Пожалуйста, помогите. Есть ли простой способ взять самый большой слой tiff и сжать его обратно как однослойный tiff снова с помощью imagemagick или аналогичного?

Ответы [ 3 ]

3 голосов
/ 22 апреля 2019

Просто немного более легкая версия ответа Фреда. Вы можете создать список областей (в пикселях) каждого слоя в формате TIF, за которым следует номер слоя / сцены, например:

magick identify -format "%[fx:w*h] %s\n" image.tif

Пример вывода

240000 0
560000 1
200000 2

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

layer=$(magick identify -format "%[fx:w*h] %s\n" image.tif | sort -rn | awk 'NR==1{print $2}')

Итак, полное решение будет выглядеть так:

#!/bin/bash

# Get layer number of layer with largest area
layer=$(magick identify -format "%[fx:w*h] %s\n" image.tif | sort -rn | awk 'NR==1{print $2}')

# Extract that layer and recompress as single layer
magick image.tif[$layer] -compress lzw result.tif

Если вы используете ImageMagick v6 или старше:

  • magick identify ... становится identify ...
  • magick image.tif ... становится convert image.tif ...
3 голосов
/ 23 апреля 2019

В принципе, используя ImageMagick, это можно сделать одной командой.Вот пример ...

magick input.tif -background none -virtual-pixel none ^
   ( -clone 0--1 +repage -layers merge ) ^
   -distort affine "0,0 0,%[fx:s.w==u[-1].w&&s.h==u[-1].h?0:h]" ^
   -delete -1 -layers merge output.tif

Это начинается с чтения в оригинальном TIF и установки фона и настроек виртуального пикселя на "none".

Затем в скобках он клонирует всеслои TIF, повторяет их и объединяет их в одно изображение с размерами самого большого слоя.Это станет мерой для измерения.

Затем он использует «-distort affine», чтобы выдвинуть каждое изображение из области просмотра и оставить его прозрачным , если изображение не соответствует ширине и высотеэтот датчик.Таким образом, после этого искажения самое большое изображение останется неизменным, а все остальные будут прозрачными.

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

Команда в синтаксисе Windows использует IM7.Если вы используете ImageMagick v6, используйте «convert» вместо «magick».Чтобы это работало в * nix, измените символы продолжения строки «^» на обратную косую черту «\» и уберите круглые скобки с обратной косой чертой «\ (... \)».Могут быть и другие проблемы, которые я упустил из виду.

Очевидно, что если два или более слоев соответствуют наибольшим размерам, выходной результат будет только первым из исходного TIF.

Отредактированодобавить: этот метод будет работать, только если наибольшая ширина и наибольшая высота находятся на одном изображении.

1 голос
/ 22 апреля 2019

Как вы определяете наибольший? Ширина, Высота, Размер файла? Если используется наибольшее измерение по ширине и высоте, то в Unix вы можете сделать следующее для трехслойного файла TIF. Получите максимальный размер каждого слоя. Затем найдите, какой слой является самым большим. Затем используйте только этот слой при чтении и записи файла.

Arr=(`identify -format "%[fx:max(w,h)]\n" img.tif`)
echo "${Arr[*]}"
500 1024 770

num=${#Arr[*]}
dim=0
for ((i=0; i<num; i++)); do
if [ ${Arr[$i]} > $dim ]; then
dim=${Arr[$i]}
index=$i
fi
done
echo "$index"
2

convert img.tif[$index] -compress zip newimg.tif
identify newimg.tif
newimg.tif[2] TIFF 770x768 770x768+0+0 8-bit sRGB 3662B 0.000u 0:00.000

Я не могу придумать какой-либо прямой и простой способ найти самый большой слой и извлечь его в той же командной строке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...