Jika gambar diputar tanpa kehilangan, mengapa ukuran file berubah?

37

Saya sedang mencari metode rotasi gambar lossless dan terjadi pada pertanyaan ini yang menjelaskannya dengan cukup baik:

Apakah rotasi "Windows Photo Viewer" tidak rugi?

Jadi saya membuat 256 × 256 JPEG dengan piksel acak (Photoshop cloud filter) dan kemudian memutarnya menggunakan Windows Picture Viewer. Setelah rotasi, ukuran file sebenarnya meningkat, tetapi hanya pada rotasi pertama. Setiap rotasi sesudahnya, ukuran file tetap statis. Saya tahu itu berputar tanpa kehilangan karena saya telah memutarnya berkali-kali tanpa kehilangan kualitas yang nyata sedangkan gambar 257 × 257 diputar 20 kali menjadi sangat rugi.

ocilatingcretin
sumber
8
Berapa ukuran file yang meningkat dalam pengujian Anda?
James Snell
3
@ JamesNell saya tahu saya harus memasukkan itu. Yang saya lakukan hanya menggunakan filter clounds perbedaan GIMP awalnya 14.583 byte, tetapi berubah menjadi 23.638 byte setelah roation. Itu perbedaan lebih dari 9000 byte yang tampaknya seperti banyak data tambahan jika kita hanya memikirkan metadata saja.
oscilatingcretin
4
Itu sepertinya banyak metadata tambahan. Saya tidak akan terlalu cepat untuk menganggap semua data tambahan itu sebagai metadata. Tampak bagi saya bahwa perbedaan ukuran karena metadata harus hampir konstan (dalam beberapa byte untuk menjelaskan representasi string dari beberapa angka).
scottbb
4
Saat memberikan informasi tambahan yang berkaitan dengan pertanyaan, harap edit ke dalam pertanyaan daripada di komentar. Komentar bersifat sementara dan dapat dibersihkan dari waktu ke waktu.
scottbb
2
Mengunggah versi asli gambar uji Anda akan sangat membantu.
CodesInChaos

Jawaban:

36

Ini kemungkinan besar disebabkan oleh pengkodean entropi , yang merupakan tahap akhir dari kompresi JPEG, setelah data gambar dikuantisasi untuk mengurangi ukurannya.

Ketika gambar JPEG diputar secara lossless, lapisan akhir pengkodean lossless ini harus diurungkan, koefisien DCT yang tidak dibongkar bergeser ke sekitarnya, dan kemudian koefisien yang dikocok perlu dikodekan lagi dengan kode entropi. Karena efisiensi lapisan pengkodean entropi tergantung pada urutan koefisien DCT dalam setiap blok, yang memutar gambar akan berubah, tidak mengherankan bahwa file gambar yang diputar mungkin beberapa persen lebih kecil atau lebih besar dari aslinya.

Ada juga beberapa cara berbeda di mana langkah pengkodean entropi dapat dilakukan, sehingga sangat mungkin bahwa ukuran file dari gambar JPEG yang sama persis dapat bervariasi tergantung pada perangkat lunak yang melakukan pengkodean. Beberapa perbedaan potensial antara pembuat enkode meliputi:

  • pilihan pengkodean aritmatika (jarang tetapi berpotensi lebih efisien, digunakan untuk dipatenkan) vs. pengkodean Huffman (lebih sederhana, standar);
  • pilihan berurutan (setiap blok 8x8 piksel dikodekan satu per satu) vs progresif (komponen frekuensi rendah dari semua blok dikodekan sebelum komponen frekuensi yang lebih tinggi, biasanya sedikit lebih kompak) urutan pengkodean;
  • pilihan menggunakan tabel simbol Huffman standar (lebih cepat, lebih sederhana, mungkin lebih efisien untuk gambar yang sangat kecil) vs tabel kustom yang dioptimalkan untuk setiap gambar (biasanya lebih efisien untuk gambar besar, lebih lambat dan lebih kompleks untuk disandikan);
  • jika tabel Huffman khusus digunakan, enkode yang berbeda berpotensi menghasilkan tabel yang berbeda untuk data gambar yang sama;
  • berbagai perincian tingkat rendah dari proses penyandian itu sendiri, seperti apakah dan kapan untuk memasukkan tanda mulai ulang dalam aliran data, juga dapat bervariasi di antara penyandi.

Juga, "file JPEG" yang biasanya digunakan orang benar-benar berisi data gambar terkompresi JPEG yang dibungkus dalam JFIF atau wadah Exif , yang menggabungkan data gambar dengan satu atau lebih blok metadata, dan memperkenalkan serangkaian komplikasinya sendiri. Bahkan jika perangkat lunak yang memutar gambar tidak benar-benar membuat perubahan substantif pada metadata JFIF / Exif, hanya menata ulang data dapat berpotensi mempengaruhi ukuran file beberapa byte.

Khususnya, metadata JFIF / Exif dapat berisi satu atau lebih gambar kecil dari gambar ukuran penuh, dan perangkat lunak yang memutar gambar benar-benar harus membuat ulang (atau juga memutar tanpa kehilangan!) Gambar kecil sehingga mereka akan cocok dengan orientasi baru dari gambar penuh. gambar ukuran. Ini saja bisa dengan mudah menjelaskan perbedaan ukuran yang diamati.

Ilmari Karonen
sumber
4
Untuk perbedaan 9KB (60%), tebakan saya adalah thumbnail.
BlueRaja - Danny Pflughoeft
JPEG mungkin terlalu sederhana untuk melakukan encoders layak, tetapi encoders video seperti x264 sebenarnya dapat mempertimbangkan kemampuan entry coder untuk mengkodekan apa yang akan mereka output selanjutnya, ketika membuat keputusan tradeoff tingkat vs distorsi. (Yaitu memutuskan berapa banyak bit setiap alternatif bisa biaya, dan menimbang itu terhadap kesalahan lossy). Ini disebut kuantisasi terali. Lihat Catatan tentang implementasi kuantisasi terali di H.264 dari penulis x264 (Loren Merritt); dia mulai dengan penjelasan yang cukup mendasar tentang tujuannya.
Peter Cordes
Bagaimanapun, maksudnya, encoder JPEG mungkin telah memilih koefisien DCT sedemikian rupa sehingga mereka dikompres dengan baik dengan entropi coder, sehingga bahkan kompresor yang optimal tidak dapat membuat versi yang diputar sebagai kecil. (Karena menempatkan mereka dalam urutan yang berbeda mungkin akan membuat mereka kompres kurang baik.) Ini hampir pasti akan menjadi efek kecil untuk JPEG, karena setiap blok 8x8 dikodekan secara terpisah (mengatur ulang keadaan kode entropi, AFAIK). (I-frame di h.264 menggunakan intra-prediksi, memprediksi dari blok lain dalam frame yang sama, membuatnya lebih kecil dari JPEG pada kualitas visual yang sama.)
Peter Cordes
24

Saya melanjutkan dan mengulangi percobaan untuk melihat apakah saya bisa mengetahui apa yang sedang terjadi.

Prosedur

Saya menghasilkan gambar RGB 256-by-256 piksel acak menggunakan filter "Solid Noise" di GIMP (Filter> Render> Clouds> Solid Noise ...) menggunakan pengaturan default (ditunjukkan di bawah):

masukkan deskripsi gambar di sini

Dan hasilnya:

masukkan deskripsi gambar di sini

Lalu saya menyimpan gambar sebagai JPEG menggunakan pengaturan default:

masukkan deskripsi gambar di sini

Kemudian saya mentransfer gambar ke Windows dan membuka gambar dengan Windows Photo Viewer dengan mengklik kanan pada gambar di File Explorer dan memilih Preview dari menu. Lalu saya memutar gambar menggunakan tombol di bagian bawah, dan menyimpan gambar dengan menavigasi ke gambar berikutnya menggunakan tombol panah.

Untuk setiap tes di bawah ini saya mulai dengan salinan gambar asli, dan memutar (mengklik tombol putar) beberapa kali sebelum menyimpan. Berikut ini ukuran reslting ( ls -l -r):

                    size in bytes    last-modified date 
                          VVVVV        VVVVV
-rwxrwx--- 1 root vboxsf   6258 Nov  8 11:24 original.jpg
-rwxrwx--- 1 root vboxsf  23645 Nov  8 11:30 cw.jpg
-rwxrwx--- 1 root vboxsf  23636 Nov  8 11:30 cw-cw.jpg
-rwxrwx--- 1 root vboxsf  23649 Nov  8 11:30 cw-cw-cw.jpg
-rwxrwx--- 1 root vboxsf   6258 Nov  8 11:27 cw-cw-cw-cw.jpg
-rwxrwx--- 1 root vboxsf  23649 Nov  8 11:31 cw-cw-cw-cw-cw.jpg
-rwxrwx--- 1 root vboxsf  23649 Nov  8 11:29 ccw.jpg
-rwxrwx--- 1 root vboxsf  23636 Nov  8 11:29 ccw-ccw.jpg
-rwxrwx--- 1 root vboxsf  23645 Nov  8 11:29 ccw-ccw-ccw.jpg
-rwxrwx--- 1 root vboxsf   6258 Nov  8 11:27 ccw-ccw-ccw-ccw.jpg
-rwxrwx--- 1 root vboxsf  23649 Nov  8 11:30 ccw-ccw-ccw-ccw-ccw.jpg

Pengamatan langsung

  • Windows Photo Viewer (WPV) memang meningkatkan ukuran secara dramatis; jumlah kenaikan sekitar empat kali dalam tes ini!
  • Semua gambar baru bertambah sekitar ukuran yang sama, tetapi mereka tidak identik.
  • WPV tidak menyandikan ulang atau bahkan menyimpan kembali gambar ketika diputar dengan kelipatan 360 derajat. (Stempel waktu, 11:27, adalah saat file pertama kali disalin.)

Menggunakan cmp -lpada file yang seharusnya memiliki konten yang identik memungkinkan kita untuk melihat di mana file berbeda.

robert@unity ../jpeg-rotate-test % cmp -l cw.jpg ccw-ccw-ccw.jpg
 2223  63  62
 2224  60  71
 2226  60  64
 2227  60  66
robert@unity ../jpeg-rotate-test % cmp -l cw-cw.jpg ccw-ccw.jpg
 2223  63  62
 2224  60  71
 2226  60  64
 2227  62  64
robert@unity ..jpeg-rotate-test % cmp -l ccw.jpg cw-cw-cw.jpg
 2223  62  63
 2224  71  60
 2226  64  60
 2227  61  64
robert@unity ../jpeg-rotate-test % cmp -l cw.jpg cw-cw-cw-cw-cw.jpg
 2221  60  61
 2223  63  61
 2224  60  66
 2226  60  61
 2227  60  61
robert@unity ../jpeg-rotate-test % cmp -l ccw.jpg ccw-ccw-ccw-ccw-ccw.jpg
 2223  62  63
 2224  71  60
 2226  64  65
 2227  61  64

File-file ini berbeda hanya dalam empat byte (sebenarnya dalam cap waktu), yang berarti bahwa WPV melakukan hal yang sama setiap kali; sekarang kita hanya perlu mencari tahu apa itu.

Pengamatan rinci

Untuk ini saya menggunakan JPEGsnoop untuk melihat apa sebenarnya yang ada di gambar.

Karena outputnya cukup panjang, saya menghubungkannya sebagai intisari . Berikut ringkasan perbedaan:

  • GIMP hanya menggunakan segmen APP0(JFIF) dan COM(komentar) untuk metadata. WPV membiarkan bagian tersebut APP0tidak tersentuh, tetapi dengan anehnya menambahkan byte nol pada komentar (sehingga diakhiri null)

  • WPV menambahkan dua APP1segmen, yaitu metadata Exif dan XMP. Segmen ini masing-masing adalah 4286 dan 12726 byte. Bersama-sama mereka menghitung hampir seluruh peningkatan dalam ukuran file.

  • GIMP menghasilkan JPEG progresif, sedangkan WPV menghasilkan JPEG dasar (non-progresif). Karena alasan ini gambar GIMP memiliki beberapa segmen pemindaian, sedangkan gambar WPV hanya memiliki satu segmen. Dalam pengalaman saya, gambar progresif kadang-kadang sedikit lebih kecil.

  • GIMP menggunakan 1 × 1 chroma subsampling, sedangkan WPV menggunakan 2 × 2 subsampling. Ini membuat saya percaya bahwa WPV tidak menggunakan rotasi lossless "benar", kecuali jika entah bagaimana dapat mendeteksi ini adalah gambar hitam-putih.

Untuk mengatasi masalah ini, saya menjalankan tes kedua.

Prosedur

Saya mengikuti langkah-langkah serupa pada tes pertama. Saya membuat gambar 256 × 256 RGB acak menggunakan filter Noise RGB (Filter> Nose> RGB Nose ...) dengan pengaturan berikut:

masukkan deskripsi gambar di sini

Inilah hasilnya:

masukkan deskripsi gambar di sini

Saya mengekspor file sebagai JPEG menggunakan pengaturan berikut:

masukkan deskripsi gambar di sini

Progresif telah dimatikan, tetapi Subsampling masih diatur ke 4: 4: 4 (yang merupakan nama lain untuk subsampling 1 × 1). Kualitasnya meningkat menjadi 98.

Saya menyalin gambar dan memutar salinan searah jarum jam; kemudian menyalin versi yang diputar dan memutar salinan itu berlawanan arah jarum jam, sehingga kita dapat langsung membandingkan kualitas antara yang asli dan salinan yang diproses WPV.

Hasil

-rwxrwx--- 1 root vboxsf 159774 Nov  8 16:21 original-random.jpg
-rwxrwx--- 1 root vboxsf 222404 Nov  8 16:24 cw-random.jpg
-rwxrwx--- 1 root vboxsf 222467 Nov  8 16:24 cw-ccw-random.jpg

Meskipun peningkatan kali ini relatif lebih kecil (sekitar 40%), peningkatan absolut bahkan lebih besar — ​​sekitar 62 kB. Ini menunjukkan bahwa WMV menggunakan pengkodean yang kurang efisien.

Saya akan menggunakan ImageMagick untuk membandingkan dua gambar:

robert@unity ../jpeg-rotate-test % compare -verbose -metric AE original-random.jpg cw-ccw-random.jpg null:
original-random.jpg JPEG 256x256 256x256+0+0 8-bit sRGB 160KB 0.000u 0:00.009
cw-ccw-random.jpg JPEG 256x256 256x256+0+0 8-bit sRGB 222KB 0.010u 0:00.010
Image: original-random.jpg
  Channel distortion: AE
    red: 0
    green: 0
    blue: 0
    all: 0
original-random.jpg=> JPEG 256x256 256x256+0+0 8-bit sRGB 0.050u 0:00.020

Ada nol piksel yang berbeda antara salinan asli dan yang diputar. Jadi, bahkan jika WPV tidak menggunakan rotasi lossless "benar", itu melakukan pekerjaan yang cukup baik. Saya kira saya tahu apa yang sedang terjadi, dan untuk menjelaskan saya akan mengalihkan sedikit ke dalam matematika di balik kompresi JPEG.

Algoritma kompresi JPEG memecah gambar menjadi blok 8 × 8-piksel. Masing-masing dari blok ini kemudian mengalami Discrete Cosine Transform (DCT) . Koefisien DCT yang dihasilkan menggambarkan blok sebagai jumlah dari gelombang frekuensi-berbeda. Algoritma kemudian "membuang" beberapa informasi dalam gelombang frekuensi tinggi yang sesuai dengan kebisingan dan detail yang sangat kecil. Proses decoding membalikkan DCT, menambahkan gelombang yang tersimpan bersama untuk mendapatkan kembali blok.

Dimungkinkan untuk memutar "gelombang" DCT tanpa benar-benar membatalkan dan mengulangi transformasi (pada dasarnya Anda mengubah semua gelombang horizontal menjadi gelombang vertikal dan sebaliknya). Apa yang saya pikir terjadi dalam WPV adalah bahwa gambar tersebut benar-benar diterjemahkan, diputar, dan kemudian disandikan ulang. Selama proses pengkodean ulang, karena ukuran gambar kami adalah kelipatan 8 di kedua dimensi, masing-masing blok baru sesuai dengan salah satu blok asli. Yang penting, karena setiap blok tidak memiliki komponen frekuensi tinggi, algoritma tidak membuang informasi apa pun, dan menemukan komponen DCT yang tepat yang dimiliki oleh rotasi lossless "benar".

Terakhir, saya akan melihat komponen file JPEG lagi. Hasilnya dikaitkan kembali sebagai intisari . Membandingkan keduanya:

  • Gambar WPV berisi ekstra 4286 + 2 byte metadata Exif, 1 byte ekstra di komentar, dan 12.726 + 2 byte metadata XMP. Ini adalah total 17.017 byte metadata tambahan. Untuk apa semua data itu digunakan? Saya mengintip ke dalam file dengan hex editor terpercaya saya dan salinan standar yang relevan:

    • Exif metadata terstruktur seperti gambar TIFF, yang berisi sejumlah tag (ada cara yang lebih kompleksitas, tapi aku akan melewatkan hak di atasnya). Sebagian besar byte di segmen Exif terkandung dalam dua tag identik dengan nomor tag EA1C(59.932 desimal). Nomor tag itu tidak didokumentasikan di mana pun saya dapat temukan. Kedua tag berisi 2060 byte tipe "tidak terdefinisi", yang semuanya byte nol kecuali untuk enam ( 1C EA 00 00 00 08) pertama. Saya tidak tahu apa tag ini, mengapa ada dua, dan mengapa mereka harus masing-masing 2 kB.

    • Metadata XMP sebenarnya adalah seluruh dokumen XML yang disematkan dengan namespacing dan UUID yang panjang, yang hanya berisi string versi WPV (yang sudah ada dalam metadata Exif). Namun, itu hanya menyumbang sekitar 400 byte. Sisa dari segmen ini adalah 122 pengulangan dari 100 ruang diikuti oleh baris baru . Itu lebih dari 12.000 byte ruang yang benar-benar terbuang.

  • Seperti tes sebelumnya, baik GIMP dan WPV menggunakan tabel kuantisasi DCT yang sama. Ini berarti bahwa mereka harus menghitung koefisien DCT yang persis sama, itulah sebabnya gambarnya persis sama. Saya tidak yakin apakah WPV kebetulan menggunakan tabel kuantisasi yang sama atau jika menyalin tabel dari input.

  • Berbeda dengan tes sebelumnya, kali ini WPV menggunakan subsampling 1 × 1, jadi itu sebenarnya dapat mendeteksi bahwa ini adalah gambar berwarna (atau setidaknya sampel yang lebih tinggi diperlukan untuk menyandikan ulang gambar tanpa hilang).

  • GIMP dan WPV menggunakan tabel Huffman yang berbeda (bagian dari langkah pengkodean entropi). Tabel untuk WPV lebih besar dengan total 279 byte, dan dalam satu kasus mengandung 7 kali lebih banyak kode.

    Melihat statistik JPEGsnoop, kita dapat melihat bahwa beberapa kode ini jarang digunakan. Misalnya, dalam ID: 1, Class: ACtabel, dari 119 kode 16-bit yang ditentukan, hanya 23 yang benar-benar digunakan. Secara keseluruhan, segmen pemindaian yang sebenarnya adalah 28,5% lebih besar di versi WPV.

Ringkasan

  • WPV mungkin tidak melakukan rotasi lossless "benar", tetapi rotasi tampaknya praktis lossless.

  • Ukuran ekstra sebagian karena jumlah tetap metadata yang ditambahkan, dan sebagian karena pengkodean entropi yang kurang efisien.

Informasi Versi:

  • OS (Linux) ( uname -a):

    Linux unity 3.16.0-4-amd64 #1 SMP Debian 3.16.36-1+deb8u1 (2016-09-03) x86_64 GNU/Linux
    
  • OS (Windows):

    masukkan deskripsi gambar di sini

  • GIMP (Linux): 2.8.14 (dari paket gimp, versi 2.8.14-1+deb8u1)

    masukkan deskripsi gambar di sini

  • Window Photo Viewer (sesuai dengan metadata gambar):

    Microsoft Windows Photo Viewer 10.0.10586.0
    
2012 Arcampion
sumber
20

EDIT : Jawaban ini diposting sebelum saya tahu bahwa ukuran file telah meningkat sekitar 9 KiB (9055 byte untuk gambar 256 × 256, 9612 KiB untuk gambar 512 × 512).

Kemungkinan besar, ketika Anda pertama kali memutar gambar, Windows Picture Viewer melakukan satu (atau keduanya) hal-hal berikut:

  1. Menambahkan tag EXIF ​​yang tidak ada dalam gambar JPEG asli (mungkin tag Orientation);
  2. Informasi yang dimodifikasi / ditambahkan ke tag yang sudah ada (mungkin Perangkat Lunak Pemrosesan atau tag Perangkat Lunak Gambar).

Ini meningkatkan ukuran file karena tag EXIF ​​tambahan (dan / atau data tambahan untuk tag yang ada).

Rotasi selanjutnya tidak menambah ukuran file karena semua tag dan / atau data tag yang akan ditambahkan / dimodifikasi WPV sudah ada di sana. Hanya Orientasi Tag nilai berubah (dan mungkin tanggal / waktu nilai-nilai tag juga).


EDIT : Hampir dapat dipastikan bahwa penjelasan ini tidak dapat menjelaskan sekitar 9 KiB data tambahan dalam file. Lebih lanjut, jika tidak ada alasan lain untuk peningkatan ukuran, penjelasan ini akan berharap bahwa peningkatan ukuran akan lebih atau kurang konstan (modulo beberapa perbedaan panjang antara representasi string dari data numerik, mungkin beberapa byte). Jelas bukan itu yang terjadi di sini, setidaknya bukan penjelasan yang lengkap.

scottbb
sumber
1
Dan tag EXIF ​​akan mengambil 9kB? Yah, setidaknya ini mudah untuk diuji - minta OP menghapus EXIF ​​atau tag lain dari gambar yang diputar dan lihat bagaimana ukuran file berubah.
Carl Witthoft
2
@CarlWitthoft, 9kB adalah informasi baru. Mengedit untuk menyebutkan itu.
scottbb
3

Tanpa rekayasa terbalik, jpeg en / decoder tidak mungkin untuk mengatakan dengan pasti. Sebenarnya ada sejumlah standar jpeg dan bertentangan dengan kepercayaan populer, tidak semuanya dapat dimodifikasi tanpa pengkodean ulang.

Ada kemungkinan bahwa penyimpanan pertama adalah penulisan ulang yang hilang menjadi rasa jpeg yang disukai dan rotasi berikutnya adalah tweak metadata sederhana atau operasi langsung pada tabel DCT (yang mungkin untuk beberapa skema pengkodean).

Peningkatan filesize mungkin juga mencakup beberapa metadata tambahan, meskipun 9k sepertinya banyak, itu mungkin. Peningkatan ini juga dapat diperhitungkan dengan penambahan thumbnail yang mungkin belum ada dalam output dari GIMP. Kami mungkin dapat memperoleh informasi lebih banyak dari file secara langsung (sebelum WPV dan setelah).

Bagaimanapun, mencoba untuk bekerja tanpa kehilangan dengan jpeg benar-benar tugas bodoh karena hanya berguna dengan ukuran gambar tertentu, tidak semua decoder dan encoders identik dan itu mengharuskan para editor untuk bekerja secara langsung dengan konten jpeg yang Anda tidak dapat mengandalkan untuk menjadi kasus ini ... Hanya karena hal itu terjadi sekarang tidak berarti itu akan terus berlanjut di masa depan.

Taruhan terbaik Anda adalah bekerja dengan format lossless dan menghindari rasa sakit sepenuhnya.

James Snell
sumber
2
Saya sama sekali tidak yakin bahwa memutar data jpeg harus menyebabkan pengkodean ulang di tempat pertama.
Carl Witthoft
Tergantung pada apakah Anda seorang programmer atau tidak ... Dugaan saya adalah Anda tidak. Anda harus secara khusus mencari optimasi itu untuk membuat perubahan minimal jika operasi save akan dimulai dari bitmap yang tidak terkompresi.
James Snell
3
Dari pertanyaan yang ditautkan, jelas bahwa Windows Photo Viewer memang memutar JPEG tanpa kehilangan.
vclaw
2
@ James, aku bukan programmer level rendah, karena aku bermain di TV :-). OP memberikan tautan ke deskripsi yang akurat tentang kapan akan ada pengkodean ulang dan ketika tidak ada pengkodean ulang. Saya telah menyimpulkan dari diskusi itu bahwa dia hanya berputar oleh $ \ frac {\ pi} {2} $. Saya setuju bahwa rotasi sudut sewenang-wenang menyebabkan pengkodean ulang, dan dalam hal ini akan menyebabkan kehilangan informasi kecuali gambar X-by-Y tertanam di suatu wilayah setidaknya sama besar dengan sisi miring.
Carl Witthoft
1
Kami yakin kami tahu bahwa WPV berputar terbalik untuk gambar dengan kelipatan dimensi 8/16. Lihat @ Tristan komentar untuk jawaban Matt Grum untuk pertanyaan yang terkait dalam OP. Tristan bekerja di tim WPV di Microsoft, dan pada dasarnya mengkonfirmasi.
scottbb
1

Rotasi JPEG lossless hanya dimungkinkan tanpa pengenalan artefak batas jika dimensi gambar adalah kelipatan dari ukuran blok (biasanya [/ selalu?] 8). Lihat halaman manual jpegtran (maaf saya tidak memiliki tautan kanonik yang baik untuk itu; jangan ragu untuk mengedit jika Anda menemukannya) untuk detail tentang apa yang terlibat:

Transformasi transpose tidak memiliki batasan mengenai
dimensi gambar . Transformasi lain beroperasi agak aneh jika dimensi gambar bukan kelipatan dari ukuran iMCU (biasanya 8 atau 16 piksel), karena mereka hanya dapat mengubah blok lengkap data koefisien DCT dengan cara yang diinginkan.

perilaku default jpegtran ketika mentransformasikan gambar ukuran ganjil
dirancang untuk menjaga reversibilitas yang tepat dan
konsistensi matematis dari set transformasi. Seperti yang dinyatakan, transpose
dapat membalik seluruh area gambar. Pencerminan horizontal membuat kolom iMCU parsial apa pun di tepi kanan tidak tersentuh, tetapi dapat membalik semua baris gambar. Demikian pula, mirroring vertikal membuat setiap baris iMCU parsial di tepi bawah tidak tersentuh, tetapi mampu membalik semua kolom. Transformasi lain dapat dibangun sebagai urutan operasi transpose dan flip; untuk konsistensi, aksi mereka pada piksel tepi didefinisikan sama dengan hasil akhir dari urutan transpos-dan-balik yang sesuai.

Untuk penggunaan praktis, Anda dapat memilih untuk membuang
piksel tepi yang tidak dapat diubah daripada memiliki strip yang tampak aneh di sepanjang tepi
kanan dan / atau bawah gambar yang diubah. Untuk melakukan ini, tambahkan sakelar -trim:

Saya curiga Windows Photo Viewer menghindari masalah ini dengan melakukan dekompresi dan ekstrem berkualitas tinggi untuk mensimulasikan perilaku lossless ketika dimensi gambar bukan kelipatan 8, daripada benar-benar melakukan rotasi lossless. Utilitas yang baik hanya akan melakukan lossless aktual, artefak dan semua, atau menjatuhkan beberapa piksel, daripada merusak kualitas seluruh gambar (dan meningkatkan ukuran file).

R ..
sumber
1
tidak relevan untuk gambar 256x256.
THS
Saya salah membaca dan berpikir bahwa masalahnya adalah untuk versi 257x257.
R ..
0

Saya tidak punya jawaban yang pasti tetapi beberapa teori yang mungkin mengapa itu terjadi. Beberapa tipe file bekerja sedemikian rupa sehingga dua kode berbeda untuk suatu gambar dari tipe file itu tidak selalu menghasilkan gambar yang berbeda. Sebagai contoh, jenis file PNG bekerja dengan cara itu karena memungkinkan untuk latar belakang transparan tetapi gambar dengan latar belakang transparan dan yang sama kecuali bahwa latar belakang yang sama putih muncul dengan cara yang sama persis. File gambar dikatakan dikompres jika membutuhkan kurang dari 3 byte memori per piksel. Saya percaya bahwa kecuali untuk yang dengan latar belakang transparan, tidak ada dua file PNG menghasilkan gambar yang sama persis. Setiap kali Anda menyimpan gambar sebagai PNG, itu mengubahnya menjadi kode yang menghasilkan gambar asli dan kecuali untuk gambar yang sangat tidak biasa seperti di mana setiap piksel adalah warna acak dari semua 2 ^ 24 warna, kode ini akan memakan lebih sedikit memori dari 3 byte per piksel sehingga menghemat karena PNG dikatakan kompresi lossless. Di sisi lain, untuk menghemat memori, hanya gambar tertentu yang dapat dihasilkan oleh kode file gambar JPEG. Mungkin ada lebih dari satu tipe file JPEG dan saya tidak tahu apakah ada di antara mereka yang memiliki properti bahwa dua gambar berbeda dari tipe file itu dapat menghasilkan gambar yang sama persis. Saya berasumsi bahwa beberapa kali Anda hanya memutar gambar kemudian menyimpannya sebagai JPEG dan akan memberikan penjelasan tentang apa yang terjadi di bawah asumsi bahwa itulah yang Anda lakukan yang saya tidak tahu apakah itu benar. Rotasi yang Anda lakukan tidak akan rugi jika ada cara untuk mendapatkan kembali kode file gambar yang sama persis seperti yang Anda miliki sebelum Anda memutarnya dan menyimpannya. Anda mungkin tidak benar bahwa Anda benar-benar melakukan rotasi lossless. Jika itu benar-benar lossless,

Timotius
sumber
-3

Alasan di balik ini ada beberapa

cara gambar dikodekan dan dikompresi akan mengubah ukuran hanya karena algoritma kompresi. Anda dapat mengujinya dengan menyimpannya sebagai bitmap lalu memutarnya. Dalam format itu atau format mentah apa pun ukurannya harus tetap sama. Jika tidak maka program yang menyimpan gambar menambahkan data baru mungkin beberapa metadata atau sesuatu.

Tetapi mengapa Anda memutar jpeg 20 kali?

Cc Dd
sumber
2
Jika Anda membaca tautan di pertanyaan awal, setidaknya untuk Windows Picture Viewer , jika dimensi JPEG adalah kelipatan 8, maka rotasi JPEG di WPV adalah transformasi tanpa kerugian . Cara sederhana untuk menguji yaitu memutar 4 kali (menghasilkan orientasi yang sama seperti aslinya) dan melakukan pengurangan gambar piksel-demi-piksel sederhana.
scottbb
@ skottbb Ini tidak selalu hanya masalah dengan windows picture viewer. Apa pun yang memutar format lossy harus menghitung ulang kompresi. memutar gambar dalam kelipatan 8 berarti semuanya cocok dalam kata-kata 8 bit dan mungkin tidak dikompresi dengan cara yang menambahkan artefak. Ini didasarkan pada bagaimana algoritma bekerja dan diimplementasikan dalam program yang digunakan.
Cc Dd
-3

Karena cara kompresi gambar bekerja . Format apa pun seperti PNG atau JPG pada umumnya tidak mempertahankan ukuran file setelah rotasi.

Untuk kompresor gambar yang diputar hanya gambar yang berbeda, karena cara heuristik kompresi tidak ada jaminan itu akan mengkompres gambar yang diputar sama .

Tentu saja jika kompresinya lossless, jika Anda memutar gambar 4 kali ke-4 kali gambar itu sama lagi (diputar sampai menjadi miring seperti aslinya): dalam hal itu harus menjadi lagi dari ukuran terkompresi yang sama, jika tidak maka itu karena salah satu alasan berikut :

  • Menambahkan metadata : program menambahkan beberapa potongan teks untuk beberapa alasan
  • Kompresor berubah: program dapat memilih untuk hanya menyimpan kembali gambar seperti aslinya jika tidak ada perubahan, tetapi jika Anda menerapkan perubahan apa pun (bahkan 4 rotasi 90 derajat), ia dapat memutuskan untuk mengompres ulang gambar lagi menggunakan sendiri kompresor (program tidak lagi tahu gambarnya masih sama).
  • Secara umum kompresor yang sama (libPNG atau libJPG) menghasilkan hasil yang sangat berbeda di implementasi yang berbeda, versi berbeda dari perpustakaan yang sama dan dengan parameter kompresi yang berbeda (juga sistem operasi dan kompiler membuat perbedaan di sini kadang-kadang).

Kompresi gambar bekerja dengan mengompres gambar menjadi 4x4 atau potongan ukuran lain. Secara umum kompresor melihat gambar yang dirotasi sebagai gambar yang berbeda, namun karena potongan piksel terkompresi hanya merupakan dekomposisi linier, jika potongan pada gambar adalah sama, maka dimungkinkan untuk melakukan Transpose / Cermin matriks dekomposisi linier secara efektif menjaga sama kualitas:

Catatan ini harus diterapkan pada basis per fitur , dan itu juga menjelaskan peningkatan awal dalam ukuran => pada rotasi pertama itu hanya mencoba untuk mengompres gambar dalam potongan yang dapat diputar:

  • Jika gagal melakukannya: kualitas gambar menurun
  • Jika berhasil, ia menambah ukuran hanya sekali maka setiap rotasi menjaga kualitas yang sama.

  • Operasi itu berhasil hanya jika gambar dibuat oleh potongan yang sama. (ukuran gambar adalah kelipatan dari ukuran chunk).

Jawaban scottbb salah dan Anda dapat melakukan tes sederhana:

  • Buka gambar asli: Screenshot itu
  • Putar gambar 4 kali dengan WPV: Screenshot-nya
  • Bandingkan 2 tangkapan layar

Anda akan melihat gambar berubah (dikompres ulang pada rotasi pertama). Namun perubahan itu terbatas dalam waktu, Anda sekarang dapat memutarnya lagi tanpa kehilangan kualitas (jika gambar memiliki ukuran kelipatan 8)

Untuk langsung menjawab OP:

Saya tahu itu berputar tanpa kerugian

Bukannya tidak berputar losslessy, ia kehilangan kualitas setidaknya satu kali (pada rotasi pertama: karena ia harus memampatkannya terlebih dahulu dengan cara yang dapat diputar), kemudian ia mempertahankan kualitasnya.

GameDeveloper
sumber
1
Pertanyaannya adalah tentang rotasi lossless, jadi rekompresi dihindari.
Agent_L
5
OP bertanya bukan tentang kasus umum tetapi tepatnya tentang sepotong perangkat lunak tertentu dan satu kasus spesifik yang melakukannya. Jawaban Anda tidak salah, itu hanya menjawab pertanyaan yang berbeda dari yang diminta OP.
Agent_L
1
3 kalimat pertama masih untuk pertanyaan yang berbeda: "bagaimana kompresi gambar bekerja" - tidak ada kompresi dalam rotasi lossless. "Untuk kompresor gambar yang diputar" - lagi, kompresor tidak dipanggil. "jika kompresinya lossless" - kompresinya lossy. Rotasi itu lossless. Sekarang, sejauh ini saya bersedia mengambil argumen ini. Saya bisa mengerti maksud Anda, saya setuju dengan itu, tapi itu benar-benar tidak pada tempatnya di sini. BTW, saya seorang programmer juga dan saya melakukan bagian saya membaca dan menulis file mentah.
Agent_L
1
Saya telah membuat gambar dalam Paint, memutarnya 4 kali dan identik, tetapi ukurannya tetap melonjak dari 1,6 menjadi 8,1 KB. Binary diff menunjukkan bahwa data gambar tidak tersentuh, hanya sejumlah besar metadata dalam <?xpackettag.
Agent_L
1
Jika dimensi JPEG secara merata dapat dibagi 8 (atau 16 dengan subsampling), ia dapat diputar dalam peningkatan 90 derajat tanpa kehilangan . Kuncinya adalah untuk tidak mendekodekan sepenuhnya ke RGB, tetapi untuk bekerja secara langsung dengan koefisien DCT. Ini adalah fungsi khusus yang tidak sering dimasukkan dalam editor gambar umum. Lihat misalnya en.wikipedia.org/wiki/Libjpeg#jpegtran . Jika Anda melakukan percobaan dengan Windows Photo Viewer seperti yang ditentukan dalam pertanyaan, Anda akan melihat bahwa itu memang lossless.
Mark Ransom