C#教程

关注公众号 jb51net

关闭
首页 > 软件编程 > C#教程 > WPF颜色选择器

基于WPF开发简单的颜色选择器

作者:WPF开发者

这篇文章主要介绍了如何基于WPF实现简单的颜色选择器,文中的示例代码讲解详细,对我们学习或工作有一定帮助,需要的小伙伴可以参考一下

 WPF 简单实现颜色选择器

实现代码

1)新增 xaml 代码如下:

<Canvas x:Name="canvas" MouseLeftButtonDown="canvas_MouseLeftButtonDown">
                <Canvas.Background>
                    <ImageBrush ImageSource="{Binding Bitmap}" />
                </Canvas.Background>
                <Thumb
                    x:Name="thumb"
                    Canvas.Left="0"
                    Canvas.Top="0"
                    Width="20"
                    Height="20"
                    Background="Transparent"
                    BorderBrush="Black"
                    BorderThickness="2"
                    DragDelta="Thumb_DragDelta">
                    <Thumb.Template>
                        <ControlTemplate TargetType="Thumb">
                            <Border
                                Background="{TemplateBinding Background}"
                                BorderBrush="{TemplateBinding BorderBrush}"
                                BorderThickness="{TemplateBinding BorderThickness}"
                                CornerRadius="10"
                                SnapsToDevicePixels="True" />
                        </ControlTemplate>
                    </Thumb.Template>
                </Thumb>
            </Canvas>

2)新增 Loaded逻辑 处理代码如下:

            IntPtr backBuffer = Bitmap.BackBuffer;
            int stride = Bitmap.BackBufferStride;
            for (int y = 0; y < height; y++)
            {
                for (int x = 0; x < width; x++)
                {
                    byte r, g, b;
                    double normalizedX = (double)x / (width - 1);
                    double normalizedY = (double)y / (height - 1);
                    HSVToRGB(normalizedX, normalizedY, 1, out r, out g, out b);
                    int pixelOffset = y * stride + x * 4;
                    Marshal.WriteByte(backBuffer, pixelOffset + 0, b);
                    Marshal.WriteByte(backBuffer, pixelOffset + 1, g);
                    Marshal.WriteByte(backBuffer, pixelOffset + 2, r);
                    Marshal.WriteByte(backBuffer, pixelOffset + 3, 0xFF);
                }
            }

3)新增 HSVToRGB 方法代码如下:

private static void HSVToRGB(double h, double s, double v, out byte r, out byte g, out byte b)
        {
            if (s == 0)
            {
                r = g = b = (byte)(v * 255);
            }
            else
            {
                double hue = h * 6.0;
                int i = (int)Math.Floor(hue);
                double f = hue - i;
                double p = v * (1.0 - s);
                double q = v * (1.0 - (s * f));
                double t = v * (1.0 - (s * (1.0 - f)));
                switch (i)
                {
                    case 0:
                        r = (byte)(v * 255);
                        g = (byte)(t * 255);
                        b = (byte)(p * 255);
                        break;
                    case 1:
                        r = (byte)(q * 255);
                        g = (byte)(v * 255);
                        b = (byte)(p * 255);
                        break;
                    case 2:
                        r = (byte)(p * 255);
                        g = (byte)(v * 255);
                        b = (byte)(t * 255);
                        break;
                    case 3:
                        r = (byte)(p * 255);
                        g = (byte)(q * 255);
                        b = (byte)(v * 255);
                        break;
                    case 4:
                        r = (byte)(t * 255);
                        g = (byte)(p * 255);
                        b = (byte)(v * 255);
                        break;
                    default:
                        r = (byte)(v * 255);
                        g = (byte)(p * 255);
                        b = (byte)(q * 255);
                        break;
                }
            }
        }

4)新增 Thumb_DragDelta 代码如下:

 private void Thumb_DragDelta(object sender, DragDeltaEventArgs e)
        {
            var thumb = (Thumb)sender;
            double newLeft = Canvas.GetLeft(thumb) + e.HorizontalChange;
            double newTop = Canvas.GetTop(thumb) + e.VerticalChange;
            double canvasRight = canvas.ActualWidth - thumb.ActualWidth;
            double canvasBottom = canvas.ActualHeight - thumb.ActualHeight;
            if (newLeft < 0)
                newLeft = 0;
            else if (newLeft > canvasRight)
                newLeft = canvasRight;
            if (newTop < 0)
                newTop = 0;
            else if (newTop > canvasBottom)
                newTop = canvasBottom;
            Canvas.SetLeft(thumb, newLeft);
            Canvas.SetTop(thumb, newTop);
            GetAreaColor();
        }

5)新增 canvas_MouseLeftButtonDown 代码如下:

实现鼠标左键按下时,将 Thumb 控件移动到鼠标点击位置,并进行边界限制。同时,还获取了鼠标点击位置的颜色信息

 private void canvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            var canvasPosition = e.GetPosition(canvas);
            double newLeft = canvasPosition.X - thumb.ActualWidth / 2;
            double newTop = canvasPosition.Y - thumb.ActualHeight / 2;
            double canvasRight = canvas.ActualWidth - thumb.ActualWidth;
            double canvasBottom = canvas.ActualHeight - thumb.ActualHeight;
            if (newLeft < 0)
                newLeft = 0;
            else if (newLeft > canvasRight)
                newLeft = canvasRight;
            if (newTop < 0)
                newTop = 0;
            else if (newTop > canvasBottom)
                newTop = canvasBottom;
            Canvas.SetLeft(thumb, newLeft);
            Canvas.SetTop(thumb, newTop);
            var thumbPosition = e.GetPosition(canvas);
            GetAreaColor(thumbPosition);
        }

6)新增 GetAreaColor 代码如下:

Thumb 控件的中心点坐标转换为相对于 Canvas 的坐标。

计算每行像素数据所占的字节数。

创建一个字节数组,用于存储位图的像素数据。

将位图的像素数据复制到字节数组中。

计算要访问的像素在字节数组中的索引位置。

Color.FromArgb取其 Alpha、红色、绿色和蓝色通道的值。在这段代码中,它被用于构造一个 Color 对象,表示位图中特定像素的颜色。

 void GetAreaColor(Point? thumbPosition = null)
        {
            thumbPosition = thumbPosition == null ? thumbPosition = thumb.TranslatePoint(new Point(thumb.ActualWidth / 2, thumb.ActualHeight / 2), canvas) : thumbPosition;
            int xCoordinate = (int)thumbPosition?.X;
            int yCoordinate = (int)thumbPosition?.Y;
            if (xCoordinate >= 0 && xCoordinate < Bitmap.PixelWidth && yCoordinate >= 0 && yCoordinate < Bitmap.PixelHeight)
            {
                int stride = Bitmap.PixelWidth * (Bitmap.Format.BitsPerPixel / 8);
                byte[] pixels = new byte[Bitmap.PixelHeight * stride];
                Bitmap.CopyPixels(new Int32Rect(0, 0, Bitmap.PixelWidth, Bitmap.PixelHeight), pixels, stride, 0);
                int pixelIndex = (yCoordinate * stride) + (xCoordinate * (Bitmap.Format.BitsPerPixel / 8));
                Color color = Color.FromArgb(pixels[pixelIndex + 3], pixels[pixelIndex + 2], pixels[pixelIndex + 1], pixels[pixelIndex]);
                MyBtn.Background = new SolidColorBrush(color);
            }
        }

效果图

到此这篇关于基于WPF开发简单的颜色选择器的文章就介绍到这了,更多相关WPF颜色选择器内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文