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.
metadata
image-quality
jpeg
rotation
ocilatingcretin
sumber
sumber
Jawaban:
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:
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.
sumber
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):
Dan hasilnya:
Lalu saya menyimpan gambar sebagai JPEG menggunakan pengaturan default:
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
):Pengamatan langsung
Menggunakan
cmp -l
pada file yang seharusnya memiliki konten yang identik memungkinkan kita untuk melihat di mana file berbeda.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) danCOM
(komentar) untuk metadata. WPV membiarkan bagian tersebutAPP0
tidak tersentuh, tetapi dengan anehnya menambahkan byte nol pada komentar (sehingga diakhiri null)WPV menambahkan dua
APP1
segmen, 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:
Inilah hasilnya:
Saya mengekspor file sebagai JPEG menggunakan pengaturan berikut:
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
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:
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: AC
tabel, 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
):OS (Windows):
GIMP (Linux): 2.8.14 (dari paket
gimp
, versi2.8.14-1+deb8u1
)Window Photo Viewer (sesuai dengan metadata gambar):
sumber
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:
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.
sumber
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.
sumber
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:
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).
sumber
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,
sumber
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?
sumber
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 :
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 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:
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:
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.
sumber
<?xpacket
tag.