Bir görüntü kayıpsız bir şekilde döndürülürse, dosya boyutu neden değişir?


37

Kayıpsız görüntü döndürme yöntemlerini araştırıyordum ve bu soruya oldukça güzel bir şekilde açıklayan oldu:

"Windows Fotoğraf Görüntüleyicisi" döndürmeler kayıpsız mıdır?

Böylece rastgele pikselli bir 256 × 256 JPEG (Photoshop bulut filtresi) oluşturdum ve ardından Windows Resim Görüntüleyici kullanarak döndürdüm. Döndürmeden sonra, dosya boyutu gerçekte arttı, ancak yalnızca ilk dönüşte. Bundan sonraki her dönüş, dosya boyutu statik kalmıştır. Kayıpsız döndüğünü biliyorum çünkü farkedilir kalite kaybı olmadan defalarca döndürdüm, oysa 20 kez döndürülen 257 × 257 bir görüntü çok kaybedildi.


8
Testlerinizde dosya boyutu ne kadar arttı?
James Snell

3
@JamesSnell Bunu dahil etmem gerektiğini biliyordum. GIMP'nin farklı clounds filtresini kullandığım ilk başlangıçta 14.583 bayt, ancak rotasyondan sonra 23.638 bayt olarak değiştirildi. Bu, yalnızca meta veriler hakkında konuşuyorsak, ek veriye çok benzeyen 9000 baytın üzerinde bir fark.
oscilatingcretin

4
Çok fazla ek meta veri gibi görünüyor. Tüm bu ek verileri meta veri olarak kabul etmek için fazla hızlı olmazdım. Bana göre, meta veriden kaynaklanan boyut farkının neredeyse sabit olması gerekiyor (bazı sayıların dize olarak gösterilmesi için birkaç bayt içinde).
scottbb

4
Soruyla ilgili ek bilgi verirken, lütfen yorumlar yerine soruyu düzenleyin. Yorumlar geçicidir ve zaman zaman temizlenebilmektedir.
scottbb

2
Test resminizin orijinal sürümünü yüklemek faydalı olabilir.
KodlarInChaos

Yanıtlar:


36

Bu, büyük olasılıkla , görüntü verilerinin boyutunu küçültmek için nicelendirildikten sonra JPEG sıkıştırmasının son kayıpsız aşaması olan entropi kodlamasından kaynaklanmaktadır .

Bir JPEG görüntüsü kayıpsız bir şekilde döndürüldüğünde, bu son kayıpsız kodlama katmanı geri alınmalı, ambalajlanmamış DCT katsayıları etrafa karıştırılmalıdır ve daha sonra karıştırılmış katsayıların tekrar entropi kodlanması gerekir. Entropi kodlama katmanının verimliliği, görüntüyü döndüren her bloktaki DCT katsayılarının sırasına bağlı olduğundan, görüntüyü değiştirecek, döndürülen görüntü dosyasının orijinalden yüzde birkaç daha küçük veya daha büyük olması şaşırtıcı olmamalıdır.

Entropi kodlama adımının gerçekleştirilebileceği birkaç farklı yol vardır, bu nedenle aynı JPEG görüntüsünün dosya boyutunun, kodlamayı yapan yazılıma bağlı olarak değişmesi oldukça muhtemeldir. Kodlayıcılar arasındaki potansiyel farklardan bazıları şunlardır:

  • aritmetik kodlama seçimi (nadir fakat potansiyel olarak daha verimli, patentli olmak için kullanılmış) vs. Huffman kodlaması (daha basit, standart);
  • ardışık seçim (her biri 8x8 piksel blok, birer birer birer kodlanır) - ilerici (tüm blokların alçak frekans bileşenleri, yüksek frekans bileşenlerinden önce, genellikle biraz daha kompakt olan) kodlama sırasına göre kodlanır;
  • standart Huffman sembol tablolarını kullanma seçimi (daha hızlı, daha basit, çok küçük görüntüler için daha verimli olabilir) - her bir görüntü için optimize edilmiş özel tablolar (genellikle büyük görüntüler için daha verimli, daha yavaş ve daha karmaşık hale getirmek için);
  • Özel Huffman tabloları kullanılıyorsa, farklı kodlayıcılar aynı görüntü verileri için potansiyel olarak farklı tablolar oluşturabilir;
  • Veri akışına yeniden başlatma işaretleyicilerinin dahil edilip edilmeyeceği ve ne zaman ekleneceği gibi kodlama işleminin çeşitli alt düzey detayları da kodlayıcılar arasında değişebilir.

Ayrıca, "JPEG dosyaları" normalde çalışan insanlar aslında, bir JFIF veya bir Exif kabına sarılı JPEG-sıkıştırılmış görüntü verilerini içerir; Görüntüyü döndüren yazılım aslında JFIF / Exif meta verilerinde önemli bir değişiklik yapmasa da, yalnızca verileri yeniden düzenlemek, dosya boyutunu birkaç bayt olarak etkileyebilir.

Özellikle, JFIF / Exif meta verileri , tam boyutlu görüntünün bir veya daha fazla küçük resmini içerebilir ve görüntüleri gerçekten döndüren yazılım, küçük resimleri tam olarak yeni yönelimi ile eşleşecek şekilde yeniden oluşturmalı (veya kayıpsız olarak döndürmelidir!). boy görüntü Bu tek başına gözlenen boyut farkını kolayca hesaba katabilir.


4
9KB (% 60) fark için, tahminim küçük olurdu.
BlueRaja - Danny Pflughoeft

JPEG, kodlayıcıların yapmaya değmeyecek kadar basit olabilir, ancak x264 gibi video kodlayıcılar, girdi kodlayıcısının, hız-bozulma tradeoff kararları verirken, sıradaki çıktının ne olacağını kodlama yeteneğini düşünebilir. (yani, her alternatifin kaç bit maliyeti olacağına karar vermek ve bunu kayıplı hataya karşı tartmak). Buna kafes nicelemesi denir. Bkz H.264 kafes Nicemlemenin uygulanmasına ilişkin notlar x264 yazarı (Loren Merritt) den; amacın oldukça basit bir açıklaması ile başlar.
Peter Cordes,

Her neyse, nokta şu ki, JPEG kodlayıcı entropi kodlayıcı ile iyi sıkıştırılmış olacak şekilde DCT katsayıları seçmiş olabilir, bu nedenle optimal bir kompresör bile döndürülmüş bir versiyonun bu kadar küçük olmasını sağlayamazdı. (Çünkü onları farklı bir sıraya koymak muhtemelen daha az sıkıştırılmasını sağlar.) Her 8x8 bloğu ayrı ayrı kodlandığından (entropi kodlayıcı AFAIK durumu sıfırlanarak) JPEG için bu kesinlikle küçük bir etki olurdu. (H.264'teki I-kareler, aynı karedeki diğer bloklardan tahmin ederek, aynı görsel kalitede bir JPEG'den daha küçük hale getirerek öngörme için öngörü kullanırlar.)
Peter Cordes

24

Devam ettim ve neler olup bittiğini çözüp çözemeyeceğimi görmek için deneyi tekrarladım.

prosedür

Varsayılan ayarları kullanarak (aşağıda gösterilen) GIMP'deki (Filtreler> İşleyici> Bulutlar> Katı Gürültü ...) "Katı Gürültü" filtresini kullanarak rastgele 256 x 256 piksel RGB görüntü oluşturdum:

görüntü tanımını buraya girin

Ve sonuç:

görüntü tanımını buraya girin

Sonra varsayılan ayarları kullanarak görüntüyü JPEG olarak kaydettim:

görüntü tanımını buraya girin

Sonra görüntüyü Windows'a aktardım ve görüntüyü Dosya Gezgini'ndeki görüntüye sağ tıklayıp menüden Önizleme'yi seçerek Windows Fotoğraf Görüntüleyicisi ile açtım . Daha sonra alttaki düğmeleri kullanarak görüntüyü döndürdüm ve ok tuşlarını kullanarak bir sonraki görüntüye giderek görüntüyü kaydettim.

Aşağıdaki testlerin her biri için orijinal görüntünün bir kopyasıyla başladım ve kaydetmeden önce karşılık gelen sayıda döndürdüm (döndür düğmesine tıklayın). İşte reslting boyutları ( 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

Acil gözlemler

  • Windows Fotoğraf Görüntüleyicisi (WPV) boyutu önemli ölçüde artırır; Bu testte artış miktarı yaklaşık dört kat!
  • Tüm yeni görüntüler aynı boyutta artıyor, ancak aynı değiller.
  • WPV, görüntüyü 360 derecelik bir kat ile döndürdüğünde yeniden kodlamaz veya yeniden kaydetmez. (Zaman damgası, 11:27, dosyaların ilk kopyalandığı zamandır.)

cmp -lAynı içeriğe sahip olması gereken dosyaları kullanmak , dosyaların farklı olduğunu görmemizi sağlar.

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

Bu dosyalar yalnızca dört baytta (aslında bir zaman damgasında) farklılık gösterir, yani WPV her zaman aynı şeyi yapar; Şimdi sadece bunun ne olduğunu bulmamız gerekiyor.

Detaylı Gözlemler

Bunun için resimlerde tam olarak ne olduğunu görmek için JPEGsnoop kullandım .

Çıktılar oldukça uzun olduğu için onlara bir öz olarak bağladım . İşte farklılıkların bir özeti:

  • GIMP, meta veriler için yalnızca bir APP0(JFIF) ve COM(yorum) bölümü kullanır. WPV APP0segmenti el değmeden bırakır , fakat merakla yoruma boş bir bayt ekler (böylece boş bırakılır).

  • WPV APP1, Exif ve XMP meta verileri olan iki segment ekler . Bu segmentler sırasıyla 4286 ve 12726 bayttır. Birlikte, dosya boyutundaki neredeyse tüm artışı hesaba katarlar.

  • GIMP aşamalı bir JPEG, WPV ise temel (aşamalı olmayan) bir JPEG üretir. Bu nedenle GIMP'nin görüntüsünde birden fazla tarama parçası varken, WPV görüntüsünde yalnızca bir tane vardır. Tecrübelerime göre, ilerici görüntü bazen biraz daha küçüktür.

  • GIMP 1 × 1 kroma alt örneklemesini, WPV ise 2 × 2 alt örneklemesini kullandı. Bu, WPV'nin "gerçek" kayıpsız döndürme kullanmadığına, bunun bir şekilde siyah beyaz bir görüntü olduğunu tespit edemediğine inanmamı sağlıyor.

Bu sorunları çözmek için ikinci bir test yaptım.

prosedür

İlk testte benzer adımları izledim. Aşağıdaki ayarlarla RGB Gürültü filtresini (Filtreler> Burun> RGB Burun ...) kullanarak rastgele 256 × 256 RGB görüntü oluşturdum:

görüntü tanımını buraya girin

İşte sonuç:

görüntü tanımını buraya girin

Aşağıdaki ayarları kullanarak dosyayı JPEG olarak verdim:

görüntü tanımını buraya girin

Aşamalı kapatıldı, ancak Alt Örnekleme hala 4: 4: 4 olarak ayarlandı (bu, 1 × 1 alt örneklemenin başka bir adıdır). Kalite 98'e yükseldi.

Görüntüyü kopyaladım ve kopyayı saat yönünde döndürdüm; daha sonra döndürülen sürümü kopyaladı ve bu kopya saat yönünün tersine döndürüldü, böylece orijinal ve WPV işlenmiş kopyası arasındaki kaliteyi doğrudan karşılaştırabiliriz.

Sonuçlar

-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

Bu zamandaki artış göreceli olarak daha küçük olmasına rağmen (yaklaşık% 40), mutlak artış daha da büyüktür - yaklaşık 62 kB. Bu, WMV'nin daha az verimli bir kodlama kullandığını göstermektedir.

İki görüntüyü karşılaştırmak için ImageMagick kullanacağım :

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

Orijinal ve döndürülmüş kopya arasında sıfır piksel var . Dolayısıyla, WPV "gerçek" kayıpsız rotasyon kullanmasa bile, yeterince iyi bir iş yapıyor. Neler olduğunu bildiğimden şüpheleniyorum ve açıklamak için biraz JPEG formatının arkasındaki matematiğe yönlendireceğim.

JPEG sıkıştırma algoritması, bir görüntüyü 8 × 8 piksel bloklara böler. Bu blokların her biri daha sonra bir Ayrık Kosinüs Dönüşümüne (DCT) tabi tutulur . Elde edilen DCT katsayıları bloğu farklı frekans dalgalarının toplamı olarak tanımlar. Algoritma daha sonra gürültüye ve çok küçük detaya karşılık gelen yüksek frekanslı dalgalarda bazı bilgileri “atar”. Kod çözme işlemi DCT'yi tersine çevirir ve bloğu geri almak için depolanan dalgaları birleştirir.

DCT "dalgalarını", dönüşümü geri almadan ve tekrar yapmaksızın döndürmek mümkündür (temel olarak tüm yatay dalgaları dikey dalgalara ve tersi yönde çevirirsiniz). WPV'de olan şey, görüntünün aslında kodu çözüldüğü, döndürüldüğü ve sonra yeniden kodlandığı. Yeniden kodlama işlemi sırasında, resmimizin boyutu her iki boyutta da 8 katı olduğundan, yeni blokların her biri orijinal bloklardan birine karşılık gelir. Önemli olarak, her bloğun yüksek frekanslı bileşenleri olmadığından, algoritma herhangi bir bilgiyi atmaz ve "gerçek" kayıpsız bir rotasyonun sahip olacağı tam olarak doğru DCT bileşenlerini bulur.

Son olarak, JPEG dosyalarının bileşenlerine tekrar bakacağım. Sonuçlar tekrar gists olarak bağlanır . İkisini karşılaştırarak:

  • WPV görüntüsü, fazladan 4286 + 2 bayt Exif meta verisi, yorumda 1 ekstra bayt ve 12,726 + 2 bayt XMP meta verisi içerir. Bu, toplamda 17.017 bayt ek meta veridir. Tüm bu veriler ne için kullanılıyor? Güvenilir hex editörüm ve ilgili standartların bir kopyası ile dosyaya baktım:

    • Meta veri etiketleri numarasını içeren bir TIFF resim gibi yapılandırılmıştır Exif (orada bir yol daha karmaşık, ama doğru üzerinde atlamak gerekir). Exif segmentindeki baytların çoğu, etiket numarasına sahip EA1C(59,932 ondalık) iki özdeş etikette bulunur . Bu etiket numarası bulabildiğim hiçbir yerde belgelenmemiş. Her iki etiket de ilk altı ( 1C EA 00 00 00 08) hariç tümü boş bayt olan 2060 bayt "tanımsız" tür içerir . Bu etiketlerin ne olduğu, neden ikisi olduğu ve neden her birinin 2 kB olması gerektiği hakkında hiçbir fikrim yok.

    • XMP meta verileri aslında sadece WPV sürüm dizesini içeren (zaten Exif meta verilerindeydi) ad alanlı ve uzun UUID'lere sahip tümleşik bir XML belgesidir. Ancak, bu yalnızca yaklaşık 400 baytlık hesap oluşturur. Segmentin geri kalanı 100 alanın 122 tekrarı ve ardından yeni bir satır . Bu, 12,000 baytın üzerinde tamamen boşa harcanan alan.

  • Önceki test gibi, hem GIMP hem de WPV aynı DCT niceleme tablolarını kullanır. Bu, aynı DCT katsayılarını tam olarak hesaplamaları gerektiği ve dolayısıyla görüntülerin tamamen aynı olması gerektiği anlamına gelir. WPV'nin aynı kantitatif tabloları kullanıp kullanmadığını veya tabloları girdiden kopyalayıp kopyalamadığından emin değilim.

  • Önceki testten farklı olarak, bu kez WPV 1x1 alt örnekleme kullanır, bu nedenle bunun renkli bir görüntü olduğunu tespit ediyor olabilir (veya görüntüyü kayıpsız olarak yeniden kodlamak için en azından daha yüksek örneklerin gerekli olduğunu).

  • GIMP ve WPV farklı Huffman masaları kullanır (entropi kodlama adımının bir parçası). WPV için tablolar toplam 279 bayt daha büyüktür ve bir durumda 7 kat kadar kod içerir.

    JPEGsnoop’un istatistiklerine bakıldığında, bu kodların bazılarının nadiren kullanıldığını görebiliriz. Örneğin, ID: 1, Class: ACtabloda tanımlanmış 119 16 bit kodun yalnızca 23'ü kullanılıyor. Genel olarak, gerçek tarama segmenti WPV versiyonunda% 28,5 daha büyüktür.

özet

  • WPV "gerçek" kayıpsız rotasyonlar yapmıyor olabilir, ancak rotasyonlar pratik olarak kayıpsız gibi görünmektedir.

  • Ekstra büyüklük kısmen sabit miktarda ek meta veriden ve kısmen de daha az verimli entropi kodlamasından kaynaklanmaktadır.

Versiyon bilgisi:

  • İşletim Sistemi (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
    
  • İşletim Sistemi (Windows):

    görüntü tanımını buraya girin

  • GIMP (Linux): 2.8.14 (paketten gimp, sürümden 2.8.14-1+deb8u1)

    görüntü tanımını buraya girin

  • Pencere Fotoğraf Görüntüleyicisi (resim meta verilerine göre):

    Microsoft Windows Photo Viewer 10.0.10586.0
    

20

EDIT : Bu cevap, dosyaların boyutlarının yaklaşık 9 KiB (256 x 256 görüntü için 9055 bayt, 512 × 512 görüntü için 9612 KiB) olduğunu bilmeden önce gönderildi.

Her durumda, görüntüyü ilk döndürdüğünüzde, Windows Resim Görüntüleyici aşağıdakilerden birini (veya her ikisini) yaptı:

  1. Orijinal JPEG görüntüsünde olmayan bir EXIF ​​etiketi eklendi (belki de Oryantasyon etiketi);
  2. Daha önce var olan bir etikete değiştirilmiş / eklenmiş bilgi (belki de İşleme Yazılımı veya Görüntü Yazılımı etiketleri).

Bu, ek EXIF ​​etiketi (ve / veya mevcut etiketlere ek veriler) nedeniyle dosya boyutunu artırdı.

Sonraki dönüşler WPV'nin ekleyeceği / değiştirdiği tüm etiket ve / veya etiket verilerinin zaten orada olması nedeniyle dosya boyutunu büyütmedi. Sadece Oryantasyon Etiketi değeri değişti (ve belki de tarih / saat etiketi değerleri).


EDIT : Bu açıklamanın dosyada yaklaşık 9 KiB ek veri hesaba katmayacağı kesin. Ayrıca, boyut artışının başka nedenleri yoksa, bu açıklama, boyuttaki artışın az çok sabit olacağını bekler (sayısal verilerin, muhtemelen birkaç baytlık dize gösterimleri arasında bazı uzunluk farklarını modüle eder). Burada ne olduğu belli değil, en azından tam bir açıklama değil.


1
Ve bir EXIF ​​etiketi 9kB'ı alacak mı? Eh, bu en azından test etmek kolaydır - OP'nin EXIF ​​veya döndürülmüş görüntüdeki diğer etiketlerin silinmesini ve dosya boyutunun nasıl değiştiğini görün.
Carl Witthoft

2
@CarlWitthoft 9kB yeni bir bilgidir. Bunu söylemek için düzenleme.
scottbb

3

Tersine mühendislik olmadan jpeg en / decoder'ı kesin olarak söylemek mümkün değil. Aslında bir dizi jpeg standardı vardır ve halkın inancının aksine, hepsi yeniden kodlama olmadan değiştirilemez.

Şartla ki, ilk mümkün olduğu da tercih JPEG lezzet bir kayıplı yeniden yazma ve sonraki dönme basit bir meta veri çimdik ya da (bir kodlama şeması için mümkündür) DCT doğrudan masada bir işlem bulunmaktadır.

Dosya boyutundaki artış ayrıca bazı ek meta veriler içerebilir, ancak 9k çok görünüyor olsa da mümkündür. Artış, GIMP'den çıktıda bulunmayan bir küçük resmin eklenmesiyle de hesaplanabilir. Doğrudan dosyalardan daha fazla bilgi edinebiliriz (WPV öncesi ve sonrası).

Her durumda, jpeg ile kayıpsız çalışmaya çalışmak gerçekten bir aptaldır, çünkü sadece bazı görüntü boyutlarında kullanışlıdır, tüm kod çözücüler ve kodlayıcılar aynı değildir ve bu editörlerin doğrudan olamayacağınız jpeg içeriği ile çalışmasını gerektirir. durum ... Sadece şimdi olduğu için gelecekte de devam edeceği anlamına gelmez.

En iyisi, kayıpsız bir formatta çalışmak ve acıdan tamamen kaçınmak.


2
Jpeg verilerinin döndürülmesinin her şeyden önce yeniden kodlamaya neden olması gerektiğine hiç inanmıyorum.
Carl Witthoft

Bir programcı olup olmadığına bağlı olarak ... Sanırım sen değilsin. Bu minimum değişikliği yapmak için özel olarak bu optimizasyonu arıyor olmalısınız, aksi takdirde tasarruf işlemi sıkıştırılmamış bitmap'ten başlar.
James Snell

3
Bağlantılı sorudan, Windows Fotoğraf Görüntüleyicisi'nin JPEG'leri kayıpsız döndürdüğü açıktır.
vclaw

2
@James Ben düşük seviyeli bir programcı değilim, tho 'TV'de oynarım :-). OP, yeniden kodlamanın ne zaman yapılacağına ve ne zaman yapılmadığına dair doğru bir açıklama için bir bağlantı sağladı. Bu tartışmadan yalnızca $ \ frac {\ pi} {2} $ döndürdüğünü anladım. Rasgele açı döndürmenin yeniden kodlamaya neden olduğuna ve bunun için en az hipotenüs kadar büyük bir bölgeye gömülmediği sürece bu konuda bilgi kaybına neden olacağını kabul ediyorum.
Carl Witthoft

1
Biz oldukça emin bildiğimiz ediyoruz o WPV 8/16 boyutları katları ile görüntüler için geri dönüşümlü olarak dönmektedir. @ Tristan’ın Matt Grum’un OP’de bağlantılı soruya verdiği cevaba yaptığı yorumu görün. Tristan, Microsoft'ta WPV ekibinde çalıştı ve temelde doğruladı.
scottbb

1

Kayıpsız JPEG döndürme, ancak görüntü boyutları blok boyutunun katları ise (tipik olarak [/ her zaman?] 8) sınır eserleri kullanılmadan mümkündür. Bkz jpegtran adam sayfasını (üzgünüm bunun için iyi bir standart bağlantıyı yoktur; bir tane bulursan düzenlemek çekinmeyin) da işin dair ayrıntılı bilgi için:

Transpozisyon dönüşümünün görüntü
boyutlarıyla ilgili herhangi bir kısıtlaması yoktur . Diğer dönüşümler, eğer görüntü boyutları iMCU boyutunun bir katı değilse (genellikle 8 veya 16 piksel), oldukça garip çalışır, çünkü DCT katsayısı verilerinin sadece tüm bloklarını istenen şekilde dönüştürebilirler.

Tek boyutlu bir görüntüyü dönüştürürken jpegtran'ın varsayılan davranışı , dönüşüm kümesinin
tam tersinirliğini ve matematiksel
tutarlılığını korumak için tasarlanmıştır . Belirtildiği gibi, devrik
tüm görüntü alanını çevirebilir. Yatay yansıtma, herhangi bir kısmi iMCU sütununu sağ kenarına dokunmadan bırakır, ancak görüntünün tüm satırlarını çevirebilir. Benzer şekilde, dikey yansıtma alt kenardaki herhangi bir kısmi iMCU sırasına dokunmadan bırakır ancak tüm sütunları çevirebilir. Diğer dönüşümler transpozisyon ve çevirme işlemlerinin sekansları olarak oluşturulabilir; Tutarlılık için, kenar pikseller üzerindeki eylemlerinin, karşılık gelen transpo-flip dizisinin son sonucuyla aynı olduğu tanımlanır.

Pratik kullanım için, dönüştürülmüş bir görüntünün sağ ve / veya alt kenarları
boyunca tuhaf görünümlü bir şerit kullanmak yerine dönüştürülemeyen kenar piksellerini atmayı tercih edebilirsiniz
. Bunu yapmak için -trim anahtarını ekleyin:

Görüntü boyutları aslında kayıpsız döndürme yapmak yerine 8'in katları olmadığında kayıpsız davranışı simüle etmek için dekompresyon ve aşırı yüksek kaliteli yeniden sıkıştırma uygulayarak Windows Fotoğraf Görüntüleyicisi'nin bu sorundan kaçındığından şüpheleniyorum. İyi bir yardımcı program, gerçek kayıpsız, artefaktları ve hepsini yapar veya tüm görüntünün kalitesini bozmak yerine (ve dosya boyutunu artırmak) birkaç piksel düşürür.


1
256x256 görüntü için anlamsız.
ths

Yanlış anladım ve sorunun 257x257 sürümü için olduğunu düşündüm.
R. 17

0

Kesin bir cevabım yok ama bunun neden olduğuna dair bazı teoriler var. Bazı dosya türleri bu şekilde çalışır, bu dosya türünün bir görüntüsü için iki farklı kod mutlaka farklı görüntüler üretmez. Örneğin, PNG dosya türü bu şekilde çalışır, çünkü saydam bir arka plana izin verir, ancak saydam bir arka planı olan bir görüntü ve aynı arka planın beyaz olması dışında aynı olan, tam olarak aynı şekilde görünür. Bir görüntü dosyasının, piksel başına 3 bayttan daha az bellek kaplaması durumunda sıkıştırıldığı söylenir. Saydam bir arka plana sahip olanlar dışında, iki PNG dosyasının aynı görüntüyü üretmediğine inanıyorum. Bir görüntüyü PNG olarak kaydettiğinizde, onu orijinal görüntüyü üreten bir koda dönüştürür ve her pikselin tüm 2 ^ 24 renklerinin rastgele bir rengi olduğu biri gibi çok olağandışı görüntüler dışında Kod, piksel başına 3 bayttan daha az bellek alacağından PNG olarak kaydetmenin kayıpsız sıkıştırma olduğu söylenir. Öte yandan, bellekten tasarruf etmek için, bir JPEG görüntü dosyasının kodu ile yalnızca belirli görüntüler oluşturulabilir. Muhtemelen birden fazla JPEG dosya tipi vardır ve bu dosya tiplerinden iki farklı görüntünün aynı resmi oluşturabileceği özelliğine sahip olup olmadığını bilmiyorum. Bir görüntüyü sadece birkaç kez döndürdüğünüzden sonra JPEG olarak kaydettiğinizi ve bunun doğru olmadığını bilmediğim, yaptığınız şeyin ne olduğu ile ilgili bir açıklama yapacağını farz ediyorum. Döndürmeden ve kaydetmeden önceki aynı resim dosyası kodunu geri almanın bir yolu varsa, yaptığınız rotasyon kayıpsızdır. Gerçekten kayıpsız bir rotasyon yaptığınız doğru olmayabilir. Eğer gerçekten kayıpsız olsaydı,


-3

Bunun arkasındaki nedenler birkaçı

görüntülerin kodlanma ve sıkıştırılma şekli, yalnızca sıkıştırma algoritması nedeniyle boyutu değiştirecektir. Bunu bir bitmap olarak kaydederek ve sonra döndürerek test edebilirsiniz. Bu formatta veya herhangi bir ham formatta boyut aynı kalmalıdır. Bu durumda değilse, görüntüyü kaydeden program, muhtemelen bir miktar meta veri veya başka bir veri ekliyor.

Ama neden 20 kez bir jpeg döndürüyorsun?


2
Orijinal sorudaki bağlantıyı okursanız, en azından Windows Resim Görüntüleyici için , bir JPEG boyutunun 8 katının katı olması durumunda , WPV'deki JPEG'lerin dönüşleri kayıpsız dönüşümlerdir. Bunu test etmenin basit bir yolu (orijinaliyle aynı yönde sonuçlanan) 4 kez döndürerek basit bir piksel piksel görüntü çıkarma işlemi yapmaktır.
scottbb

@scottbb Bu sadece pencere resim görüntüleyicide bir sorun değildir. Kayıplı bir formatta dönen herhangi bir şey sıkıştırmayı yeniden hesaplamalıdır. bir görüntüyü 8'in katlarına çevirmek, her şeyin 8 bitlik kelimelerle uyduğu ve eserler katacak şekilde sıkıştırılamayacağı anlamına gelir. Bu, algoritmanın nasıl çalıştığına ve kullanılan programda nasıl uygulandığına dayanmaktadır.
Cc Dd

-3

Görüntülerin sıkıştırılmasının nasıl çalıştığı yüzünden . Genel olarak PNG veya JPG gibi hiçbir format, döndürme işleminden sonra dosya boyutunu korumaz.

Kompresöre döndürülen görüntü yalnızca farklı bir görüntüdür, sezgisel çalışmanın sıkıştırılmasından dolayı döndürülen görüntüyü aynı şekilde sıkıştıracağının garantisi yoktur .

Elbette, sıkıştırma kayıpsızsa, görüntüyü 4. kez 4 kez döndürürseniz, görüntü yine aynıdır (orijinal olarak yatırılıncaya kadar döndürülür): bu durumda, aynı sıkıştırılmış boyutta olmalıdır; bunun nedeni, aşağıdaki nedenlerden biri :

  • Meta veri eklendi: program bazı nedenlerden dolayı bir miktar metin ekledi
  • Kompresör değişti: değişiklik yapılmazsa, program yalnızca görüntüyü orijinal olarak yeniden kaydetmeyi seçebilir, ancak herhangi bir değişiklik uygularsanız (90 derecelik 4 dönüş bile olsa) görüntüyü kendi görüntüsünü kullanarak yeniden sıkıştırmaya karar verebilir kompresör (program artık aynı görüntü olduğunu bilmiyor).
  • Genel olarak, aynı kompresör (libPNG veya libJPG), farklı uygulamalar, aynı kütüphanenin farklı sürümleri ve farklı sıkıştırma parametreleriyle (ayrıca işletim sistemi ve derleyici bazen burada bir fark yaratır) çok farklı sonuçlar verir.

Görüntü sıkıştırma, görüntüleri 4x4 veya diğer boyutlardaki parçalara sıkıştırarak çalışır. Genel olarak, bir kompresör, döndürülmüş bir görüntüyü farklı bir görüntü olarak görür, ancak sıkıştırılmış bir piksel öbeği yalnızca doğrusal bir ayrıştırma olduğundan, görüntüdeki öbekler aynıysa, yalnızca aynı şekilde aynı olan doğrusal bozunma matrislerini Dönüştürmek / Aynalamak mümkündür kalite:

Bunun özellik bazında uygulanması gerektiğini ve boyuttaki ilk artışı => ilk dönüşte açıklamasının, görüntüyü döndürülebilen parçalarda sıkıştırmaya çalıştığını unutmayın:

  • Bunu başaramazsa: görüntü kalitesi düşer
  • Başarılı olursa, boyutu yalnızca bir kez artırır, ardından her dönüş aynı kaliteyi korur.

  • Bu işlem yalnızca görüntü eşit boyutta yapılırsa başarılı olur. (görüntünün boyutu, yığın boyutunun katlarıdır).

Scottbb yanlış cevap veriyor ve basit bir test yapabilirsiniz:

  • Orijinal resmi aç: Ekran görüntüsü
  • Resmi WPV ile 4 kez döndür: Ekran görüntüsü
  • 2 ekran görüntüsünü karşılaştırın

Görüntünün değiştiğini göreceksiniz (ilk dönüşte yeniden sıkıştırılmıştır). Ancak bu değişiklik zamanla sınırlıdır, şimdi kalite kaybı olmadan tekrar döndürebilirsiniz (görüntünün 8 katı olan bir boyutu varsa)

OP’ye doğrudan cevap vermek için:

Kayıpsız döndüğünü biliyorum

Kayıpsız bir şekilde dönmemesi durumunda, en az bir kere (ilk dönüşte: ilk önce döndürülebilecek şekilde sıkıştırması gerekir) kalitesini yitirmez.


1
Soru kayıpsız rotasyon hakkında, bu nedenle yeniden sıkıştırma kaçınılmasıdır.
Ajan_L

5
OP genel durum hakkında değil, tam olarak bu özel yazılım parçası ve bunu yapan özel bir vaka hakkında sorular sordu. Cevabınız yanlış değil, sadece OP'nin istediğinden farklı bir soruyu cevaplıyor.
Ajan_L

1
İlk 3 cümle hala farklı bir soruyla ilgili: "görüntülerin sıkıştırılmasının nasıl çalıştığı" - kayıpsız rotasyonda sıkıştırma yok. "Kompresöre döndürülen görüntü" - tekrar, kompresör çağrılmaz. "eğer sıkıştırma kayıpsızsa" - sıkıştırma kayıplıdır. Dönme kayıpsızdır. Şimdi, bu tartışmayı ne kadar uzağa almaya razıyım. Amacınızı görebiliyorum, aynı fikirdeyim ama burası tamamen yerinde değil. BTW, ben de bir programcı ve ham dosya okuma ve yazma payımı yaptım.
Ajan_L

1
Paint'te bir resim oluşturdum, 4 kez döndürdüm ve özdeş, ancak yine de boyutu 1.6'dan 8.1 KB'a çıktı. İkili fark, görüntü verilerinin dokunulmadığını gösterir, bu sadece <?xpacketetiketlerdeki büyük meta veri yığınıdır .
Ajan_L

1
Bir JPEG'in boyutları 8 (veya alt örneklemeli 16) ile eşit şekilde bölünebilirse, kayıpsız olarak 90 derecelik artışlarla döndürülebilir . Anahtar, RGB'nin sonuna kadar şifresini çözmemek, doğrudan DCT katsayılarıyla çalışmaktır. Genel bir resim düzenleyicide bulunmayan özel bir işlevdir. Örneğin, en.wikipedia.org/wiki/Libjpeg#jpegtran adresini ziyaret edin . Denemenizi soruda belirtildiği gibi Windows Fotoğraf Görüntüleyicisi ile gerçekleştirdiyseniz , bunun gerçekten kayıpsız olduğunu göreceksiniz.
Mark Ransom 20
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.