zoukankan      html  css  js  c++  java
  • 【WPF/C#】图层筛选/拾取——Color Picker

    文章标题实在不懂怎么表述才清楚。

    描述问题:多个图片(图层)重叠时,如何通过鼠标点击来拾取到相应的图层。因为图层中会有很多空白的地方(比如图片四周),要求是获取鼠标点击位置的像素颜色值,如果为空白时或透明度小于50%,则穿透到下一层图层再次进行颜色判断,直到找到符合条件的图层。


    根据颜色拾取搜索WPF Color Picker,找到一些相关的资料:

    为了适应当前需求,稍作整理之后,提取为一个工具类,代码有点长这里只放个链接,本文重点是如何使用这个工具类来实现需求:


    阅读Demo可知:

    • 需要把能被拾取到的图片,专门放到一个集合中,如
    ObservableCollection<ImageColorPicker> ImageList
    • 在遍历该集合时,遍历的顺序即是检测点击位置的像素颜色值所属图层的顺序(点击穿透的顺序)。即在将图片加入集合的时候,应该将处于上层的图片先加入集合。
            /// <summary>
            /// 根据鼠标位置,拾取图像
            /// </summary>
            private void PickImageByMousePosition()
            {
                // 获得鼠标相对于当前窗口的位置
                Point mousePoint = Mouse.GetPosition(curWindow);
    
           // 遍历图层列表,找到符合条件的图层
                foreach (ImageColorPicker image in ImageList)
                {
                    // 鼠标相对于当前遍历到的图片的位置(以图片左下角为原点?)
                    Point p = Mouse.GetPosition(image);
    
                    Color color = new Color();
    
                    // 鼠标在图片外面,就遍历下一张图片
                    if (p.X < 0 || p.Y < 0 || p.X > image.ActualWidth || p.Y > image.ActualHeight)
                    {
                        continue;
                    }
    
                    // 获取鼠标位置的颜色值
                    color = image.PickColor(p.X, p.Y);
    
                    // 无色或透明度小于0.5的图层,不是目标图层
                    if (color != null && color.A <= 50)
                    {
                        continue;
                    }
    
              // 能执行到这一步,说明找到了目标图层
             // to what you want
    
                    break;
                }
    
            }

    进阶:给每张图片(每个图层)添加鼠标事件,通过点击事件来执行遍历检查。

    先给图片集合中的每个图片添加一个鼠标左键弹起事件,该事件是激发下一张图片的鼠标左键弹起事件,从而实现事件穿透,直到找到符合要求的图片。

            // 每次添加处理器AddHandler之前先清空Handler,防止重复多次添加
            for (int i = 0; i < ImageList.Count; i++)
            {
                ImageList[i].RemoveHandler(Image.MouseLeftButtonUpEvent, new RoutedEventHandler(DesignImage_PreviewMouseLeftButtonUp));
            }
    
            // 给拾取图片添加鼠标事件
            foreach (ImageColorPicker image in ImageList)
            {
                image.AddHandler(Image.MouseLeftButtonUpEvent, new RoutedEventHandler(DesignImage_PreviewMouseLeftButtonUp));
            }

    然后是激发的事件。

            private void DesignImage_PreviewMouseLeftButtonUp(object sender, RoutedEventArgs e)
            {
                // 当前激发事件的图片
                ImageColorPicker image = (ImageColorPicker)sender;
                
    // 当前图片在集合中的角标
    int currentIndex = GetIndex(image); // 鼠标相对于该图片的位置 Point p = Mouse.GetPosition(image); Color color = new Color(); try { // 位于图像外部,抛异常执行Catch(跳过该层,继续穿透到下一层) if (p.X < 0 || p.Y < 0 || p.X > image.ActualWidth || p.Y > image.ActualHeight) { throw new Exception("p.X或p.Y小于0!"); } color = image.PickColor(p.X, p.Y); // 获取鼠标位置的颜色值 if (color != null && color.A <= 50) // 无色或透明度小于0.5 { ImageColorPicker NextImage = null; if (currentIndex < ImageList.Count - 1) { NextImage = ImageList[currentIndex + 1]; } if (NextImage != null) // 传递到下一图层,下一层激发该事件 { MouseDevice mouseDevice = Mouse.PrimaryDevice; MouseButtonEventArgs mouseButtonEventArgs = new MouseButtonEventArgs(mouseDevice, 0, MouseButton.Left); mouseButtonEventArgs.RoutedEvent = Image.MouseLeftButtonUpEvent; mouseButtonEventArgs.Source = NextImage; NextImage.RaiseEvent(mouseButtonEventArgs); } } else // 找到了有颜色的图层,即是目标图层 { // do what you want } }
    }
    catch (Exception) { System.Console.WriteLine("----- 图层拾取发生异常,则继续穿透到下一层 ------"); // 点击到了图层的外部,则继续穿透到下一层 ImageColorPicker NextImage = null; if (currentIndex < fileDataService.DesignViewModelList[i].ImageList.Count - 1) { NextImage = fileDataService.DesignViewModelList[i].ImageList[currentIndex + 1]; } if (NextImage != null) { string nextType = NextImage.Uid; MouseDevice mouseDevice = Mouse.PrimaryDevice; MouseButtonEventArgs mouseButtonEventArgs = new MouseButtonEventArgs(mouseDevice, 0, MouseButton.Left); mouseButtonEventArgs.RoutedEvent = Image.MouseLeftButtonUpEvent; mouseButtonEventArgs.Source = NextImage; NextImage.RaiseEvent(mouseButtonEventArgs); } } } /// <summary> /// 当前image在ImageList列表中的角标 /// </summary> /// <param name="image">当前ImageColorPicker</param> /// <returns></returns> int GetIndex(ImageColorPicker image) { object targetTag = image.Tag; int index = -1; for (int i = 0; i < ImageList.Count; i++) { ImageColorPicker obj = ImageList[i]; if (obj.Equals(image)) { index = i; break; } } return index; }
  • 相关阅读:
    java keytool证书工具使用小结(转)
    Https socket 代理
    SSL连接出现的问题
    Https 代理 sslsocket
    Https socket 连接
    linux系统一键安装phpstudy的lnmp环境
    Yii2框架实现计数器功能
    yii2框架增删改查案例
    yii2框架原生的结合框架使用的图片上传
    php将抓取的图片链接下载到本地
  • 原文地址:https://www.cnblogs.com/guxin/p/csharp-wpf-layer-image-color-picker.html
Copyright © 2011-2022 走看看