簡體   English   中英

如何在 MacOS 上創建每像素 16 位的 bitmap?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM