Bir komut dosyasıyla JPEG ve PNG arasındaki seçimi otomatikleştirme


4

Görüntülerinizi kaydetmek için doğru formatı seçmek, görüntü kalitesini korumak ve eserleri azaltmak için çok önemlidir. Farklı formatlar farklı sıkıştırma yöntemlerini takip eder ve kendi avantajları ve dezavantajları ile birlikte gelir.

Örneğin JPG, renk gradyanları bakımından zengin gerçek yaşam fotoğrafları için uygundur. Kayıpsız PNG ise şematik rakamlara gelince çok daha üstün:

enter image description here

Çok sayıda dosyayla çalışırken doğru formatı seçmek bir angarya olabilir. Bu yüzden onu otomatikleştirmenin bir yolunu bulmayı çok isterim.


Özel kullanım durumumla ilgili biraz arka plan:

Üniversitemdeki bir dizi konferans için çok sayıda çalışma üzerinde çalışıyorum. Ders notları, PDF formatındaki slaytlardan çıkarmam gereken rakamlar bakımından zengindir. Bu görüntüleri çıkarmak, zaman zaman gereksiz yere büyük olan kayıpsız PNG'ler veriyor.

Bu belirli dosyaları JPEG'e dönüştürmek, aynı kaliteyi korurken, boyutlarını orijinal dosya boyutlarının% 20'sine kadar küçültebilir. Kelime işlemcilerde yüzlerce büyük resimle çalışmak, çarpışma eğilimli olduğu için bu önemlidir.

Tüm çıkarılan PNG'leri JPEG'lere dönüştürme toplu çoğu resim PNG olarak biçimlendirilmeye daha uygun değilse, izlemeye istekli olduğum bir seçenek değil. Bunları dönüştürmek önemsiz boyut küçültmelerine ve bazen dosya boyutunda da artışlara yol açacaktır - en azından testimin gösterdiği şey buydu.


Bundan alabileceğimiz, sıkıştırma işleminden sonraki dosya boyutunun, belirli bir görüntü için hangi formatın en uygun olduğuna dair bir gösterge olabileceğidir. Bu özellikle kesin bir tahmin değil, ancak yeterince iyi çalışıyor. Öyleyse neden bir senaryo şeklinde kullanmıyorsunuz:

enter image description here

Dahil ettim inotifywait Çünkü çıkartılmış bir görüntüyü bir klasöre sürüklersem komut dosyasının otomatik olarak çalıştırılmasını tercih ederim.

Bu, son birkaç haftadır kullandığım betiğin daha basit bir versiyonudur:

#!/bin/bash
inotifywait -m --format "%w%f" --exclude '.jpg' -r -e create -e moved_to --fromfile '/home/MHC/.scripts/Workflow/Conversion/include_inotifywait' | while read file; do mogrify -format jpg -quality 92 "$file"
done

Komut dosyasının ileri sürümünün

  • Dosya isimlerinde ve dizin isimlerinde boşluk kullanabilme
  • orijinal dosya adlarını koru
  • bir alfa değeri ayarlanmışsa PNG görüntülerini düzleştir
  • Geçici olarak dönüştürülen görüntü ile orijinal arasındaki dosya boyutunu karşılaştır
  • farkın belirli bir yüzdeden büyük olup olmadığını belirleyin
  • uygun davran

Gerçek dönüşüm, imagemagick araçlarıyla yapılabilir:

convert -quality 92 -flatten -background white file.png file.jpg

Maalesef, bash becerilerim yukarıdaki şemayı gerçek bir betiğe dönüştürecek kadar gelişmiş bile değil, ama çoğunuzun yapabileceğinden eminim.

Buradaki itibar puanlarım oldukça düşük, ancak memnuniyetle belirleyebileceğim en yüksek ödülle en yararlı cevabı vereceğim.

Referanslar: http://www.formortals.com/introducing-cnb-imageguide/ , http://www.turnkeylinux.org/blog/png-vs-jpg

Düzenle : Ayrıca, bu betiğin neden karşılaştığım soruna en iyi çözüm olacağını düşündüğüm hakkında daha fazla bilgi için aşağıdaki yorumlarıma bakınız.


Bir uzman değil, sağlıklı bir sodyum klorür dozu ile söylediklerimi alın: PNG'nin fotoğraflarla başa çıkma yeteneğini hafife alıyor olabilirsiniz. Gösterdiğiniz degrade sorunları, biçimin kendine özgü bir özelliği değil, bir yazılım eseri gibi görünüyor. Ayrıca kullanmayı düşünebilirsiniz JPEG 2000 , JPEG'in bazı eksikliklerini gideren bir format.
Isaac Rabinovitch

@IsaacRabinovitch Kesinlikle haklısın, görüntü karşılaştırması yanıltıcı olabilir. Kalite sorunları JPG dosyalarıyla sınırlıdır. PNG'de biçimlendirilmiş fotoğraflar mükemmel bir şekilde ince ve herhangi bir yapaylık oluşturmaz fakat JPG emsallerinden önemli ölçüde daha büyüktür. Bu gereksiz ek boyut ortadan kaldırmak için çalışıyorum. JPEG2000'i neden düşünmedim diye, LibreOffice tarafından desteklenmiyor, bu benim için vazgeçilmez kılıyor (gerçekten de oldukça iyi bir format gibi görünse de).
Glutanimate

Yanıtlar:


1

PDF'ler hem kayıpsız kodlamaları hem de JPEG kodlamasını destekler. (JPEG 2000 de.) Görüntü verilerini doğrudan PDF'den çıkaran ve olduğu gibi bırakan bir araç isteyebilirsiniz. Pdfimages'den XPDF paketi , bunu yapacağım.

ImageMagick aslında tüm sayfayı oluşturacak ve ayıklayacaktır. Bu, zaten PDF'de depolanan kodlama seçimini atar ve bu görevi yapmanın en iyi yolu değildir.


Görüntüleri nasıl çıkardığımı açıklığa kavuşturmalıydım. Her slayt setinde verilenlerin yalnızca birkaç figürünü kullanmaya meyilli olduğum için hepsini bir kerede çıkarmak pratik olmaz. Bu yüzden evince (Ubuntu'daki varsayılan PDF görüntüleyici) istediğim dosyaları kendi klasörlerine sürükleyip bırakmak için kullanıyorum. Oradan onları düzenlediğim belgelere gömüyorum. Evince, PNG'yi yalnızca bir dezavantaj olan görüntüleri kaydetmek için kullanır. Az önce XPDF'yi birkaç belge ile denedim. ama kesin olarak kırılmış gibi görünüyor
Glutanimate

Ancak, tüm gömülü görüntüleri orijinal biçiminde çıkaran bir PDF görüntüleyici bulsam bile, gömülü biçimin doğru olduğunun garantisi olmazdı. Belge boyutunu küçültmek istesem yine de her dosyadan geçip doğru formatta olup olmadığına karar vermem gerekirdi.
Glutanimate

Tüm görüntüleri çıkarmanın pratik olmadığını, ardından bunları başka bir programda sıraladığınızdan emin misiniz? Xpdf sizin için çalışmıyor olsa bile, pdfimages (xpdf-utils paketinde bulunur) olabilir. Hangi PDF'yi oluşturduğuna bağlı olarak, PDF'deki sıkıştırmanın iyi bir olasılık olması muhtemeldir. Ancak, renk sayısına göre en iyi formatı belirlemenin bir yolu olabilir. (Ya da, her ikisini de sıkıştırmak ve hangisinin daha büyük olduğunu, hangisinin öneriniz olduğunu bulmak için bir komut dosyası yazın.)
Alan Shutko

Ortalama bir ölçekte, her bir slayt setinde görüntülerin yaklaşık% 10'unu kullandığımı söyleyebilirim. Bu yüzden, çıkarılan tüm görüntüleri sonradan sıralamak çok pratik değildir. PDF görüntü ayıklama, arka plan ve çerçeve gibi görüntü olmayan öğeleri de görüntüler olarak yorumlamaya meyillidir ve bu da bu görevi daha da zorlaştırır.
Glutanimate

Ben de bazı testler ile yaptım pdfimages (ile -j parametre seti ). ~ 300 görüntüden sadece 2 tanesi jpeg olarak kabul edildi. Geri kalan her şey, bmp formatına benzer (kayıpsız, sıkıştırılmamış) ppm olarak kaydedilmiştir. Önerdiğim betiğin bir diğer avantajı da, PDF rakamlarını çıkarması veya indirilmiş dosyaları olması, tüm görüntü kaynaklarıyla uyumlu olması. Ama yine de teşekkürler!
Glutanimate

1

Düzenle: Orijinal komut dosyasıyla ilgili bazı sorunlar giderildi. Marcks Thomas'ın önerisine dayanarak alternatif bir tane daha ekledi.

Düzenle 2 : Bir dizi değere göre güncellenmiş kesme değerleri test çalışmaları . Gri tonlamalı resimler için dosya boyutlarını nasıl tahmin edeceğimi hala bilmiyorum. RGB renk şemaları dışında çok sayıda görüntüyle çalışıyorsanız, ilk komut dosyasını ikincisine bir geri dönüş modu olarak uygulamak isteyebilirsiniz.

Düzenle 3 : Katma optipng entegrasyon. Bu, PNG dosya boyutlarını kalite kaybı olmadan optimize eder. Görmek İşte daha fazla bilgi için. Bazı küçük iyileştirmeler.


Sürüm 0.1

Önemli Not : Bu komut dosyası kullanımdan kaldırıldı. Yeni sürümler çok daha verimli.

Tamam, sorum biraz fazla yerelleştirilmiş olabilir, bu yüzden biraz zaman harcadım ve senaryoyu kendim hazırladım:

#!/bin/bash

# AUTHOR:   (c) MHC (http://askubuntu.com/users/81372/mhc)
# NAME:     Intelliconvert 0.1
# DESCRIPTION:  A script to automate and optimize the choice between different image formats.
# LICENSE:  GNU GPL v3 (http://www.gnu.org/licenses/gpl.html)
# REQUIREMENTS:  Imagemagick

ORIGINAL="$1"

###Filetype check###

MIME=$(file -ib "$ORIGINAL")

if [ "$MIME" = "image/png; charset=binary" ]
  then
    echo "PNG Mode"

###Variables###

      ##Original Image##
    FILENAME=$(basename "$ORIGINAL")
    PARENTDIR=$(dirname "$ORIGINAL")
        SUBFOLDER=$(echo "$PARENTDIR" | cut -d"/" -f10-)
    ORIGARCHIVE="~/ORIG"

      ##Converted Image##
    TEMPDIR="/tmp/imgcomp"
    CONVERTED="$TEMPDIR/$FILENAME.jpg"

      ##Image comparison##
    DIFFLO="50"
    DIFFHI="75"
    CUTOFF="1000000"

      ##DEBUG
    echo "#### SETTINGS ####"
    echo "Filepath to original = $ORIGINAL"
    echo "Filename= $FILENAME"
    echo "Parent directory = $PARENTDIR"
    echo "Archive directory = $ORIGARCHIVE"
    echo "Temporary directory = $TEMPDIR"
    echo "Filepath to converted image = $CONVERTED"
    echo "Low cut-off = $DIFFLO"
    echo "High cut-off = $DIFFHI"

###Conversion###

    convert -quality 92 -flatten -background white "$ORIGINAL" "$CONVERTED"

###Comparison###

    F1=$(stat -c%s "$ORIGINAL" )
    F2=$(stat -c%s "$CONVERTED" )
    FQ=$(echo "($F2*100/$F1)" | bc)

      #Depending on filesize we use a different Cut-off#
    if [ "$F1" -ge "$CUTOFF" ]
      then
        DIFF="$DIFFHI"
      else  
        DIFF="$DIFFLO"
    fi

      ##DEBUG
    echo "### COMPARISON ###"
    echo "Filesize original = $F1 Bytes"
    echo "Filesize converted = $F2 Bytes"
    echo "Chosen cut-off = $DIFF %"
    echo "Actual Ratio = $FQ %"


    if [ "$FQ" -le "$DIFF" ]
      then
           echo "JPEG is more efficient, converting..."
           mv -v "$CONVERTED" "$PARENTDIR"
               mkdir -p "$ORIGARCHIVE/$SUBFOLDER"
           mv -v "$ORIGINAL" "$ORIGARCHIVE/$SUBFOLDER"
      else
           echo "PNG is fine, exiting."
           rm -v "$CONVERTED"
    fi


  else
    echo "File does not exist or unknown MIME type, exiting."

fi

Komut ile birlikte harika çalışıyor bakıcı .

Bu benim ilk uygun betiğim, bu yüzden henüz çözemediğim bazı çözülmüş hatalar ve sorunlar olabilir. Kendiniz için kullanmaktan ve geliştirmek için çekinmeyin. Bunu yaparsanız, burada bir yorum yapıp, öğrenebilmem için teşekkür ederim.


Sürüm 0.2.1

Orijinalin dosya boyutu ile karşılaştırılarak doğru formatı bulmanın daha etkili bir yolu sağlanabilir. sıkıştırılmamış bir resim olarak tahmini boyut :

#!/bin/bash

# AUTHOR:   (c) MHC (http://askubuntu.com/users/81372/mhc)
# NAME:     Intelliconvert 0.2.1
# DESCRIPTION:  A script to automate and optimize the choice between different image formats.
# LICENSE:  GNU GPL v3 (http://www.gnu.org/licenses/gpl.html)
# REQUIREMENTS:  Imagemagick, Optipng

################ Filetype Check#################

MIME=$(file -ib "$1")

if [ "$MIME" = "image/png; charset=binary" ]
  then
    echo "###PNG Mode###"

####################Settings####################

##Folders##
ORIGARCHIVE="~/ORIG"

##Comparison##
DIFFLO="25"
DIFFHI="20"
CUTOFF="1000000"

################################################

###Variables###

ORIGINAL="$1"
FILENAME=$(basename "$ORIGINAL")
PARENTDIR=$(dirname "$ORIGINAL")
SUBFOLDER=$(echo "$PARENTDIR" | cut -d"/" -f10-)
CONVERTED="$PARENTDIR/$FILENAME.jpg"

#DEBUG#
    echo "###SETTINGS###"
    echo "Filepath to original = $ORIGINAL"
    echo "Filename= $FILENAME"
    echo "Parent directory = $PARENTDIR"
    echo "Archive directory = $ORIGARCHIVE"
    echo "Filepath to converted image = $CONVERTED"
    echo "Low cut-off = $DIFFLO"
    echo "High cut-off = $DIFFHI"


###Image data###

        WIDTH=$(identify -format "%w" "$ORIGINAL")
        HEIGHT=$(identify -format "%h" "$ORIGINAL")
        ZBIT=$(identify -format "%z" "$ORIGINAL")
        COL=$(identify -format "%[colorspace]" "$ORIGINAL")
        F1=$(stat -c%s "$ORIGINAL")

        if [ "$COL" = "RGB" ]
          then
              CHANN="3"
          else
              CHANN="1"
        fi


###Cutoff setting###

    if [ "$F1" -ge "$CUTOFF" ]
      then
        DIFF="$DIFFHI"
      else  
        DIFF="$DIFFLO"
    fi


###Calculations on uncompressed image###

        BMPSIZE=$(echo "($WIDTH*$HEIGHT*$ZBIT*$CHANN/8)" | bc)
        FR=$(echo "($F1*100/$BMPSIZE)" | bc)

#DEBUG#

        echo "###IMAGE DATA###"
        echo "Image Dimensions = $WIDTH x $HEIGHT"
        echo "Colour Depth = $ZBIT"
        echo "Colour Profile = $COL"
        echo "Channels = $CHANN"
        echo "Estimated uncompressed size = $BMPSIZE"
        echo "Actual file size = $F1"
        echo "Estimated size ratio = $FR %"
        echo "Cutoff at $DIFF %"

###Backup###

        echo "###BACKUP###"
        mkdir -p "$ORIGARCHIVE/$SUBFOLDER"  #keep the original folder structure
        cp -v "$ORIGINAL" "$ORIGARCHIVE/$SUBFOLDER"
        echo ""

###Comparison###

    if [ "$FR" -ge "$DIFF" ]
      then
          echo "JPEG is more efficient, converting..."
          convert -quality 92 -flatten -background white "$ORIGINAL" "$CONVERTED"
              echo "Done."
          echo "Cleaning up..."
          rm -v "$ORIGINAL"
      else
          echo "PNG is fine, passing over to optipng."
              echo "Optimizing..."
              optipng "$ORIGINAL"
              echo "Done."
    fi

################ Filetype Check#################

  else
    echo "File does not exist or unknown MIME type, exiting."

fi

Harika bir fikir için @ Thomas Thomas'a sahne.


1
İşte senaryoyu daha verimli hale getirebilecek bir düşünce. PNG'nin dosya boyutunu, boyutlara ve renk derinliğine bağlı olarak tahmini sıkıştırılmamış boyutuyla karşılaştırın. Fotoğrafik görüntüler yaklaşık% 50'lik bir sıkıştırma oranına sahip olabilir, ancak karmaşık şemalar bile% 10'un altına kolayca inmelidir. Eğer oran daha düşük bir sınırın altındaysa, PNG'nin daha iyi bir seçim olduğunu varsayabilir ve JPG'ye dönüşümün tamamını atlayabilirsiniz.
Marcks Thomas

@MarcksThomas: Harika bir fikir, teşekkür ederim! Teklifine dayanarak alternatif bir senaryo ekledim. Oranlar hala biraz değişmeye ihtiyaç duyuyor, ancak aksi halde iyi çalışıyor. Gri tonlamalı görüntülerde yalnızca bir sorun var. BMP boyutları onlar için doğru hesaplanmadı ve nedenini anlayamıyorum. Gerçekten küçük bir sorun, çalıştığım neredeyse tüm resimler renkli olduğundan, ama yine de can sıkıcı.
Glutanimate
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.