2009-12-24 47 views
3

摘要

使用Windows GDI將24位顏色轉換爲索引顏色,看起來GDI選擇的顏色「足夠接近」,即使在提供的調色板中有精確的匹配。GDI無法使用精確的調色板轉換爲索引顏色?

任何人都可以證實這是一個GDI問題,或者我在某個地方犯了一個錯誤嗎?

也許有一個「請檢查顏色匹配的整個調色板」標誌,我沒有找到?

注意:這是關於量化的而不是。源代碼是24位的,但包含256或更少的顏色,因此精確的調色板計算起來微不足道。問題是GDI不使用完整的調色板。

解決方法

我解決此問題通過映射的顏色自己的工作,但我寧願使用GDI所應當更好地優化。問題是,它似乎是「快但錯了」。

詳述

我的源圖像是24位,但使用256(或更少)的顏色。我爲它生成了一個精確的調色板,並要求GDI使用該調色板將圖像轉換爲索引位圖。對於某些像素,即使在調色板的其他地方有精確的顏色,GDI也會選擇相似但不是精確的顏色。這破壞了平滑的漸變。

此問題發生:

  • 的SetDIBitsToDevice
  • 的StretchDIBits
  • 的BitBlt
  • StretchBlt

這個問題不是的發生是:

  • SetPixel或SetPixelV在一個循環(!令人難以置信的慢)
  • 使用自己的代碼進行映射

我已經在測試這一點:

  • 的Windows 7(英偉達硬件/驅動程序)
  • 的Windows Vista(ATI硬件/驅動器)
  • 的Windows 2000(VMware的硬件/驅動器)

在每次測試中我都得到相同的結果。 (不只是錯誤的顏色,但總是錯誤的顏色。)

我不認爲問題是顏色管理(ICM/ICC配置文件/等),因爲大多數的API說他們不使用它,我試過在GDI DC上以及通過V5位圖標題明確地關閉它,我認爲它不適用於我的vanlilla-Win2k VM。

測試項目

代碼一個簡單的Win32/GDI/VS2008的測試項目可以在這裏找到:

http://www.pretentiousname.com/data/GdiIndexColor.zip

內Win32UI.cpp的Test1的功能是實際測試。它有兩個RGBQUADs數組,一個是源圖像,另一個是精確的調色板。它驗證調色板確實是確切的,然後要求GDI使用上面提到的API轉換圖像,每次測試結果。對於每個測試,它會告訴你顏色之後&之前的第一個不正確的像素,或者告訴你所有像素在工作時都是正確的。

謝謝!

感謝您閱讀我的問題!對不起,如果這是我做一些非常愚蠢的事情的結果! :-)

回答

5

我遇到了這個完全相同的問題,最終聯繫了微軟併爲他們提供了一個測試用例。在測試用例中,我提供了一個在24位DIB中具有128種顏色的漸變圖像,然後將其轉換爲8位DIB,該DIB使用包含來自24位圖像的所有128種顏色的顏色表創建。轉換後,8位圖像只使用了128種顏色中的65種。

總結他們的迴應: 這不是一個錯誤,GDI確實使用足夠接近的計算時,下轉換圖像的顏色深度。這在任何地方都沒有記錄,保證所有原始顏色轉換的唯一方法就是自己手動操作像素。

+0

+1的答案似乎是正確的。這個問題已經有一年多的時間了,但它仍然可以幫助未來的人。 – casablanca 2010-11-12 14:50:57

+0

謝謝里斯!令人失望的是要知道這是怎麼回事,但知道我沒有做錯什麼是很好的。 – 2010-11-12 16:18:22

0

你使用的是SetDIBColorTable()This article似乎暗示,畫一個DIB時,它不足以稱之爲SelectPalette(),但SetDIBColorTable()也需要被調用來設置DIB調色板:

但是,如果應用程序使用 DIB部分,您可以通過DIB顏色表創建邏輯 調色板,通常爲 ,然後還可以將DIB 顏色表通過調用SetDIBColorTable()的 傳遞給DIB部分。儘管 RealizePalette()的「Platform SDK」文檔 似乎暗示, RealizePalette()不調整DIB部分的 顏色表。

本文包含有關繪製到可能相關的調色板DIB中的更多信息(請參閱「調色板和DIB部分」一節)。

+0

我已經嘗試過目標DC上的SetDIBColorTable,選擇DIB後,但結果是一樣的。 也嘗試移動SelectPalette調用,以便在DIB選擇後,以及在SelectPalette之後在兩個位置添加RealizePalette調用,但沒有運氣。 我已更新示例代碼以包含SetDIBColorTable調用FWIW。 (先前版本的代碼已移至GdiIndexColor_old.zip) 感謝您的回覆!我會嘗試任何想法。 – 2009-12-27 10:29:52

+0

對不起,聽到沒有伎倆... – 2009-12-27 10:41:58

0

我依稀記得你在調色板被選入DC後還需要調用RealizePalette(hdc)。我們很久以前就拋棄了調色板代碼,甚至代碼甚至不再在我們的源代碼樹中。我從你的代碼中看到,你已經嘗試了這個,但是我建議你可能想再玩一些。

我記得調色板代碼非常脆弱,我們儘快停止使用它。

一些較舊的AVI文件會有一個嵌入文件中的調色板的8位palettized視頻,因此這些文件的播放代碼需要加載一個調色板。我記得,除非你是前臺應用,否則認識並沒有做任何事情,但是應該只適用於屏幕DC而不是內存DC。

如果您搜索了可以播放調色板AVI的示例源代碼,您可能會發現一些顯示獲取調色板的魔術公式。

對不起,我不能更多的幫助。