Спасибо @WumpusQ.Wumbley за то, что указал мне правильное направление.
TL;DR:Используйте -type TrueColor
для удаления цветовых карт либо из типов палитры изображений псевдокласса.
Читая форумы IM, я, наконец, (больше -или -меньше )понял, что такое карта цветов в изображении и как с ней работать. Прежде всего, есть разница между DirectClass и PseudoClass :
.
Это было источником моего замешательства:Псевдокласс не является цветовой картой , это разные вещи. И поскольку IM почти всегда преобразует изображение PseudoClass в изображение DirectClass, я был сбит с толку.
Major operations involving image modifications would generally upgrade PsuedoColor images (images using a color table) to a DirectColor (images using separate color values for every pixel) before the operation is applied.
источник (P.S. DirectClass и PseudoClass являются синонимами DirectColor и PseudoColor )
.
Цветовая карта представляет собой индекс цветов по отношению к палитре, которая хранится в изображении. Это очень похоже на Псевдокласс , поскольку он также является таблицей цветов, разница в том, что Псевдокласс будет включать только цвета, присутствующие в изображении, и цветовая карта будет включать все цвета палитры. Обратите внимание, что псевдокласс будет иметь раздел палитры , но это будет таблица цветов псевдокласса , а не тип палитры (. да, это очень сбивает с толку IM ).
Цветовая карта определяется опцией -type
для IM:
-type type
the image type.
Choose from: Bilevel, Grayscale, GrayscaleMatte,
Palette, PaletteMatte, TrueColor, TrueColorMatte,
ColorSeparation, or ColorSeparationMatte.
Normally, when a format supports different subformats such
as grayscale and truecolor, the encoder will try to choose an
efficient subformat. The -type option can be used to override
this behavior. For example, to prevent a JPEG from being written
in grayscale format even though only gray pixels are present, use.
convert bird.png -type TrueColor bird.jpg
Similarly, use -type TrueColorMatte to force the encoder to write
an alpha channel even though the image is opaque, if the output
format supports transparency.
Use -type optimize to ensure the image is written in the
smallest possible file size.
Обратите внимание, что тип отличается от цветового пространства . Большинство изображений будут иметь аналогичный тип и цветовое пространство , например. Type: Grayscale
и Colorspace: Gray
, но это не обязательно. Изображение (в вопросе ), которое было загружено на мой сервер, имело отдельный тип и цветовое пространство .
Типы от человека выше можно понимать как:
Примечание. :По современным стандартам разница между записью изображения в градациях серого в цветовом пространстве sRGB или в цветовом пространстве Серый должна быть почти незначительной. (И использование обычного RGB вместо sRGB также было бы незначительным, и изображение часто отображалось бы плохо. Не используйте обычный RGB, используйте sRGB.)
Теперь мы можем объяснить решения, принятые IM, и можем утверждать, что виноват image1.png , а не IM. Давайте еще раз посмотрим на изображения:
[grochmal@phoenix so]$ identify -verbose image1.png | grep -A 3 -e 'Color\|Type\|Class'
Class: DirectClass
Geometry: 95x74+0+0
Resolution: 28.35x28.35
Print size: 3.35097x2.61023
--
Type: PaletteAlpha
Endianess: Undefined
Colorspace: sRGB
Depth: 8-bit
Channel depth:
red: 8-bit
--
Colors: 96
Histogram:
1357: (217,217,217,255) #D9D9D9FF grey85
16: (217,217,218,255) #D9D9DAFF srgba(217,217,218,1)
[grochmal@phoenix so]$ identify -verbose image2.png | grep -A 3 -e 'Color\|Type\|Class'
Class: DirectClass
Geometry: 69x102+0+0
Resolution: 28.35x28.35
Print size: 2.43386x3.59788
--
Type: GrayscaleAlpha
Endianess: Undefined
Colorspace: sRGB
Depth: 8-bit
Channel depth:
gray: 8-bit
--
Colors: 188
Histogram:
1: ( 26, 26, 26,255) #1A1A1AFF graya(26,1)
1: ( 35, 35, 35,255) #232323FF graya(35,1)
Мы видим, что image1.png имеет тип PaletteAlpha
(Или PaletteMatte
в терминах IM ), а image2 имеет тип GrayscaleAlpha
.
Тот факт, что image1.png не имеет цветовой карты , совершенно неверен. Таким образом, средство записи изображений с ошибками должно было записать это изображение как имеющее цветовую карту , но не записывающее цветовую карту в изображение.
Когда IM видит, что изображение должно иметь цветовую карту , он присваивает ее, вероятно, на основе предположения. Предполагается, что цветовая карта оттенков серого добавляется во время преобразования.
(См. вопрос, чтобы увидеть результат преобразования изображений -)
К счастью, мы можем помочь IM, сказав ему, что мы не хотим сохранять или угадывать тип изображения. Нам просто нужно изображение, которое будет использовать цвета из стандартной палитры (sRGB или серого цвета для наших целей )вместо палитры, которой у нас все равно нет (, поскольку средство записи изображений с ошибками не записало их в изображение. ).
Мы используем-type TrueColor
:
[grochmal@phoenix so]$ convert image1.png -strip -quality 80 -type TrueColor image1.jpg
[grochmal@phoenix so]$ convert image2.png -strip -quality 80 -type TrueColor image2.jpg
И изображения получаются такими, как мы ожидаем:
[grochmal@phoenix so]$ identify -verbose image1.jpg | grep -A 3 -e 'Color\|Type\|Class'
Class: DirectClass
Geometry: 95x74+0+0
Resolution: 28x28
Print size: 3.39286x2.64286
--
Type: Grayscale
Endianess: Undefined
Colorspace: sRGB
Depth: 8-bit
Channel depth:
gray: 8-bit
--
Colors: 37
Histogram:
1520: (217,217,217) #D9D9D9 gray(217)
95: (219,219,219) #DBDBDB gray(219)
[grochmal@phoenix so]$ identify -verbose image2.jpg | grep -A 3 -e 'Color\|Type\|Class'
Class: DirectClass
Geometry: 69x102+0+0
Resolution: 28x28
Print size: 2.46429x3.64286
--
Type: Grayscale
Endianess: Undefined
Colorspace: sRGB
Depth: 8-bit
Channel depth:
gray: 8-bit
--
Colors: 195
Histogram:
1: ( 14, 14, 14) #0E0E0E gray(14)
1: ( 37, 37, 37) #252525 gray(37)
Обратите внимание, что IM выяснил, что изображения используют оттенки серого пикселей, и выдал изображение DirectClass,Grayscale,sRGB , которое, вероятно, будет тем, что нам нужно почти во всех случаях.
Если вы вместо этого используете -type Grayscale
, вы получите изображение PseudoClass,Graysclae,Gray , которое может сэкономить вам несколько байт (, возможно, 10 -20 КБ на типичном веб-изображении 100 -500k )за счет менее совместимого формата. Например, мой pygtk
иногда блюет на изображениях PseudoClass , я думаю, отсутствие обратной совместимости.
Возможно, вы захотите реализовать свою стратегию переименования самостоятельно, так как код, который вы просматриваете, явно -занижает имена файлов в вызове mv
для обнаружения дубликатов в реальных конфликтах имен файлов.
Следующее переименовывает файлы только при наличии коллизий, фактически не вызывая коллизий (, т. е. не обращается к GNU mv
для обработки коллизий):
#!/bin/bash
# The suffix array contains a filename suffix (a positive integer)
# for each lower-cased filename.
declare -A suffix
# Get all names in the current directory.
set -- *
# Initialise the suffixes for each existing name to zero.
for name do
suffix[${name,,}]=0
done
for name do
# Loop until no name collision.
while true; do
# Get the current suffix for this filename.
suf=${suffix[${name,,}]}
# Increment the suffix for this filename.
suffix[${name,,}]=$(( ${suffix[${name,,}]} + 1 ))
# If the suffix is 0, empty it.
[[ $suf == 0 ]] && suf=
# Create the new name.
newname=$name$suf
# Break out of the loop if the name didn't change, or if
# there's no other file that has this name.
if [[ $name == "$newname" ]] ||
[[ -z ${suffix[${newname,,}]} ]]
then
break
fi
done
if [[ $name != "$newname" ]]; then
printf '%s --> %s\n' "$name" "$newname"
# uncomment the next line to actually do the renaming
# mv -- "$name" "$newname"
else
printf '%s unchanged\n' "$name"
fi
done
(обратите внимание на закомментированный mv
, вы можете запускать это с закомментированной строкой, пока не будете уверены, что она работает правильно)
Тестирование:
$ ls
A Bb TEST1 a bb test
BB TEST Test bB script.sh
$ bash script.sh
A unchanged
BB unchanged
Bb --> Bb1
TEST unchanged
TEST1 unchanged
Test --> Test2
a --> a1
bB --> bB2
bb --> bb3
script.sh unchanged
test --> test3