我想在這個問題前面加上我只是在玩耍和學習的問題。我不想使用本機內置方法或外部庫來解決問題。我也不想以其他類似問題中肯定可以實作和描述的更優化的方式來做到這一點。我只想了解我所看到的以及為什么我手動解碼標頭。
簡短版本:我正在嘗試PNG從二進制格式讀取標頭位元組。我似乎總是得到 8 的位深度值,但檔案的 Windows 屬性顯示不同的值(例如 32、24)。
我還使用顯示位深度為 8 的
這是我的示例代碼(來自 LinqPad,但很容易轉移到程式中)
var rawFileStream = new System.IO.FileStream("c:\\temp\\test2.png", FileMode.Open);
var buffer = new char[4].ToList();
while (!IsHeaderInBuffer())
{
ReadIntoBuffer();
}
var width = BitConverter.ToInt32(ReadNBytesAsLittleEndian(4)).Dump();
var height = BitConverter.ToInt32(ReadNBytesAsLittleEndian(4)).Dump();
var bitdepth = ReadSingle().Dump();
var colorType = ReadSingle().Dump();
var compression = ReadSingle().Dump();
var filter = ReadSingle().Dump();
var interlace = ReadSingle().Dump();
int ReadSingle()
{
return rawFileStream.ReadByte();
}
byte[] ReadNBytesAsLittleEndian(int n)
{
var result = new byte[n];
for (int i = 0; i < n; i )
{
var b = rawFileStream.ReadByte();
result[n - i - 1] = (byte)b;
}
return result;
}
void ReadIntoBuffer()
{
buffer.Remove(buffer.First());
buffer.Add((char)rawFileStream.ReadByte());
}
bool IsHeaderInBuffer()
{
var enumerator = "IHDR".GetEnumerator();
return buffer.All(x =>
{
enumerator.MoveNext();
return x == enumerator.Current;
});
}
上面的輸出是:
1197
883
8
6
0
0
0
uj5u.com熱心網友回復:
Windows檔案屬性中顯示的位深度與 PNG 格式的位深度不同。
Windows 顯示每個像素的總位數(在您的情況下為 32,假設您有 4 通道 RGBA 影像)。
正如您在WikiPedia PNG 頁面width中看到的那樣,PNG 標頭在和之后有 2 個相關欄位height:
- 位深度(1 位元組,值 1、2、4、8 或 16)
- 顏色型別(1 位元組,值 0、2、3、4 或 6)
即從 PNG 的角度來看,位深度是單個通道的位數。
您需要將它乘以通道數(基于顏色型別)以獲得每個像素的總位數,如 Windows 檔案屬性中所示。
更新:
您在評論中提到您案例中的顏色型別是 6。根據規范,這意味著:
每個像素都是一個 R、G、B 三元組,后跟一個 alpha 樣本。
這意味著您有 4 個通道,每個通道有 8 位,因此每個像素的總位數為 32,如 Windows 檔案屬性中所報告的那樣。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/533358.html
下一篇:在C#中訂購IGrouping
