首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

WIN32 COLORREF 與 .NET Color 結構互轉完整解析:位元組序、ARGB、BGR 詳解

     編輯:關於C語言

前言

MFC/C++ 與 .NET 混合開發時,顏色值傳遞是常見痛點。Win32 COLORREF 採用 BGR 位元組序,.NET Color 結構 ToArgb() 回傳 AARRGGBB。本文詳細解析位元組序差異,提供雙向轉換標準程式碼。

核心差異:位元組序對比

項目Win32 COLORREF.NET Color.ToArgb()
大小32 位元(實際用 24 位)32 位元
格式0x00BBGGRR(BGR)0xAARRGGBB(ARGB)
Alpha 通道無(最高位元組固定 0)有(AA,0-255)
紅色分量位置最低位元組(bits 0-7)第 3 位元組(bits 16-23)
綠色分量位置中間位元組(bits 8-15)第 2 位元組(bits 8-15)
藍色分量位置最高有效位元組(bits 16-23)最低位元組(bits 0-7)

一、Color → COLORREF 轉換

// 輸入:.NET Color 結構
Color clrColor = Color.FromArgb(123, 200, 12); // R=123, G=200, B=12

// 1. 取得 ARGB 整數
int argb = clrColor.ToArgb(); // 格式:AARRGGBB

// 2. 擷取各分量(注意:ToArgb 回傳 ARGB,紅在 bits 16-23)
int blue  = argb & 0xFF;           // bits 0-7
int green = (argb >> 8) & 0xFF;    // bits 8-15
int red   = (argb >> 16) & 0xFF;   // bits 16-23

// 3. 重組為 BGR 格式(COLORREF)
int colorRef = (blue << 16) | (green << 8) | red; // 0x00BBGGRR

// 結果:colorRef 可直接傳給 Win32 API

二、COLORREF → Color 轉換

// 輸入:Win32 COLORREF (0x00BBGGRR)
int colorRef = 0x000C0C7B; // 範例:B=12, G=200, R=123

// 1. 擷取 BGR 分量
int red   = colorRef & 0xFF;           // bits 0-7 = R
int green = (colorRef >> 8) & 0xFF;    // bits 8-15 = G
int blue  = (colorRef >> 16) & 0xFF;   // bits 16-23 = B

// 2. 建立 .NET Color(忽略 Alpha,預設 255 不透明)
Color clrColor = Color.FromArgb(red, green, blue);

// 一行版
Color clr = Color.FromArgb(colorRef & 0xFF, (colorRef >> 8) & 0xFF, (colorRef >> 16) & 0xFF);

三、完整工具類

public static class ColorConverter
{
    /// .NET Color 轉 Win32 COLORREF (BGR)
    public static int ToColorRef(Color color)
    {
        int argb = color.ToArgb();
        int b = argb & 0xFF;
        int g = (argb >> 8) & 0xFF;
        int r = (argb >> 16) & 0xFF;
        return (b << 16) | (g << 8) | r;
    }
    
    /// Win32 COLORREF (BGR) 轉 .NET Color
    public static Color FromColorRef(int colorRef)
    {
        int r = colorRef & 0xFF;
        int g = (colorRef >> 8) & 0xFF;
        int b = (colorRef >> 16) & 0xFF;
        return Color.FromArgb(r, g, b);
    }
    
    /// 帶 Alpha 的 COLORREF 轉換(若 Win32 擴展支援 Alpha)
    public static Color FromColorRefWithAlpha(int colorRef, int alpha = 255)
    {
        int r = colorRef & 0xFF;
        int g = (colorRef >> 8) & 0xFF;
        int b = (colorRef >> 16) & 0xFF;
        return Color.FromArgb(alpha, r, g, b);
    }
}

四、驗證測試

// 測試往返轉換
Color original = Color.FromArgb(123, 200, 12);
int colorRef = ColorConverter.ToColorRef(original);
Color converted = ColorConverter.FromColorRef(colorRef);

Console.WriteLine($"原始: R={original.R}, G={original.G}, B={original.B}");
Console.WriteLine($"COLORREF: 0x{colorRef:X8}");
Console.WriteLine($"轉回: R={converted.R}, G={converted.G}, B={converted.B}");
Console.WriteLine($"一致: {original.R == converted.R && original.G == converted.G && original.B == converted.B}");

輸出

原始: R=123, G=200, B=12
COLORREF: 0x000C0C7B
轉回: R=123, G=200, B=12
一致: True

五、常見錯誤與注意事項

  • 直接用 Color.ToArgb() 傳給 Win32:錯誤!位元組序不符,顏色會錯亂(紅藍互換)
  • 忽略 Alpha 通道:COLORREF 無 Alpha,轉換時預設 255(不透明)
  • 有號/無號整數:C# int 為有號,位元運算需注意符號延伸,建議用 uint 或 & 0xFF 遮罩
  • MFC RGB() 宏:同樣產生 BGR 格式,RGB(r,g,b) = (r | (g << 8) | (b << 16))

總結

核心口訣:.NET 是 ARGB(紅在中間),Win32 是 BGR(紅在最右)。轉換時務必拆解分量、重新組裝,不可直接傳遞整數值。封裝工具類可避免重複造輪子與錯誤。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved