網站首頁 編程語言 正文
windows系統中的畫板工具,有好幾種畫刷,C#中并沒有直接對應可使用的類,只能自己研究。
1.畫刷原理
根據本人對PS的相關功能細心分析,發現各種畫刷其實就是一幅圖片的移位重疊顯示。通常這幅畫刷圖是半透明的,只有其中一些區域有顏色。
上圖中的畫刷,把間隔設大之后可以明顯看到原圖的模樣。
這是基于位移的畫刷,另外有基于時間的,比如噴槍工具。
2.代碼實現
1).? 直線算法
為什么要直線算法?因為我們移動鼠標,觸發MouseMove事件,記錄鼠標前一坐標點與當前點,如果兩點是是相鄰的,當然不需要再做多余的算法,當如果兩點是不相鄰的,我們就需要計算兩點之間所有的點。否則無法有效地進行固定間隔繪制畫刷圖。
/// <summary>
/// 順序獲取兩點間直線上的所有點
/// </summary>
/// <param name="pStart">開始點</param>
/// <param name="pEnd">結束點</param>
/// <returns>兩點間直線上的所有點</returns>
private List<Point> getPoint2Point(Point pStart, Point pEnd)
? ? ? ? {
? ? ? ? ? ? List<Point> linePoint = new List<Point>();
? ? ? ? ? ? if (pStart.X == pEnd.X && pStart.Y == pEnd.Y)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? linePoint.Add(pStart);
? ? ? ? ? ? ? ? return linePoint;
? ? ? ? ? ? }
? ? ? ? ? ? DDALine(pStart.X, pStart.Y, pEnd.X, pEnd.Y, ref ?linePoint);
? ? ? ? ? ? return linePoint;
? ? ? ? }
? ? ? ? //DDA直線畫法
? ? ? ? private void DDALine(int x0, int y0, int x1, int y1, ref List<Point> ptl)?
? ? ? ? { ?
? ? ? ? ? ? int dx,dy,eps1,k; ?
? ? ? ? ? ? float x,y,xIncre,yIncre; ?
? ? ? ? ? ? dx=x1-x0; ?
? ? ? ? ? ? dy=y1-y0; ?
? ? ? ? ? ? x=x0; ?
? ? ? ? ? ? y=y0; ?
? ? ? ? ? ? if(Math.Abs(dx)>Math.Abs(dy)) ?
? ? ? ? ? ? eps1=Math.Abs(dx); ?
? ? ? ? ? ? else ?
? ? ? ? ? ? eps1=Math.Abs(dy); ?
? ? ? ? ? ? xIncre=(float)dx/(float)eps1; ?
? ? ? ? ? ? yIncre=(float)dy/(float)eps1; ?
? ? ? ? ? ? for(k=0;k<=eps1;k++) ?
? ? ? ? ? ? {
? ? ? ? ? ? ? ? ptl.Add( new Point((int)(x + 0.5), (int)(y + 0.5)) ); ?
? ? ? ? ? ? ? ? x+=xIncre; ?
? ? ? ? ? ? ? ? y+=yIncre; ?
? ? ? ? ? ? } ?
? ? ? ? }?
2).鼠標事件
分別為鼠標按下、移動、放開事件
bool bIsDraw = false; //主圖畫線
Point startPoint_Draw = new Point();//劃線點變量
List<Point> pts = new List<Point>();//畫點保存
private void pictureBox_main_MouseMove(object sender, MouseEventArgs e)
?{
? ? ? ? ? ? PictureBox pb = sender as PictureBox;
? ? ? ? ? ? ssl_point.Text = e.Location.ToString();
? ? ? ? ? ? pb.Refresh();
? ? ? ? ? ? if (bIsDraw)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? Point p = limitPoint(e.Location, pictureBox_main.ClientSize);
? ? ? ? ? ? ? ? if (p == startPoint_Draw) return;
? ? ? ? ? ? ? ? Graphics gs = Graphics.FromImage(pb.Image);
? ? ? ? ? ? ? ? if (pictureBox_main.Image != null ?)
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ?List<Point> pl = ?getPoint2Point(startPoint_Draw, ?p);
? ? ? ? ? ? ? ? ? ? ?pl.RemoveAt(0);
? ? ? ? ? ? ? ? ? ? ?pts.AddRange(pl);
? ? ? ? ? ? ? ? ? ? ?if (pts.Count >= peninv)
? ? ? ? ? ? ? ? ? ? ?{
? ? ? ? ? ? ? ? ? ? ? ? ?for (int i = penmod; i < pts.Count; i += peninv)
? ? ? ? ? ? ? ? ? ? ? ? ?{
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?gs.DrawImage(blushbmp_curr, pts[i].X - pensize , pts[i].Y - pensize ?, pensize*2, pensize*2);
? ? ? ? ? ? ? ? ? ? ? ? ?}
? ? ? ? ? ? ? ? ? ? ? ? ?penmod = pts.Count % peninv;
? ? ? ? ? ? ? ? ? ? ? ? ?pts.RemoveRange(0, pts.Count - penmod);
? ? ? ? ? ? ? ? ? ? ?}?
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? gs.Dispose();
? ? ? ? ? ? ? ? startPoint_Draw = p;
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? private void pictureBox_main_MouseDown(object sender, MouseEventArgs e)
? ? ? ? {
? ? ? ? ? ? if(e.Button == System.Windows.Forms.MouseButtons.Left)
? ? ? ? ? ? if (bIsDraw == false)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? startPoint_Draw = e.Location;
? ? ? ? ? ? ? ? pts.Clear();
? ? ? ? ? ? ? ? pts.Add(startPoint_Draw);
? ? ? ? ? ? ? ? bIsDraw = true;
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? private void pictureBox_main_MouseUp(object sender, MouseEventArgs e)
? ? ? ? {
? ? ? ? ? ? if (bIsDraw == true)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? bIsDraw = false;
? ? ? ? ? ? ? ? if (pictureBox_main.Image != null ? )
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ?pts.Clear();
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? pictureBox_main.Refresh(); ??
? ? ? ? ? ? }
? ? ? ? }
如果根據位移方向加上圖片的角度旋轉效果,應該會更加接近PS的效果。
3.效果
我使用的畫刷圖就是來源于本文上圖的PS畫刷。
圖中5條畫刷線分別使用間隔1,10,20,40,80。使用不同的原圖,就能得到各種各樣的畫刷。
原文鏈接:https://blog.csdn.net/wangzibigan/article/details/78993975
相關推薦
- 2023-06-03 Numpy數值積分的實現_python
- 2022-07-23 C語言詳解用char實現大小寫字母的轉換_C 語言
- 2022-04-20 C#實現變量交換、斐波那契數列、質數、回文方法合集_C#教程
- 2022-08-05 C#實現動態數字時鐘和日歷_C#教程
- 2022-12-14 C++利用類實現矩陣的數乘,乘法以及點乘_C 語言
- 2022-04-28 .net項目使用日志框架log4net_實用技巧
- 2022-07-27 python如何為list實現find方法_python
- 2022-06-08 Tomcat部署iframe出現Refused to display ‘url‘ in a fram
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支