WPF繪製圓形調色盤

本文使用writeableBitmap類和HSB、RGB模式來繪製圓形的調色盤。

開源項目地址://github.com/ZhiminWei/Palette

RGB為可見光波段三個顏色通道,灰度值範圍為0-255,HSB模式,H是色相:取值範圍0-360°,S是飽和度:取值範圍0-100%,B是亮度:取值範圍是0-100%,本文僅展示了部分程式碼,詳細程式碼見上述項目地址。
程式截圖:
image

中國傳統色示例:
image


渲染圓形調試盤主要程式碼
		private void RenderColorPicker(double brightness)
        {
            bitmap = new WriteableBitmap(radius * 2 + 20, radius * 2 + 20, 96.0, 96.0, PixelFormats.Pbgra32, null);
            Utility.DrawingAllPixel(bitmap, (x, y) =>
            {
                RGBColor rgb = new RGBColor(255, 255, 255, 0);
                double H = 0;
                Vector vector = Point.Subtract(new Point(x, y), new Point(radius + 10, radius + 10));
                var angle = Math.Atan(vector.Y / vector.X) * 180 / Math.PI;
                if (vector.X < 0)
                {
                    H = 270 + angle;
                }
                else if (vector.X > 0)
                {
                    H = 90 + angle;
                }
                else
                {
                    if (vector.Y < 0)
                    {
                        H = 0;
                    }
                    else if (vector.Y > 0)
                    {
                        H = 180;
                    }
                    else
                    {
                        return new RGBColor(255, (int)(255 * brightness), (int)(255 * brightness), (int)(255 * brightness));
                    }
                }
                //計算飽和度
                double S;
                if (vector.Length >= radius)
                {
                    S = 1;
                }
                else
                {
                    S = vector.Length / radius;
                }
                //亮度值
                double B = brightness;
                return new HSBColor(H, S, B).RgbColor;
            });
            this.img.Source = bitmap;
        }
		
		/// <summary>
        /// 繪製所有像素
        /// </summary>
        /// <param name="bitmap"></param>
        /// <param name="action"></param>
        public static void DrawingAllPixel(WriteableBitmap bitmap, Func<int, int, RGBColor> func)
        {
            //跨距 :針對跨距(stride)的計算,WritePixels()方法需要跨距。
            //從技術角度看,跨距是每行像素數據需要的位元組數量。
            //可通過將每行中像素的數量乘上所使用格式的每像素位數(通常為4,如本例使用的Bgra32格式)
            //然後將所得結果除以8,進而將其從位數轉換成位元組數。
            int stride = bitmap.PixelWidth * bitmap.Format.BitsPerPixel / 8;

            for (int y = 0; y < bitmap.PixelHeight; y++)
            {
                for (int x = 0; x < bitmap.PixelWidth; x++)
                {
                    var rgb = func.Invoke(x, y);
                    byte[] colorData = new byte[4] { (byte)rgb.B, (byte)rgb.G, (byte)rgb.R, (byte)rgb.A };

                    bitmap.WritePixels(new Int32Rect(x, y, 1, 1), colorData, stride, 0);
                }
            }
        }
		
Tags: