HOW TO:旋轉色彩

更新:2007 年 11 月

將四度空間中的旋轉視覺化很困難。但是,如果能將其中一個色彩元素固定,視覺化起來就會比較容易。假設已同意將 Alpha 元素固定為 1 (完全不透明),然後就可以用紅色、綠色和藍色三個軸,將三度色彩空間視覺化,如下圖所示。

重新著色

您可以將色彩想像成是三度空間中的一個點。例如,在三度空間中的 (1, 0, 0) 這個點代表紅色,(0, 1, 0) 這個點則代表綠色。

下圖顯示的就是何謂在紅綠平面中將色彩 (1, 0, 0) 旋轉 60 度角。在與紅綠平面平行的平面中旋轉可以想像成是以藍色軸為中心的旋轉。

重新著色

下圖顯示的是如何初始化色彩矩陣,分別執行以這三個座標軸 (紅色、綠色、藍色) 為中心的旋轉。

重新著色

範例

下列範例會使用全部為 (1, 0, 0.6) 一個色彩的影像,並套用以藍色軸為中心的 60 度旋轉。旋轉的角度是在與紅綠平面平行的平面中散出。

下圖左邊顯示的是原始的影像,右邊顯示的是旋轉色彩的影像。

旋轉色彩

下圖顯示以下程式碼執行色彩旋轉的視覺化效果。

重新著色

Private Sub RotateColors(ByVal e As PaintEventArgs)
    Dim image As Bitmap = New Bitmap("RotationInput.bmp")
    Dim imageAttributes As New ImageAttributes()
    Dim width As Integer = image.Width
    Dim height As Integer = image.Height
    Dim degrees As Single = 60.0F
    Dim r As Double = degrees * System.Math.PI / 180 ' degrees to radians
    Dim colorMatrixElements As Single()() = { _
       New Single() {CSng(System.Math.Cos(r)), _
                     CSng(System.Math.Sin(r)), 0, 0, 0}, _
       New Single() {CSng(-System.Math.Sin(r)), _
                     CSng(-System.Math.Cos(r)), 0, 0, 0}, _
       New Single() {0, 0, 2, 0, 0}, _
       New Single() {0, 0, 0, 1, 0}, _
       New Single() {0, 0, 0, 0, 1}}

    Dim colorMatrix As New ColorMatrix(colorMatrixElements)

    imageAttributes.SetColorMatrix( _
       colorMatrix, _
       ColorMatrixFlag.Default, _
       ColorAdjustType.Bitmap)

    e.Graphics.DrawImage(image, 10, 10, width, height)

    ' Pass in the destination rectangle (2nd argument), the upper-left corner 
    ' (3rd and 4th arguments), width (5th argument),  and height (6th 
    ' argument) of the source rectangle.
    e.Graphics.DrawImage( _
       image, _
       New Rectangle(150, 10, width, height), _
       0, 0, _
       width, _
       height, _
       GraphicsUnit.Pixel, _
       imageAttributes)
End Sub
private void RotateColors(PaintEventArgs e)
{
    Bitmap image = new Bitmap("RotationInput.bmp");
    ImageAttributes imageAttributes = new ImageAttributes();
    int width = image.Width;
    int height = image.Height;
    float degrees = 60f;
    double r = degrees * System.Math.PI / 180; // degrees to radians

    float[][] colorMatrixElements = { 
        new float[] {(float)System.Math.Cos(r),  (float)System.Math.Sin(r),  0,  0, 0},
        new float[] {(float)-System.Math.Sin(r),  (float)-System.Math.Cos(r),  0,  0, 0},
        new float[] {0,  0,  2,  0, 0},
        new float[] {0,  0,  0,  1, 0},
        new float[] {0, 0, 0, 0, 1}};

    ColorMatrix colorMatrix = new ColorMatrix(colorMatrixElements);

    imageAttributes.SetColorMatrix(
       colorMatrix,
       ColorMatrixFlag.Default,
       ColorAdjustType.Bitmap);

    e.Graphics.DrawImage(image, 10, 10, width, height);

    e.Graphics.DrawImage(
       image,
       new Rectangle(150, 10, width, height),  // destination rectangle 
        0, 0,        // upper-left corner of source rectangle 
        width,       // width of source rectangle
        height,      // height of source rectangle
        GraphicsUnit.Pixel,
       imageAttributes);

}

編譯程式碼

上述範例是專為與 Windows Form 搭配使用而設計的,而且它需要 PaintEventArgse(即 Paint 事件處理常式的參數)。請以系統中有效的影像檔案名稱和路徑來取代 RotationInput.bmp。

請參閱

參考

ColorMatrix

ImageAttributes

其他資源

Windows Form 中的圖形和繪圖

將影像重新著色