首先就是要肯定輸入的文字,還有文字的樣式。ide
文字的樣式用到了FontDialog控件,獲取文字呢,就放個textbox就能夠了。若是在輸入文字的顯示展現文字樣式能夠TextBox.Font = FontDialog.Font;字體
fontDialog1.ShowColor = true; 這樣fontdialog控件就能夠選擇字體顏色了。this
if (this.fontDialog1.ShowDialog() == DialogResult.OK)
{spa
這個 if 判斷的是在用戶選擇字體樣式並點擊了肯定以後。
}3d
這裏實現這個功能的原理,首先固然仍是須要一個image圖片對象,能夠用image或bitmap。而後以這個對象建立一個畫布Graphics.FromImage(image);code
在初始化一個畫筆對象new SolidBrush(this.fontDialog1.Color),這裏將畫筆的顏色設置爲字體樣式的顏色。對象
而後經過畫布的 .DrawString()方法在畫布的制定位置繪製指定的文本字符串。blog
畫完以後要將繪製的文本顯示在圖像上,須要經過圖片容器pictureBox1.Refresh()方法重繪控件。事件
由於這個畫布是根據這個圖片對象建立的,但並非再次建立一個圖片,而是在這個圖片對象上進行繪製。因此在控件刷新以後,就會顯示繪製後的圖片。圖片
再就是須要肯定要將文本繪製到圖片的那個位置
這裏就須要肯定鼠標的座標,鼠標點在那裏就讓文本顯示在哪裏。
這裏使用了picturebox控件的鼠標擡起事件,就是在鼠標在控件上按下擡起以後就會觸發。記錄一個Point點。
private void pictureBox1_MouseUp(object sender, MouseEventArgs e)//這裏這個鼠標擡起事件裏參數,e就是鼠標的對象,能夠經過這個e獲取座標
if (btn == "文字")//這個判斷是由於我還有其餘功能使用這個事件實現,因此經過這個String btn判斷執行的什麼操做 { if (txt_tjwz.Text.Length > 0)//這裏是判斷文本框裏有沒有輸入文本 { Graphics gra = Graphics.FromImage(pic);//要進行處理的圖片對象 //Graphics gra = pictureBox1.CreateGraphics();//這裏這個畫布也能夠以控件做爲對象繪製 SolidBrush brush = new SolidBrush(this.fontDialog1.Color);//初始化畫筆 this.txt_tjwz.ForeColor gra.DrawString(this.txt_tjwz.Text繪製的字符串, this.fontDialog1.Font字體樣式, brush, e.X / Xsfbl按比例縮放後的座標, e.Y / Ysfbl);//處理圖片 this.pictureBox1.Refresh();//對顯示圖片的容器裏面的控件刷新,以便及時顯示添加的文字(控件中的圖像爲對象的時候) bitlist.Add(new Bitmap(this.pictureBox1.Image));//將繪製完成的圖片放入集合,供撤銷用 txt_tjwz.Text = ""; } }
和添加文字差很少,也是首先肯定線段的粗細,顏色,在肯定繪製線段的位置。由於是線段因此須要肯定兩點Point。
線段的粗細使用textbox讓用戶輸入數字來獲取,顏色經過ColorDialog控件,兩點的位置經過兩個事件來獲取,初始點pt0經過鼠標的按下事件,結束點pt1經過擡起事件
可是還有一個問題,就是這樣在肯定兩點而後繪製成功以前,用戶是看不見線段的,因此須要經過鼠標移動事件來實時顯示線段的狀態。
在用戶點下鼠標獲得pt0以後,當鼠標移入picturebox控件後就記錄鼠標在控件中移動的座標並繪製線段,由於是鼠標移動就會觸發因此會持續繪製,此時就不須要用Refreah()刷新控件了。否則會把鼠標移動所產生的每一條線都記錄下來。最後在鼠標中止肯定在一個點繪製後鼠標按鍵擡起,此時記錄最後的座標並繪製線段。而且根據初始與結束兩點計算距離。
if (this.pictureBox1.Image.Width < 1) { return; } if (!string.IsNullOrEmpty(btn)) { pt0 = new Point(e.X, e.Y); } else { MessageBox.Show("請肯定操做"); }
if (btn == "畫線") { if (txt_tjsz.Text.Length > 0 && txt_tjsz.Text != "填入線段粗細數(1~9)") { pt1 = new Point(e.X, e.Y); try { if (banjing(pt0, pt1) == 0) { return; } if (xian) { pictureBox1.Image = DrawLineInPicture1(pic, pt0, pt1, colorDialog1.Color, 2, DashStyle.Solid);//畫線的方法 } else { pictureBox1.Image = DrawLineInPicture1(pic, pt0, pt1, colorDialog1.Color, 2, DashStyle.Dash);//最後一個參數爲線段的樣式 } } catch (Exception ex) { pt0 = new Point(0); MessageBox.Show("操做失敗 " + ex.Message, "提示"); } } }
/// <summary> /// 在圖片上繪製線段 /// </summary> /// <param name="graphics">原始圖片</param> /// <param name="p0">起始點</param> /// <param name="p1">終止點</param> /// <param name="LineColor">線的顏色</param> /// <param name="LineWidth">線的寬度</param> /// <param name="ds">線條樣式</param> /// <returns></returns> public Bitmap DrawLineInPicture(Bitmap bmp, Point p0, Point p1, Color LineColor, int LineWidth, DashStyle ds) {//修改static if (bmp == null) return bmp; if (p0.X == p1.X || p0.Y == p1.Y) return bmp; Graphics g = Graphics.FromImage(bmp); Brush brush = new SolidBrush(LineColor); Pen pen = new Pen(brush, LineWidth); //pen.Alignment = PenAlignment.Inset; pen.DashStyle = ds; if(btn!="畫角") { System.Drawing.Drawing2D.AdjustableArrowCap lineArrow = new System.Drawing.Drawing2D.AdjustableArrowCap(Convert.ToInt32(txt_tjsz.Text)/2, Convert.ToInt32(txt_tjsz.Text)/2, true);//設置箭頭大小 pen.CustomEndCap = lineArrow; } //g.DrawLine(pen,p0,p1); g.DrawLine(pen, p0.X / Xsfbl,p0.Y/Ysfbl,p1.X/Xsfbl,p1.Y/Ysfbl); g.Dispose(); return bmp; }
鼠標MouseUp事件
if (btn == "畫線") { if (txt_tjsz.Text.Length > 0 && txt_tjsz.Text != "填入線段粗細數(1~9)") { if (banjing(pt0, pt1) == 0) { return; } if (xian) { pictureBox1.Image = DrawLineInPicture(pic, pt0, pt1, colorDialog1.Color, Convert.ToInt32(txt_tjsz.Text), DashStyle.Solid); } else { pictureBox1.Image = DrawLineInPicture(pic, pt0, pt1, colorDialog1.Color, Convert.ToInt32(txt_tjsz.Text), DashStyle.Dash); } this.pictureBox1.Refresh(); Point cp = new Point((pt1.X - pt0.X) / 2, (pt1.Y - pt0.Y) / 2); Point np = new Point(cp.X + pt0.X, cp.Y + pt0.Y);//算出線段的中心點 //計算出說話線段的長度 Graphics gra = Graphics.FromImage(this.pictureBox1.Image);//要進行處理的對象 SolidBrush brush = new SolidBrush(colorDialog1.Color);//初始化畫筆 gra.DrawString(banjing(pt0, pt1).ToString(), this.fontDialog2.Font, brush, np.X / Xsfbl, np.Y / Ysfbl);//處理圖片 this.pictureBox1.Refresh();//對顯示圖片的容器裏面的控件刷新,以便及時顯示添加的文字(控件中的圖像爲對象的時候) bitlist.Add(new Bitmap(this.pictureBox1.Image)); pt0 = new Point(0); } }
繪製角度我用的 方法就是繪製兩條線段。
先繪製一條,再根據角度旋轉pt1點,而後鏈接pt0和新獲得的pt2;
嗯,也能夠選擇線段的顏色,粗細默認是2,根據以前計算獲得的圖片縮放比例改變。
也是先肯定pt0,而後鼠標移動事件中不停繪製線段顯示,知道鼠標擡起記錄pt1和pt2,而後刷新控件。
if (btn == "畫角") { if (txt_tjsz.Text.Length > 0&& txt_tjsz.Text != "填入角度度數") { pt1 = new Point(e.X, e.Y); pictureBox1.Image = DrawLineInPicture1(pic, pt0, pt1, colorDialog1.Color, 2, DashStyle.Solid); Point pt2 = GetNewPoint(Convert.ToInt32(txt_tjsz.Text), pt0, pt1); pictureBox1.Image = DrawLineInPicture1(pic, pt0, pt2, colorDialog1.Color, 2, DashStyle.Solid); } else { pt0 = new Point(0); MessageBox.Show("請填寫角度", "提示"); } }
if (btn == "畫角") { if (txt_tjsz.Text.Length > 0 && txt_tjsz.Text != "填入角度度數") { pt1 = new Point(e.X, e.Y); pictureBox1.Image = DrawLineInPicture(pic, pt0, pt1, colorDialog1.Color, Convert.ToInt32(2/Xsfbl), DashStyle.Solid); //pictureBox1.Refresh();//刷新控件繪製角的第一條線 //bitlist.Add(new Bitmap(this.pictureBox1.Image)); Point pt2 = GetNewPoint(Convert.ToInt32(txt_tjsz.Text), pt0, pt1);//順時針 pictureBox1.Image = DrawLineInPicture(pic, pt0, pt2, colorDialog1.Color, Convert.ToInt32(2 / Xsfbl), DashStyle.Solid); pictureBox1.Refresh();//刷新控件繪製角的第二條線 bitlist.Add(new Bitmap(this.pictureBox1.Image)); pt0 = new Point(0); } else { pt0 = new Point(0); MessageBox.Show("請填寫角度", "提示"); }
/// <summary> /// 獲取移動角度的新座標 /// </summary> /// <param name="Rate">旋轉角度</param> /// <param name="CirPoint">圓心座標</param> /// <param name="MovePoint">移動的座標</param> /// <returns></returns> private Point GetNewPoint(double Rate, Point CirPoint, Point MovePoint) { double Rage2 = Rate / 180 * Math.PI; //B點繞A點轉R度獲得C點座標,flag: 順時針1,反時針-1:B是轉的點,A是圓心 //C.X=(B.X-A.X)*COS(R*flag)-(B.Y-A.Y)*Sin(R*flag); //C.Y= (B.Y-A.Y)*COS(R*flag)+(B.X-A.X)*sin(R*flag); //轉的點座標-圓心座標 //圓心座標+計算座標=新位置的座標 int newx = (int)((MovePoint.X - CirPoint.X) * Math.Cos(Rage2) - (MovePoint.Y - CirPoint.Y) * Math.Sin(Rage2)); int newy = (int)((MovePoint.Y - CirPoint.Y) * Math.Cos(Rage2) + (MovePoint.X - CirPoint.X) * Math.Sin(Rage2)); Point newpoint=new Point(CirPoint.X + newx, CirPoint.Y + newy); //計算長度 double lineJ = Math.Sqrt(Math.Pow(Math.Max(newpoint.X, CirPoint.X) - Math.Min(newpoint.X, CirPoint.X), 2) + Math.Pow(Math.Max(newpoint.Y, CirPoint.Y) - Math.Min(newpoint.Y, CirPoint.Y), 2)); return newpoint; }