題:
如果無損旋轉圖像,為什麼文件大小會改變?
oscilatingcretin
2016-11-07 06:11:00 UTC
view on stackexchange narkive permalink

我正在尋找無損旋轉圖像的方法,並偶然遇到了一個可以很好地解釋它的問題:

“ Windows Photo Viewer”旋轉是否無損?

因此,我創建了一個具有隨機像素的256×256 JPEG(Photoshop雲濾鏡),然後使用Windows Picture Viewer對其進行了旋轉。旋轉後,文件大小實際上增加了,但僅在第一次旋轉時才增加。此後每旋轉一次,文件大小就保持不變。我知道它的旋轉是無損的,因為我已經旋轉了多次,而沒有明顯的質量損失,而將257×257的圖像旋轉了20次變得非常有損。

在您的測試中,文件大小增加了多少?
我知道我應該把@JamesSnell包括在內。我剛才使用GIMP的差分clounds過濾器所做的一個最初為14,583字節,但在輪換後更改為23,638字節。如果我們僅討論元數據,則相差9000多個字節,這似乎是很多額外的數據。
-1
似乎還有很多其他元數據。我不會很快就假設所有其他數據都是元數據。在我看來,由於元數據引起的大小差異幾乎應該是一個常數(在幾個字節之內,以表示某些數字的字符串表示形式)。
當提供與問題密切相關的其他信息時,請在問題中而不是在註釋中進行編輯。評論是短暫的,可以不時清理。
如果使用其他(更好)圖像處理工具旋轉,會發生什麼?哎呀,如果WPV保存了原始像素,我不會感到驚訝:-(
上載測試圖像的原始版本會有所幫助。
@CodesInChaos-“前後”文件集將使我們能夠完全回答問題。但是需要以不改變它們的方式提供它們,因此不需要通常的imgur等路線。
難道不是Windows Picture Viewer以較小的壓縮率重新保存了圖片嗎?
WPV點在第一次旋轉時會重新壓縮圖像,但它的壓縮方式是:如果大小是8個後續旋轉的倍數,只需將字節轉換應用於壓縮的字節流即可完成,我的回答正確地解決了這個問題,即使如果是downvotet,則有完整的說明(而且實際上是唯一正確的答案)
作為@DarioOO,,但試圖弄清楚。 *毫不費力地*既不等於也不等冪。重新編碼jpg,可能會有更好的壓縮率(計算機/算法/相機比照相機更好),無論是否旋轉,都是如此。 *“無損”僅表示未壓縮的圖像將是相同的,與原始(壓縮)圖像無關。
-1
MS壓縮庫較差,並且與使用“相同”算法的其他引擎相比,壓縮率通常較低。
八 答案:
Ilmari Karonen
2016-11-07 20:30:23 UTC
view on stackexchange narkive permalink

這很可能是由熵編碼引起的,熵編碼是在對圖像數據進行量化以減小其尺寸之後進行的JPEG壓縮的最後無損階段。

JPEG圖像進行無損旋轉,必須撤消該最終的無損編碼層,將未壓縮的DCT係數打亂,然後再對加密後的係數進行熵編碼。由於熵編碼層的效率取決於每個塊內DCT係數的順序(旋轉圖像會發生變化),因此旋轉圖像文件可能比原始圖像小或大幾個百分點,這不足為奇。 / p>

還有幾種不同的方法可以完成熵編碼步驟,因此完全相同的JPEG圖像的文件大小很可能會根據執行編碼的軟件而有所不同。編碼器之間的一些潛在差異包括:

  • 選擇算術編碼(很少但可能更有效,以前已申請專利)與霍夫曼編碼(更簡單,標準);
  • 順序(每個8x8像素塊一次編碼)與漸進式(所有塊的低頻分量先於高頻分量編碼,通常稍微緊湊)編碼選擇;
  • 選擇使用標準霍夫曼符號表(更快,更簡單,對於非常小的圖像可能更有效)與針對每個圖像進行優化的自定義表的選擇(對於大圖像通常更有效,編碼更慢且更複雜);
  • 如果使用自定義霍夫曼表,則不同的編碼器可能會為相同的圖像數據生成不同的表;
  • 編碼過程本身的各種底層細節,例如是否以及何時包括重啟標記在數據流中,在編碼器之間也可能有所不同。

此外,人們通常使用的“ JPEG文件”實際上包含包裹在 JFIF Exif容器中的JPEG壓縮圖像數據,該容器將圖像數據與一個或多個元數據塊,並引入其自身的複雜性。即使旋轉圖像的軟件實際上並未對JFIF / Exif元數據進行任何實質性更改,僅重新排列數據也可能會影響文件大小幾個字節。

尤其是JFIF / Exif元數據可能包含完整圖片的一個或多個縮略圖,旋轉圖片的軟件確實應該重新生成(或無損旋轉!)縮略圖,以使其與完整圖片的新方向匹配。尺寸的圖像。僅此一項就可以輕鬆解決觀察到的尺寸差異。

對於9KB(60%)的差異,我的猜測是縮略圖。
JPEG可能太簡單了,以至於不值得編碼器去做,但是像x264這樣的視頻編碼器實際上可以在決定速率與失真權衡時,考慮入口編碼器對接下來要輸出的內容進行編碼的能力。 (即,確定每個替代方案可能要花費多少位,並針對有損錯誤進行權衡)。這稱為網格量化。請參閱[x264(Loren Merritt)的作者的[關於在H.264中實施網格量化的注意事項](http://akuvian.org/src/x264/trellis.txt);他從對目標的基本解釋開始。
無論如何,JPEG編碼器可能已經選擇了DCT係數,以使它們可以用熵編碼器很好地壓縮,因此即使是最佳壓縮器也無法使旋轉版本變小。 (因為以不同的順序放置它們可能使它們的壓縮效果不太好。)這對於JPEG幾乎肯定是很小的效果,因為每個8x8塊都是單獨編碼的(重置熵編碼器AFAIK的狀態)。 (h.264中的I幀使用幀內預測,根據同一幀中的其他塊進行預測,因此在相同的視覺質量下它們要比JPEG小。)
2012rcampion
2016-11-09 00:43:04 UTC
view on stackexchange narkive permalink

我繼續並重複了實驗,以查看是否可以解決問題。

過程

我使用生成了一個256×256像素的隨機RGB圖像GIMP中的“固體噪聲”過濾器(“過濾器”>“渲染”>“雲”>“固體噪聲...”)使用默認設置(如下所示):

enter image description here

,結果如下:

enter image description here

然後我使用默認設置將圖像保存為JPEG:

enter image description here

然後我轉移了將該圖像導入Windows,然後通過在文件資源管理器中右鍵單擊該圖像並從菜單中選擇預覽,使用Windows Photo Viewer打開該圖像。然後,我使用底部的按鈕旋轉了圖像,並使用箭頭鍵導航到下一張圖像來保存圖像。

對於下面的每個測試,我都從原始圖像的副本開始,並在保存之前旋轉(單擊旋轉按鈕)相應的次數。以下是重新排序的大小( ls -l -r ):

 大小(以字節為單位)最後修改日期VVVVV VVVVV-rwxrwx-- 1根vboxsf 6258 11月8日11:24 original.jpg-rwxrwx --- 1個根vboxsf 23645 Nov 8 11:30 cw.jpg-rwxrwx --- 1個根vboxsf 23636 Nov 8 11:30 cw-cw.jpg-rwxrwx --- 1個根vboxsf 23649 Nov 8 11:30 cw-cw-cw.jpg-rwxrwx --- 1個根vboxsf 6258 Nov 8 11:27 cw-cw-cw-cw.jpg-rwxrwx --- 1個根vboxsf 23649 Nov 8 11:31 cw-cw-cw-cw-cw.jpg-rwxrwx --- 1個根vboxsf 23649 11月8日11:29 ccw.jpg-rwxrwx --- 1個根vboxsf 23636 Nov 8 11:29 ccw-ccw.jpg-rwxrwx- -1個根vboxsf 23645 11月8日11:29 ccw-ccw-ccw.jpg-rwxrwx-1個根vboxsf 6258 11月8日11:27 ccw-ccw-ccw-ccw.jpg-rwxrwx-1個根vboxsf 23649 11月8日11:30 ccw-ccw-ccw-ccw-ccw.jpg  

立即觀察

  • Windows Photo Viewer(WPV)確實會大大增加尺寸;在此測試中,增加的數量大約是四倍!
  • 所有新圖像都增加到大約相同的大小,但是它們並不相同。
  • 當圖像旋轉360度的倍數時,
  • WPV不會重新編碼或什至重新保存圖像。 (時間戳為11:27,這是第一次復製文件的時間。)

在應該具有相同內容的文件上使用 cmp -l 可以使我們看到

  robert @ unity ../jpeg-rotate-test%cmp -l cw.jpg ccw-ccw-ccw.jpg 2223 63 62 2224 60 71 2226 60 64 2227 60 66robert @ unity ../jpeg-rotate-test%cmp -l cw-cw.jpg ccw-ccw.jpg 2223 63 62 2224 60 71 2226 60 64 2227 62 64robert @ unity ..jpeg-rotate-test%cmp- l ccw.jpg cw-cw-cw.jpg 2223 62 63 2224 71 60 2226 64 60 2227 61 64robert @ 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 61robert @ 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  

這些文件的區別僅在於四個字節(實際上是一個時間戳),這意味著WPV每次都在做相同的事情。現在我們只需要弄清楚是什麼。

詳細觀察

為此,我使用了 JPEGsnoop來查看圖像中的確切內容。

由於輸出的時間很長,因此我已要點鏈接到它們。以下是差異的摘要:

  • GIMP僅將 APP0 (JFIF)和 COM (註釋)段用於元數據。 WPV使 APP0 段保持不變,但奇怪地在註釋中添加了一個空字節(以便它以空終止)。

  • WPV添加了兩個 APP1 段,它們是Exif和XMP元數據。這些段分別為4286和12726字節。它們在一起幾乎佔據了文件大小的全部增長。

  • GIMP生成漸進式JPEG,而WPV生成基線(非漸進式)JPEG。因此,GIMP的圖像有多個掃描段,而WPV圖像只有一個。以我的經驗,漸進圖像有時會稍小。

  • GIMP使用1×1色度二次採樣,而WPV使用2×2色度採樣。這使我相信WPV不會使用“真實的”無損旋轉,除非它能夠以某種方式檢測到這是黑白圖像。

這些問題,我進行了第二次測試。

過程

我遵循了與第一次測試類似的步驟。我使用RGB噪波濾鏡(濾鏡>鼻子> RGB鼻子...)創建了隨機256×256 RGB圖像,設置如下:

enter image description here

結果:

enter image description here

我使用以下設置將文件導出為JPEG:

enter image description here

漸進式已關閉,但是子採樣仍設置為4:4:4(這是1×1子採樣的另一個名稱)。質量提高到98。

我複制了圖像並順時針旋轉了複製件。然後復制旋轉的版本並逆時針旋轉該副本,以便我們可以直接比較原始和WPV處理的副本之間的質量。

結果

  -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  

儘管這次的增加相對較小(大約40%),但絕對增加甚至更大-大約62kB。這表明WMV使用的編碼效率較低。

我將使用 ImageMagick比較兩個圖像:

  robert @ unity。 ./jpeg-rotate-test%比較-verbose -metric AE original-random.jpg cw-ccw-random.jpg null:original-random.jpg JPEG 256x256 256x256 + 0 + 0 8位sRGB 160KB 0.000u 0:00.009
cw-ccw-random.jpg JPEG 256x256 256x256 + 0 + 0 8位sRGB 222KB 0.010u 0:00.010圖片:original-random.jpg通道失真:AE紅色:0綠色:0藍色:0全部:0原始隨機。 jpg = > JPEG 256x256 256x256 + 0 + 0 8位sRGB 0.050u 0:00.020  

原始副本和旋轉副本之間存在零像素不同。因此,即使WPV沒有使用“真正的”無損旋轉,它也做得很好。我懷疑我知道發生了什麼,並且要解釋一下,我將稍微介紹一下JPEG壓縮背後的數學原理。

JPEG壓縮算法將圖像分解為8×8像素的塊。然後,對這些塊中的每個塊進行離散餘弦變換(DCT)。所得的DCT係數將該塊描述為不同頻率波的總和。然後,該算法“丟棄”高頻波中與噪聲和非常小的細節相對應的一些信息。解碼過程使DCT反轉,將存儲的波加在一起以返回塊。

可以旋轉DCT“波”,而無需實際撤消和重做變換(基本上,您可以旋轉所有水平波)成垂直波,反之亦然)。我認為在WPV中發生的事情是圖像實際上已解碼,旋轉然後重新編碼。在重新編碼過程中,由於我們的圖像尺寸在兩個維度上均為8的倍數,因此每個新塊都對應於一個原始塊。重要的是,由於每個塊都沒有高頻分量,因此該算法不會丟棄任何信息,並且可以找到“真正的”無損旋轉將具有的正確的DCT分量。

最後,我是再來看一下JPEG文件的組成部分。結果再次鏈接為要點。比較兩者:

  • WPV映像包含額外的4286 + 2字節的Exif元數據,註釋中的1個額外字節和12726 + 2字節的XMP元數據。這總共是17,017字節的其他元數據。這些數據全部用來做什麼?我用值得信賴的十六進制編輯器和相關標準的副本瀏覽了該文件:

    • Exif元數據的結構類似於TIFF圖像,其中包含許多標籤(其中有方式更加複雜,但我將跳過它)。 Exif段中的大多數字節都包含在兩個相同的標籤中,標籤號為 EA1C (十進制59,932)。在我能找到的任何地方都沒有記錄該標籤號。這兩個標籤都包含2060個``未定義''類型的字節,除了前六個( 1C EA 00 00 00 08 )之外,它們都是空字節。我不知道這些標籤是什麼,為什麼有兩個,為什麼每個標籤都需要2 kB。

    • XMP元數據實際上是一個完整的嵌入式XML文檔。具有名稱間隔和長UUID,僅包含WPV版本字符串(該字符串已在Exif元數據中)。但是,這僅佔大約400個字節。該段的其餘部分是 122個重複的100個空格,後跟一個換行符。總共浪費了超過12,000個字節的空間。

  • 像以前的測試一樣,GIMP和WPV都使用相同的DCT量化表。這意味著他們應該計算出完全相同的DCT係數,這就是為什麼圖像完全相同的原因。我不確定WPV是否恰好使用了相同的量化表,還是從輸入中復制了這些表。

  • 與以前的測試不同,這次WPV使用1 ×1二次採樣,因此實際上可能是在檢測這是彩色圖像(或者至少需要更高的採樣才能無損地重新編碼圖像)。

  • GIMP和WPV使用不同的霍夫曼表(熵編碼步驟的一部分)。 WPV的表大了總共279個字節,並且在一種情況下,包含7倍的代碼。

    從JPEGsnoop的統計數據來看,我們發現其中一些代碼很少使用。例如,在 ID:1,Class:AC 表中,在定義的119個16位代碼中,實際上僅使用了23個。總體而言,在WPV版本中,實際掃描段要大28.5%。

摘要

  • WPV可能沒有做“真正的“無損旋轉”,但旋轉實際上幾乎是無損的。 。

版本信息:

  • OS(Linux)( uname -a ):

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

    enter image description here

  • GIMP(Linux):2.8.14(來自軟件包 gimp ,版本 2.8.14-1 + deb8u1

    enter image description here

  • Window Photo Viewer (根據圖像元數據):

      Microsoft Windows Photo Viewer 10.0.10586.0  
scottbb
2016-11-07 07:04:00 UTC
view on stackexchange narkive permalink

EDIT :在我知道文件的大小增加了大約9 KiB(256×256圖像的9055字節,512×512的9612 KiB)之前,發布了此答案 sup>

很有可能,當您第一次旋轉圖像時,Windows Picture Viewer會執行以下一項(或兩項)操作:

  1. 已添加一個不在原始JPEG圖像中的EXIF標籤(也許是Orientation標籤);
  2. 將信息修改/添加到已經存在的標籤中(也許是Processing Software或Image Software標籤)。
  3. 由於附加的EXIF標籤(和/或現有標籤的其他數據),文件大小增加了。

    隨後的旋轉並沒有增加文件大小,因為所有標籤和/或WPV本應添加/修改的標籤數據已經存在。僅有方向標記發生了變化(也許還有日期/時間標記值)。


    EDIT :幾乎可以肯定的是,說明不能解釋文件中大約9 KiB的附加數據。此外,在沒有其他增加大小的原因的情況下,這種解釋將期望大小的增加或多或少是恆定的(對數值數據的字符串表示之間的一些長度差異進行模運算,可能為幾個字節) 。顯然這不是這裡發生的事情,至少不是完整的解釋。

而EXIF標籤將佔用9kB?好吧,至少這很容易測試-讓OP從旋轉的圖像中刪除EXIF或其他標籤,並查看文件大小如何變化。
@CarlWitthoft的9kB是新信息。編輯提到這一點。
James Snell
2016-11-07 06:57:32 UTC
view on stackexchange narkive permalink

如果不對jpeg編碼器/解碼器進行反向工程,就不可能確定地說。實際上有許多jpeg標準,並且與流行的看法相反,並非所有這些標準都可以在不重新編碼的情況下進行修改。

第一個保存可能是有損重寫為其首選的jpeg風格,隨後的輪換是簡單的元數據調整或直接在DCT表上進行的操作(可能

文件大小的增加可能還包括一些其他元數據,儘管9k看起來很多,但有可能。增加也可以通過添加縮略圖來解決,該縮略圖可能不存在於GIMP的輸出中。我們也許可以直接從文件中獲取更多信息(在WPV之前和之後)。

無論如何,嘗試無損使用jpeg確實是傻瓜的事,因為它僅對某些圖像尺寸有用,並非所有的解碼器和編碼器都是相同的,而是要求這些編輯器直接處理jpeg內容,而您不能依靠jpeg內容...只是因為現在這樣做並不意味著將來會繼續。

您最好的選擇是採用無損格式,並完全避免痛苦。

我根本不相信旋轉jpeg數據首先應該引起重新編碼。
取決於您是否是程序員...我想您不是。您必須專門尋找該優化以進行最小的更改,否則保存操作將從未壓縮的位圖開始。
從鏈接的問題來看,很明顯Windows Photo Viewer確實無損旋轉JPEG。
但是在那種情況下...那是我們不知道的部分。
@James我不是低級程序員,所以我在電視上玩耍:-)。 OP提供了指向準確描述的鏈接,該準確描述何時需要重新編碼,何時不重新編碼。從那次討論中,我推斷他只是在旋轉$ \ frac {\ pi} {2} $。我同意任意角度旋轉都會導致重新編碼,因此,除非將X-by-Y圖像嵌入到至少與斜邊一樣大的區域中,否則這將導致信息丟失。
關鍵不是數學上可行的。這是關於代碼實際執行的操作。 OP看到的是,迭代1會導致文件大小發生變化,但後續迭代不會。這是有原因的,我將進行一些編輯以解釋可能發生的情況。
無損旋轉的原因(這是一個不好的詞;最好是_reversible_)是當圖像的尺寸是8或16的倍數時,即_Minimum Compressible Unit_。如果JPEG不包含部分MCU,則可以對其進行旋轉/翻轉,而無需更改DCT數據塊。在這種情況下,根本不需要重新編碼,只需將索引矩陣更改為這些塊即可。
@scottbb-僅適用於jpeg規範中的某些編碼方法。它依靠軟件來尋找最佳化。我們所知道的是(a)是的,在某些情況下有可能(b)我們不確切知道*此*應用程序在做什麼...
我們非常確定我們知道_that_ WPV對於尺寸倍數為8/16的圖像可逆旋轉。請參閱@Tristan's對Matt Grum對OP中鏈接的問題的回答的評論。特里斯坦(Tristan)在Microsoft的WPV團隊中工作,並且基本上得到了證實。
@scottbb-僅適用於第二和後續版本。我們不知道第一個發生了什麼,而這就是我們試圖在這裡解決的問題。
R.. GitHub STOP HELPING ICE
2016-11-07 22:20:32 UTC
view on stackexchange narkive permalink

僅當圖像尺寸是塊尺寸的倍數(通常[/總是?] 8)時,才可以在不引入邊界偽影的情況下進行無損JPEG旋轉。有關所涉及內容的詳細信息,請參見 jpegtran手冊頁(很抱歉,我沒有很好的規範鏈接;如果找到一個,請隨時進行編輯):

轉置轉換對圖像
尺寸沒有限制。如果圖像尺寸不是iMCU大小的倍數(通常為8或16個像素),則其他轉換操作會很奇怪,因為它們只能以所需的方式轉換完整的DCT係數數據塊。

jpegtran轉換奇數大小圖像時的默認行為
旨在保留轉換集的精確可逆性和數學上的一致性。如所述,轉置能夠翻轉整個圖像區域。水平鏡像使右側的任何部分iMCU列都保持不變,但能夠翻轉圖像的所有行。類似地,垂直鏡像使底部邊緣的任何部分iMCU行都保持不變,但是能夠翻轉所有列。可以將其他轉換構建為轉置和翻轉操作的序列。為了保持一致性,將它們在邊緣像素上的作用定義為與相應的轉置和翻轉序列的最終結果相同。

為實際使用,您可能更希望丟棄任何不可變形的
邊緣像素,而不是在轉換後的圖像的
右邊緣和/或底邊緣上有看起來很奇怪的條紋。為此,請添加-trim開關:

我懷疑Windows Photo Viewer通過在圖像尺寸不是8的倍數時執行解壓縮和超高質量重新壓縮來模擬無損行為來避免此問題,而不是實際執行無損旋轉。一個好的實用程序只會執行實際的無損,偽像和全部操作,或者丟失幾個像素,而不是破壞整個圖像的質量(並增加文件大小)。

與256x256圖像無關。
我誤讀並認為問題出在257x257版本。
Timothy
2016-11-09 05:14:29 UTC
view on stackexchange narkive permalink

我沒有確切的答案,但是有一些可能的原因可以解釋這一點。某些文件類型的工作方式是,該文件類型的圖像的兩個不同代碼不一定會產生不同的圖像。例如,PNG文件類型以這種方式工作,因為它允許透明的背景,但是具有透明背景且除了相同背景為白色的圖像之外,其他圖像都完全相同。如果一個圖像文件每個像素佔用少於3個字節的內存,則該圖像文件被稱為已壓縮。我相信,除了具有透明背景的文件外,沒有兩個PNG文件會生成完全相同的圖像。當您將圖片另存為PNG時,它會將其轉換為生成原始圖像的代碼,除了非常不尋常的圖像(例如每個像素都是所有2 ^ 24種顏色的隨機顏色的圖像)之外,該代碼將佔用的內存少於每像素3個字節,因此保存為PNG被稱為無損壓縮。另一方面,為了節省內存,JPEG圖像文件的代碼只能生成某些圖像。可能有不止一種JPEG文件類型,我不知道它們是否具有該文件類型的兩個不同圖像可以生成完全相同的圖像的屬性。我假設您只是旋轉了一張圖像然後將其另存為JPEG,並且在假設您所做的事情(我不知道是否為真)的情況下會解釋發生的情況。如果有一種方法可以恢復與旋轉並保存之前相同的圖像文件代碼,則所做的旋轉是無損的。您確實做過無損輪換可能並不正確。如果它確實是無損的,則可能的原因是兩個不同的圖像代碼確實會生成完全相同的圖像,而這是您擁有的圖像的代碼,而不是由您擁有哪個圖像來決定旋轉並保存後得到的圖像它。

Cc Dd
2016-11-07 16:51:57 UTC
view on stackexchange narkive permalink

其背後的原因是一些

僅僅是因為壓縮算法,圖像的編碼和壓縮方式才會改變大小。您可以通過將其保存為位圖然後旋轉來進行測試。在那種格式或任何原始格式中,大小應保持不變。如果不是這樣,那麼保存圖像的程序可能會添加新數據,可能是一些元數據或其他內容。

但是為什麼要將jpeg旋轉20次?

如果您閱讀了原始問題中的鏈接,至少對於Windows Picture Viewer_而言,如果JPEG的尺寸是8的倍數,則在WPV_中JPEGS的旋轉是無損轉換。一種簡單的測試方法是旋轉4次(結果與原始方向相同)並執行簡單的逐像素圖像減法。
@scottbb這不一定是Windows圖片查看器的問題。旋轉有損格式的任何內容都必須重新計算壓縮率。以8的倍數旋轉圖像意味著所有內容都適合8位字,並且可能不會以增加偽影的方式進行壓縮。這基於算法的工作原理並在所使用的程序中實現。
CoffeDeveloper
2016-11-07 19:54:09 UTC
view on stackexchange narkive permalink

圖像壓縮的工作原理。通常,任何格式(例如PNG或JPG)都不會在旋轉後保留文件大小。

對於壓縮程序,旋轉的圖像只是一幅不同的圖像,這是由於壓縮啟發式算法的工作原理無法保證會壓縮旋轉的圖像是相同的

當然,如果壓縮是無損的,那麼如果您將圖像旋轉4次,則第四次圖像又是相同的(旋轉直到它變得像原始圖像一樣傾斜) :在這種情況下,它應該再次具有相同的壓縮大小,否則,是因為以下原因之一

  • 添加的元數據:由於某種原因,程序添加了一些文本
  • 壓縮器已更改:如果沒有更改,則程序可以選擇將圖像重新保存為原始圖像,但是如果您進行了更改(甚至4次旋轉90度),它可以決定使用其自己的壓縮器再次重新壓縮圖像(程序不再知道它仍然是同一幅圖像)。
  • 通常,相同的壓縮器(libPNG或libJPG)在不同的實現,相同的庫的不同版本以及不同的壓縮參數下會產生非常不同的結果(有時操作系統和編譯器也會有所不同)。

圖像壓縮通過將圖像壓縮為4x4或其他大小的塊來工作。通常,壓縮器將旋轉的圖像視為不同的圖像,但是由於壓縮的像素塊只是線性分解,因此如果圖像上的塊相同,則可以有效地保持線性轉置/鏡像線性分解矩陣質量:

請注意,此操作必須基於每個功能實施,並且還可以解釋大小的初始增加=>第一次旋轉時,它只是嘗試將圖像壓縮為可旋轉的塊:

  • 如果失敗,則圖像質量會降低
  • 如果成功,則僅增加一次大小,則每次旋轉均保持相同的質量。

  • 僅當圖像由相等的塊組成時,該操作才會成功。 (圖像的大小是塊的大小的倍數)。

scottbb的答案是錯誤的,您可以做一個簡單的測試:

  • 打開原始圖像:對其進行截圖
  • 使用WPV將圖像旋轉4次:對其進行截圖
  • 比較2個屏幕截圖

您將看到圖像已更改(在第一次旋轉時已重新壓縮)。但是,更改的時間是有限的,您現在可以再次旋轉它而不會降低質量(如果圖像的大小是8的倍數)

直接回答OP:

我知道它正在無損旋轉

不是不是無損旋轉,它至少損失了一次質量(第一次旋轉時:因為它應該首先壓縮它以可以旋轉的方式),然後保持其質量。

問題在於無損旋轉,因此避免了重新壓縮。
我對圖形編輯器進行了編程,所以我知道我說的是什麼時候文件被保存=>被壓縮。至少添加到文件中的是“旋轉”信息。
我知道我在說什麼,甚至實現了圖像壓縮器。如果僅實現旋轉就可能實現(這意味著您知道旋轉是對圖像的唯一更改),在一般情況下這是不可能的。 Windows Photo Editor的開發人員似乎做到了這一點
OP詢問的不是一般情況,而是有關那套特定軟件和執行該問題的一種具體情況。您的答案是正確的,它只是回答與OP要求不同的問題。
沒有答案。再讀一遍。我前一陣子做了編輯。
前三個句子仍然有一個不同的問題:“圖像壓縮如何工作”-無損旋轉中沒有壓縮。 “向壓縮器旋轉的圖像”-再次,不調用壓縮器。 “如果壓縮是無損的”-壓縮是有損的。旋轉是無損的。現在,這就是我願意接受的論點。我同意您的觀點,但您的觀點完全不合時宜。順便說一句,我也是一名程序員,我也完成了原始文件的讀寫工作。
您似乎太個人了。它不是完美的旋轉:只需閱讀小型實驗,然後自己做即可。它基本上表明您的最後一條評論是錯誤的。你甚至可能也是一名程序員,但是我不相信你曾經編碼過圖像壓縮器(甚至更簡單的一個)
抱歉,我可以做些什麼實驗來證明呢?因為在鏈接的問題中進行了實驗。我將結果解釋錯誤嗎?
我已經在“畫圖”中創建了圖像,將其旋轉了4次,並且圖像相同,但是大小從1.6 KB躍升到8.1 KB。 Binary diff顯示圖像數據沒有被修改,只是`<?xpacket`標籤中的元數據的很大一部分。
繪製圖像不是一個很好的選擇。我只是用一張真實的照片進行了實驗。您使用的圖像是否有所不同?抱歉,您有哪個Windows版本?
我拍了一張屏幕截圖,將其粘貼到顏料中並裁剪為128x128。看起來好像重複了相同的核心數據塊,但是輪換的版本中添加了巨大的塊,幾乎是空的<< xpacket`。我在這裡沒有適當的二進制差異,所以我無法分辨。在我將它們都上傳到verexif.com之後,它們又恢復了原來的狀態,但彼此相同。但是正如我所說,我是hexeditor手工比較的,所以我可能錯過了很多。 Windows 8.1
如果JPEG的尺寸可以被8整除(或使用二次採樣為16),則可以以90度為增量*無損*旋轉。關鍵是*不*將其解碼為RGB,而是直接使用DCT係數。這是一個專用功能,通常不包含在常規圖像編輯器中。參見例如https://en.wikipedia.org/wiki/Libjpeg#jpegtran。如果您按照問題中的說明使用* Windows Photo Viewer *進行了實驗,您會發現它確實是無損的。


該問答將自動從英語翻譯而來。原始內容可在stackexchange上找到,我們感謝它分發的cc by-sa 3.0許可。
Loading...