Пакетное переименование «дубликатов регистров»

Спасибо @WumpusQ.Wumbley за то, что указал мне правильное направление.

TL;DR:Используйте -type TrueColorдля удаления цветовых карт либо из типов палитры изображений псевдокласса.

Карта цветов не является псевдоклассом

Читая форумы IM, я, наконец, (больше -или -меньше )понял, что такое карта цветов в изображении и как с ней работать. Прежде всего, есть разница между DirectClass и PseudoClass :

.

  • Класс DirectClass хранит значения цвета для каждого пикселя.
  • Псевдокласс использует таблицу цветов, а затем сохраняет смещения в этой таблице.

Это было источником моего замешательства:Псевдокласс не является цветовой картой , это разные вещи. И поскольку 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, но это не обязательно. Изображение (в вопросе ), которое было загружено на мой сервер, имело отдельный тип и цветовое пространство .

Типы от человека выше можно понимать как:

  • Bilevel:Черно-белый (Не думаю, что кто-то до сих пор этим пользуется)
  • Оттенки серого:0 -255 — оттенки серого
  • Палитра:Использует карту цветов, присутствующую в изображении
  • TrueColor:Использует одну из стандартных цветовых схем (сегодня, скорее всего, sRGB)
  • ColorSeparation:Не уверен, но я думаю, что он хранит каналы отдельно
  • |один из вышеперечисленных|Matte:Форсирует существование альфа-канала.

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

1
07.11.2019, 11:04
1 ответ

Возможно, вы захотите реализовать свою стратегию переименования самостоятельно, так как код, который вы просматриваете, явно -занижает имена файлов в вызове 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
1
27.01.2020, 23:40

Теги

Похожие вопросы