![](/img/trans.png)
[英]What is the difference between Bits Per Sample, Samples Per Pixel and Bytes Per Pixel for a Bitmap Image?
[英]How to create a bitmap with 16 bits per pixel on MacOS?
我想創建一個每像素 16 位的 bitmap,但是當我指定任何像素格式時:
PixelFormat.Format16bppArgb1555, PixelFormat.Format16bppGrayScale, PixelFormat.Format16bppRgb555, PixelFormat.Format16bppRgb565
他們都拋出System.NotImplementedException
並帶有錯誤消息"Not Implemented"
。 我無法手動為每個像素分配 16 位,因為Bitmap.SetPixel()
只允許您將一個字節設置為 alpha、red、green 或 blue(所以我需要使用需要特定像素格式的編組)。 我沒有為每個顏色值設置一個字節,而是嘗試在紅色、綠色和藍色之間分配 16 位。 例如紅色 5 位,綠色 5 位,藍色 5 位。
下面是引發System.NotImplementedException
的每像素 16 位像素格式之一的示例:
Bitmap bitmap = new Bitmap(width, height, PixelFormat.Format16bppArgb1555);
我的系統是MacOS。
System.Drawing
不支持所有平台上的每種像素格式。 一旦我收集了差異(請參閱不同平台上可能的像素格式的限制部分)。 我認為 MacOS 使用與 Linux 版本相同的 package 版本。
As Bitmap
cannot save images preserving the Format16bppArgb1555
pixel format anyway I suggest you to create a Bitmap
instance using the closest compatible format (for example, Format32bppArgb
instead of Format16bppArgb1555
), and if you really want to transform the colors into the ARGB1555
color space,您可以使用我為比較鏈接的相同庫將Quantize
方法與PredefinedColorsQuantizer.Argb1555
一起使用。 您可以從NuGet下載它。
免責聲明:我沒有在 MacOS 上測試它,但它在 Linux (Ubuntu) 中工作。
我沒有為每個顏色值設置一個字節,而是嘗試在紅色、綠色和藍色之間分配 16 位。 例如紅色 5 位,綠色 5 位,藍色 5 位。
編輯:我已經在開發下一個版本,它將允許在任何平台上使用帶有任何PixelFormat
的托管 bitmap 數據。 請參閱公共BitmapDataFactory.CreateBitmapData方法(在公共版本中尚不可用,但如果您查看Development
分支,您已經可以使用它)。
更新:
我有圖像字節(即只表示圖像的字節,沒有標題),我正在測試圖像字節解碼為的圖像格式是否為每像素 16 位。
現在我明白了為什么需要以 16 位原始格式設置像素。 與在 Linux/MacOS 中一樣, System.Drawing.Bitmap
具有有限的支持,如果您創建托管 bitmap 數據,這是最簡單的解決方案,如上所述。
注意:我發布了一個pre-release ,它使BitmapDataFactory.CreateBitmapData
方法可用,而無需檢查我的開發分支。 現在您可以將任何PixelFormat
的原始字節轉換為Bitmap
,如下所示:
(當然,如果pfGuess
不是實際格式,結果可能會很混亂)
public Bitmap ToBitmap(byte[] rawData, PixelFormat pfGuess, Size size)
{
// the result bitmap will be ARGB32, which works on every platform
Bitmap result = new Bitmap(size.Width, size.Height);
// we create an accessor for the result so we can quickly copy the translated pixels
using var bitmapDataDst = result.GetWritableBitmapData();
// For the managed source any pixel format will work.
// Please note though that unlike System.Drawing.Bitmap images,
// managed bitmap data never has padding bytes at the end of each line.
// So if your rawData has padding (eg. when size has odd width and pf is 16bpp),
// then maybe the best if you include the padding in width.
// See https://docs.microsoft.com/en-us/windows/win32/medfound/image-stride for details
using var bitmapDataSrc = BitmapDataFactory.CreateBitmapData(size, pfGuess);
// Checking if rawData is long enough. RowSize is the width in bytes.
if (rawData.Length < bitmapDataSrc.RowSize * size.Height)
throw new ArgumentException("rawData is too short");
int currentByte = 0;
// iterating through rows
for (int y = 0; y < size.Height; y++)
{
var rowSrc = bitmapDataSrc[y]; // has the specified pixel format
var rowDst = bitmapDataDst[y]; // has ARGB32 pixel format
// writing raw pixels
for (int x = 0; x < bitmapDataSrc.RowSize; x++)
rowSrc.WriteRaw<byte>(x, rawData[currentByte++]);
// copying the pixels interpreted as pfGuess to result
for (int x = 0; x < size.Width; x++)
rowDst[x] = rowSrc[x];
}
// The result bitmap is now populated from the arbitrarily interpreted raw data.
// As it has ARGB32 format you can save it on any platform without any issues.
return result;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.