【WPF/C#】图层筛选/拾取——Color Picker
文章标题实在不懂怎么表述才清楚。
描述问题:多个图片(图层)重叠时,如何通过鼠标点击来拾取到相应的图层。因为图层中会有很多空白的地方(比如图片四周),要求是获取鼠标点击位置的像素颜色值,如果为空白时或透明度小于50%,则穿透到下一层图层再次进行颜色判断,直到找到符合条件的图层。
根据颜色拾取搜索WPF Color Picker,找到一些相关的资料:
- https://www.codeproject.com/Articles/36848/WPF-Image-Pixel-Color-Picker-Element
- https://github.com/Alkalinee/ColorPicker/blob/master/ColorPicker/Controls/ImageColorPicker.cs
为了适应当前需求,稍作整理之后,提取为一个工具类,代码有点长这里只放个链接,本文重点是如何使用这个工具类来实现需求:
阅读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 < || p.Y < || p.X > image.ActualWidth || p.Y > image.ActualHeight)
{
continue;
} // 获取鼠标位置的颜色值
color = image.PickColor(p.X, p.Y); // 无色或透明度小于0.5的图层,不是目标图层
if (color != null && color.A <= )
{
continue;
} // 能执行到这一步,说明找到了目标图层
// to what you want break;
} }
进阶:给每张图片(每个图层)添加鼠标事件,通过点击事件来执行遍历检查。
先给图片集合中的每个图片添加一个鼠标左键弹起事件,该事件是激发下一张图片的鼠标左键弹起事件,从而实现事件穿透,直到找到符合要求的图片。
// 每次添加处理器AddHandler之前先清空Handler,防止重复多次添加
for (int i = ; 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 < || p.Y < || 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 <= ) // 无色或透明度小于0.5
{
ImageColorPicker NextImage = null;
if (currentIndex < ImageList.Count - )
{
NextImage = ImageList[currentIndex + ];
}
if (NextImage != null) // 传递到下一图层,下一层激发该事件
{
MouseDevice mouseDevice = Mouse.PrimaryDevice;
MouseButtonEventArgs mouseButtonEventArgs = new MouseButtonEventArgs(mouseDevice, , 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 - )
{
NextImage = fileDataService.DesignViewModelList[i].ImageList[currentIndex + ];
}
if (NextImage != null)
{
string nextType = NextImage.Uid;
MouseDevice mouseDevice = Mouse.PrimaryDevice;
MouseButtonEventArgs mouseButtonEventArgs = new MouseButtonEventArgs(mouseDevice, , 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 = -; for (int i = ; i < ImageList.Count; i++)
{
ImageColorPicker obj = ImageList[i];
if (obj.Equals(image))
{
index = i;
break;
}
} return index;
}
【WPF/C#】图层筛选/拾取——Color Picker的更多相关文章
- NX二次开发-Block UI C++界面Object Color Picker(对象颜色拾取器)控件的获取(持续补充)
Object Color Picker(对象颜色拾取器)控件的获取 NX9+VS2012 #include <uf.h> #include <uf_obj.h> UF_init ...
- [wordpress]后台自定义菜单字段和使用wordpress color picker
Wordpress Version 4.4.2 参考链接 插件使用wordpress color picker:Add A New Color Picker To WordPress 后台菜单自定义字 ...
- 使用canvas制作的移动端color picker
使用canvas制作的移动端color picker 项目演示地址(用手机或者手机模式打开) 我在另一个中demo,需要用到color picker,但是找不到我需要的移动端color picker, ...
- WPF 自定义列表筛选 自定义TreeView模板 自定义ListBox模板
有很多项目,都有数据筛选的操作.下面提供一个案例,给大家做参考. 左侧是数据源,搜索框加TreeView控件,右侧是ListBox控件.在左侧数据列点击添加数据,然后点击确定,得到所筛选的数据. 下面 ...
- 例子:Camera Color Picker Sample (YCbCr->ARGB)
本例演示了如何从相机preview缓冲区获取YCbCr模块,并且转化为ARGB. 1. 什么是YCbCr y:像素的亮度.以范围从 0 到 255 的字节值形式返回(亮度值始终为正值). cr:像素的 ...
- 颜色采集器colpick Color Picker
简单 RGB.HSB.十六进制颜色选取器 jQuery 插件. 非常直观类似 Photoshop 的界面. 光明和黑暗很容易自定义 CSS3 外观. 28 KB 总由浏览器加载看起来不错甚至在 IE7 ...
- C# WPF Datagrid的筛选
public static void SearchResult(DataGrid dg,string condition) { #region string code = string.Empty; ...
- Linux下无法运行Color picker
➜ ~ com.github.ronnydo.colorpicker com.github.ronnydo.colorpicker: error while loading shared librar ...
- An easy to use android color picker library
https://github.com/xdtianyu/ColorPicker
随机推荐
- tomcat启动报错 java.lang.ClassNotFoundException: org.apache.jsp.index_jsp
项目运行一直很平稳,但是换了tomcat之后打开jsp网页时就报错,描述如下: 1. 错误描述 打开jsp网页时报错 java.lang.NullPointerException org.ap ...
- Android基本功:异步任务(AsyncTask)
一.解决新线程无法更新UI组建问题的方案 为了解决新线程不能更新UI组建的问题,Andorid提供了如下几种解决方案: 使用Handler实现线程之间的通信. Activity.runOnUiThre ...
- Nginx(四):压缩功能详解
gzip (GNU-ZIP) 是一种压缩技术.经过 gzip 压缩后页面大小可以变为原来的 30%甚至更小. 这样,用户浏览页面的时候速度会快得多. gzip 的压缩页面需要浏览器和服务器双方都支持 ...
- JS两日期相减
JS两日期相减,主要用到下面两个方法 dateObject.setFullYear(year,month,day) 方法 stringObject.split(separator) 方法 functi ...
- 有关 WCF 的一些错误处理
错误消息: System.ServiceModel.EndpointNotFoundException: 无法调度消息,因为终结点地址"net.tcp://localhost/xxx.svc ...
- Android Studio 1.1.0 切换主题和绑定 代码提示 快捷键
这篇文章用于给刚从eclipse 转用 Android Studio 1.1.0的同学看的. 所以经常会更新的. 至于为什么要转Android Studio 1.1.0呢,就自己想吧.没有人强逼的. ...
- 关于第三方cookie的作用域以及针对用户行为的使用
cookie,很多网站都会用的一个机制,可以保存用户的相关信息,token等等,很多人熟知的应该是第一方cookie,可以针对二级域名进行信息的保存,如果遇到跨域的情况,那么第一方cookie是没有用 ...
- 【Unity】11.8 关节
分类:Unity.C#.VS2015 创建日期:2016-05-02 一.简介 Unity提供了下面的关节组件:铰链关节(Hinge Joint).固定关节(Fixed Joint).弹簧关节(Spr ...
- 行为类模式(十):模板方法(Template Method)
定义 定义一个操作中的算法的骨架,而将步骤延迟到子类中.模板方法使得子类可以不改变一个算法的结构即可重定义算法的某些特定步骤. UML 优点 模板方法模式通过把不变的行为搬移到超类,去除了子类中的重复 ...
- DOUHAO
https://www.java-forums.org/new-java/42610-java-regular-expressions-comma-seperated-list.html https: ...