winfrom在圖片上實現繪制
在控件加載入圖片的基礎上進行繪制內容
添加文字
首先就是要確定輸入的文字,還有文字的樣式。
文字的樣式用到了FontDialog控件,獲取文字呢,就放個textbox就可以了。如果在輸入文字的顯示展示文字樣式可以TextBox.Font = FontDialog.Font;
fontDialog1.ShowColor = true; 這樣fontdialog控件就可以選擇字體顏色了。
if (this.fontDialog1.ShowDialog() == DialogResult.OK)
{
這個 if 判斷的是在用戶選擇字體樣式並點擊了確定之後。
}
這裏實現這個功能的原理,首先當然還是需要一個image圖片對象,可以用image或bitmap。然後以這個對象創建一個畫布Graphics.FromImage(image);
在初始化一個畫筆對象new SolidBrush(this.fontDialog1.Color),這裏將畫筆的顏色設置為字體樣式的顏色。
然後通過畫布的 .DrawString()方法在畫布的制定位置繪制指定的文本字符串。
畫完之後要將繪制的文本顯示在圖像上,需要通過圖片容器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("請確定操作"); }鼠標按下事件記錄pt0
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("請填寫角度", "提示"); } }鼠標MouseMove
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("請填寫角度", "提示"); }MouseUp
winfrom在圖片上實現繪制