簡體   English   中英

.NET Color中的RGB格式

[英]RGB formats in .NET Color

我一直在查看關於Color的文檔(我正在編寫一個C#程序) 將顏色設置為Color

如果你看到它,它會根據RGB的8位值設置顏色。 換句話說,這是我想的RGB-888格式......我猜。

我在相機中使用的是RGB-565格式(R,B為5位,G為5)有沒有辦法根據這種格式將顏色設置為顏色而不是888? 或者我必須自己手動完成此操作?

我最近根據ScummVM項目通用顏色格式轉換器編寫了代碼來完成這項工作

答案是關於StackOverflow的另一個問題,雖然這個問題並不是真的重復,但我認為答案是,所以我只是鏈接到它:

使用10位深度數字圖像

請注意,我不確定每個因素的乘數是如何在5-6-5格式上起作用的。 6位組件是否更准確? 在這種情況下,自動轉換系統將完成這項工作。

無論如何,通過上面鏈接的代碼,這個例子應該完全符合您的需求。 這里它用於轉換自定義5-5-5-1 RGBA格式:

//bytes 84 21 ==> 0x8421 (BE) ==bin==> 1000 0100 0010 0001 ==split==> 10000 10000 10000 1 ==dec==> 16 16 16 1 (RGBA) ==adjust==> 128 128 128 255
// values in constructor are: bytes per pixel, amount of bits and amount to shift for getting R, G, B and A components, and data endianness.
private static PixelFormatter SixteenBppFormatter = new PixelFormatter(2, 5, 11, 5, 6, 5, 1, 1, 0, false);

protected static Byte[] Convert16bTo32b(Byte[] imageData, Int32 startOffset, Int32 width, Int32 height, ref Int32 stride)
{
    Int32 newImageStride = width * 4; ;
    Byte[] newImageData = new Byte[height * newImageStride];
    for (Int32 y = 0; y < height; y++)
    {
        for (Int32 x = 0; x < width; x++)
        {
            Int32 sourceOffset = y * stride + x * 2;
            Int32 targetOffset = y * newImageStride + x * 4;
            Color c = SixteenBppFormatter.GetColor(imageData, startOffset + sourceOffset);
            PixelFormatter.Format32BitArgb.WriteColor(newImageData, targetOffset, c);
        }
    }
    stride = newImageStride;
    return newImageData;
}

您需要做的就是使用5-6-5格式的正確位分配定義您自己的PixelFormatter。

您確實需要調查Bitmap.LockBits()以從圖像中獲取原始的16位數據,並將該數據寫入新的32位ARGB圖像。 我在這個答案中提到的BuildImage函數應該顯示如何處理寫作。 read方法實際上要簡單得多:

/// <summary>
/// Gets the raw bytes from an image.
/// </summary>
/// <param name="sourceImage">The image to get the bytes from.</param>
/// <param name="stride">Stride of the retrieved image data.</param>
/// <returns>The raw bytes of the image</returns>
public static Byte[] GetImageData(Bitmap sourceImage, out Int32 stride)
{
    BitmapData sourceData = sourceImage.LockBits(new Rectangle(0, 0, sourceImage.Width, sourceImage.Height), ImageLockMode.ReadOnly, sourceImage.PixelFormat);
    stride = sourceData.Stride;
    Byte[] data = new Byte[stride * sourceImage.Height];
    Marshal.Copy(sourceData.Scan0, data, 0, data.Length);
    sourceImage.UnlockBits(sourceData);
    return data;
}

請注意,在編輯原始圖像字節的所有情況下,“stride”和“width”之間的區別。 在許多格式中,圖像中的一行像素被填充到下一個四個字節的倍數,所以你不能只是讀取並處理它作為數組,假設它是所有的圖像數據; 那些填充字節會很快崩潰。 如我的示例代碼中所示,將我的16bpp格式轉換為ARGB,您確實需要逐行執行此操作,並且每行確保您僅使用仍在(寬度*每像素的字節數)范圍內的數據。

我注意到,對於可能改變步幅的所有函數,建議將其作為ref參數給出。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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