日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學(xué)無(wú)先后,達(dá)者為師

網(wǎng)站首頁(yè) 編程語(yǔ)言 正文

C#自定義畫(huà)刷原理解析_C#教程

作者:林子xxx ? 更新時(shí)間: 2022-10-16 編程語(yǔ)言

windows系統(tǒng)中的畫(huà)板工具,有好幾種畫(huà)刷,C#中并沒(méi)有直接對(duì)應(yīng)可使用的類(lèi),只能自己研究。

1.畫(huà)刷原理

根據(jù)本人對(duì)PS的相關(guān)功能細(xì)心分析,發(fā)現(xiàn)各種畫(huà)刷其實(shí)就是一幅圖片的移位重疊顯示。通常這幅畫(huà)刷圖是半透明的,只有其中一些區(qū)域有顏色。

上圖中的畫(huà)刷,把間隔設(shè)大之后可以明顯看到原圖的模樣。

這是基于位移的畫(huà)刷,另外有基于時(shí)間的,比如噴槍工具。

2.代碼實(shí)現(xiàn)

1).? 直線算法

為什么要直線算法?因?yàn)槲覀円苿?dòng)鼠標(biāo),觸發(fā)MouseMove事件,記錄鼠標(biāo)前一坐標(biāo)點(diǎn)與當(dāng)前點(diǎn),如果兩點(diǎn)是是相鄰的,當(dāng)然不需要再做多余的算法,當(dāng)如果兩點(diǎn)是不相鄰的,我們就需要計(jì)算兩點(diǎn)之間所有的點(diǎn)。否則無(wú)法有效地進(jìn)行固定間隔繪制畫(huà)刷圖。

/// <summary>
/// 順序獲取兩點(diǎn)間直線上的所有點(diǎn)
/// </summary>
/// <param name="pStart">開(kāi)始點(diǎn)</param>
/// <param name="pEnd">結(jié)束點(diǎn)</param>
/// <returns>兩點(diǎn)間直線上的所有點(diǎn)</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直線畫(huà)法
? ? ? ? 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).鼠標(biāo)事件

分別為鼠標(biāo)按下、移動(dòng)、放開(kāi)事件

bool bIsDraw = false; //主圖畫(huà)線
Point startPoint_Draw = new Point();//劃線點(diǎn)變量
List<Point> pts = new List<Point>();//畫(huà)點(diǎn)保存
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(); ??
? ? ? ? ? ? }
? ? ? ? }

如果根據(jù)位移方向加上圖片的角度旋轉(zhuǎn)效果,應(yīng)該會(huì)更加接近PS的效果。

3.效果

我使用的畫(huà)刷圖就是來(lái)源于本文上圖的PS畫(huà)刷。

圖中5條畫(huà)刷線分別使用間隔1,10,20,40,80。使用不同的原圖,就能得到各種各樣的畫(huà)刷。

原文鏈接:https://blog.csdn.net/wangzibigan/article/details/78993975

欄目分類(lèi)
最近更新