Sử Dụng Lớp Graphics - Vẽ Những Nét Cơ Bản

Các bài viết hướng dẫn về Visual Basic .NET và C#

Các điều hành viên: tungcan5diop, QUANITGROBEST

Hình đại diện của thành viên
1045007
Thành viên danh dự
Thành viên danh dự
Bài viết: 551
Ngày tham gia: Thứ 2 09/06/2008 3:35 pm
Đến từ: TP Cần Thơ
Has thanked: 2 times
Been thanked: 61 times
Tiếp xúc:

Sử Dụng Lớp Graphics - Vẽ Những Nét Cơ Bản

Gửi bài by 1045007 »

Tên bài viết: Tập tành vẽ những nét cơ bản
Tác giả: 1045007
Cấp độ bài viết: nâng cao đối với những ai đang cơ bản.
Tóm tắt: các bạn thấy rằng ngày càng có nhiều các phần mềm về đồ họa, chỉnh sửa ảnh cho ra đời, chúng ta dễ dàng nhận ra các điểm chung giữa các sản phẩm đó là đầu vào là một tấm ảnh (hoặc không), đầu ra là một tấm ảnh đã được xử lý. Ở đây tôi không nói về vấn đề xử lý như thế hay các cấu trúc file ảnh ra sao vì khả năng tôi có giới hạn… Nhưng tôi sẽ hướng dẫn các bạn cách kết xuất ra một file ảnh do chính ta vẽ ra và hiểu được cách làm việc của các nét vẽ cơ bản (pixel, hình tròn, hình chữ nhật…).
Project:
UseGraphic.rar
(111.1 KiB) Đã tải về 2614 lần

Phần I: Vẽ Ảnh



I. CÁC NÉT VẼ CƠ BẢN

Các khai báo cần thiết:

Mã: Chọn tất cả

Dim bm As Bitmap 'biến bitmap lưu những gì ta đã vẽ    Dim gp As Graphics 'biến chính để vẽ ảnh    Dim draw As Boolean    Dim line As String = "pixel" 'kiểu vẽ    Dim c As Color = Color.Black 'Màu vẽ
Trong Form cho đối tượng PictureBox có Name là pic.
Nếu chỉ để vẽ lên đối tượng ta chỉ cần viết code:

Mã: Chọn tất cả

'gan giá trị Graphics của đối tượng cho gpgp = Me.pic.CreateGraphics()
Vấn đề là khi runtime form luôn được vẽ lại khi có sự tác động, hậu quả là nó xóa luôn những gì ta đã vẽ lên.

Để khắc phục hiện tượng trên ta cần lưu những gì đã vẽ được vào một BitMap.

Mã: Chọn tất cả

'Thủ tục Chính để khởi tạo và thể hiện bm lên pictureBox    Private Sub NewBitmap(ByVal w As Integer, ByVal h As Integer)        bm = New Bitmap(w, h)        Me.pic.Image = bm        gp = Graphics.FromImage(bm)    End Sub
1. Nét vẽ điểm (pixel)
Trong lớp Drawing2D không có sẵn hàm vẽ một điểm như là putpixel(x,y) trong ngôn ngữ C,C++…

Để vẽ một điểm ta có thể dùng:

Mã: Chọn tất cả

bm.SetPixel(100, 100, Color.Black)
Mặc khắc có thể dùng hàm FillRectangle tô một hình chữ nhật có chiều dài và rộng = 1.

Mã: Chọn tất cả

Private Sub pixel(ByVal e As System.Windows.Forms.MouseEventArgs)        point = New Point(e.X, e.Y)        gp.FillRectangle(New Pen(c).Brush, point.X, point.Y, 1, 1)    End Sub
Bây giờ ta muốn khi rê chuột đến đâu, click chổ nào thì vẽ tại chổ đó, hoặc vừa kéo chuột vừa vẽ.
Vậy ta sẽ bắt 3 sự kiện chính: MouseDown, MouseUp, MouseMove của PictureBox cần vẽ lên.

Mã: Chọn tất cả

Private Sub pic_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles pic.MouseDown        If e.Button = Windows.Forms.MouseButtons.Left Then                draw = True                MyDraw(e)        End If    End Sub     Private Sub pic_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles pic.MouseMove        If draw = True Then            MyDraw(e)        End If    End Sub     Private Sub pic_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles pic.MouseUp        If draw = True Then            draw = False        End If    End Sub
Còn đây là thủ tục MyDraw(e) chính gọi lại thủ tục pixel(e):

Mã: Chọn tất cả

Private Sub MyDraw(ByVal e As System.Windows.Forms.MouseEventArgs)        If line = "pixel" Then            pixel(e)        End If    End Sub
Bây giờ thử được rồi đấy! kết quả mà ta mong đợi chắc là vầy:
1.PNG
1.PNG (12.96 KiB) Đã xem 22674 lần
Nhưng kết quả thực thì là vầy:
2.PNG
2.PNG (12.39 KiB) Đã xem 22678 lần
Lý do: tốc độ của vết chuột đi qua là rất cao mà sự kiện MouseMove không thể bắt kịp được tất cả các điểm đó nên kết quả cho ta thấy như hình trên.
Để khắc phục được nhược điểm, ta để ý rằng mỗi lần vết chuột đi qua nó cho ta một điểm, khoảng cách giữa 2 điểm liên tiếp vết chuột đi qua là tương đối gần do sự kiện MouseMove bắt được. Nên việc nối 2 điểm gần này lại với nhau là có thể tạm chấp nhận được.
Vậy việc cần làm là lưu các điểm vết chuột đi qua rồi nối chúng lại với nhau. Rất may lớp Drawing2D cho ta sẵn một kiểu GraphicsPath để lưu lại những gì ta vẽ lên:

Mã: Chọn tất cả

'Lưu lại đường thẳng được nối từ các điểmDim mousepath As New GraphicsPathDim point As Point 'Lưu các điểm đi qua
Thủ tục pixel và MyDraw được viết lại như sau:

Mã: Chọn tất cả

 Private Sub pixelDrag(ByVal e As System.Windows.Forms.MouseEventArgs)        point = New Point(e.X, e.Y)        mousepath.AddLine(point, point)        gp.DrawPath(New Pen(c), mousepath)    End Sub    Private Sub MyDraw(ByVal e As System.Windows.Forms.MouseEventArgs)        If line = "pixel" Then            pixel(e)            pixelDrag(e)        Me.pic.Invalidate()        End If    End Sub
Nhớ lưu rồi thì phải xóa để còn sử dụng lại:

Mã: Chọn tất cả

Private Sub pic_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles pic.MouseUp        If draw = True Then            draw = False            mousepath.Reset()        End If    End Sub
Và đây khuyến mãi thêm con chuột nhìn trông có vẽ pro hơn:

Mã: Chọn tất cả

Public Function CreateCursor(ByVal bm As Bitmap, ByVal size As Size) As Cursor        Try            bm = New Bitmap(bm, size)            bm.MakeTransparent()            Return New Cursor(bm.GetHicon)        Catch ex As Exception        End Try        Return Cursors.Default    End Function
Xong! bây giờ thử nhé:

Mã: Chọn tất cả

Private Sub f_paint_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load        NewBitmap(Me.pic.Width, Me.pic.Height)    End Sub
Sửa lần cuối bởi 11 vào ngày 1045007 với 0 lần sửa trong tổng số.
Xếp hình cổ điển for Android-https://play.google.com
♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀
Hình đại diện của thành viên
Dang Minh Du
Thành viên ưu tú
Thành viên ưu tú
Bài viết: 531
Ngày tham gia: Thứ 4 02/04/2008 2:08 pm
Đến từ: RGames Team
Has thanked: 3 times
Been thanked: 17 times
Tiếp xúc:

Re: Sử Dụng Lớp Drawing2D - Vẽ Những Nét Cơ Bản

Gửi bài by Dang Minh Du »

Đâu rồi, post nhanh đi anh, em muốn tập tành một chút về Graphic đây :)
~°Dòng Sông Mùa Thu°~
Studying...!
Hình đại diện của thành viên
VBNewbie
Thành viên tích cực
Thành viên tích cực
Bài viết: 113
Ngày tham gia: Thứ 7 29/03/2008 7:13 pm
Đến từ: Computer
Been thanked: 3 times
Tiếp xúc:

Re: Sử Dụng Lớp Drawing2D - Vẽ Những Nét Cơ Bản

Gửi bài by VBNewbie »

Hay quá ! Very cool ! Đang cần !
Post thêm đi anh !
Còn vẽ trong 3D thì sao !
-------[[[[[[[ VMind - PM trắc nghiệm đa năng ]]]]]]]]------
http://vmind.co.cc/vmind
-------[[[[ Diễn đàn trí tuệ Việt Nam ! ]]]]]]]]-----
http://vmind.co.cc
Hình đại diện của thành viên
anhtuyenbk
Guru
Guru
Bài viết: 1311
Ngày tham gia: Thứ 5 22/09/2005 4:12 pm
Đến từ: Một nơi chừa từng biết, chưa từng nghe, chưa từng thấy
Been thanked: 38 times

Re: Sử Dụng Lớp Drawing2D - Vẽ Những Nét Cơ Bản

Gửi bài by anhtuyenbk »

Hay lắm, cố lên post tiếp nữa đi.
Dang Minh Du đã viết:Đâu rồi, post nhanh đi anh, em muốn tập tành một chút về Graphic đây :)
Muốn nghiên cứu nhanh thì tải cuốn Pro Control Net của Hai PT hay mấy cuốn VB Pro kìa, có nhiều đọc lắm --> chỉ có điều phải chịu khó đọc English >:) >:)
Kiếm cơm cho qua ngày tháng
https://www.facebook.com/pinduphongpisenchinhhang
Hình đại diện của thành viên
1045007
Thành viên danh dự
Thành viên danh dự
Bài viết: 551
Ngày tham gia: Thứ 2 09/06/2008 3:35 pm
Đến từ: TP Cần Thơ
Has thanked: 2 times
Been thanked: 61 times
Tiếp xúc:

Re: Sử Dụng Lớp Graphics - Vẽ Những Nét Cơ Bản

Gửi bài by 1045007 »

VBNewbie đã viết:Hay quá ! Very cool ! Đang cần !
Post thêm đi anh !
Còn vẽ trong 3D thì sao !
Hiện tại thấy trong đây chưa có cái nào nên post lên cho anh em xem. Rất tiếc 3D thì .Net không có sẵn, sử dụng DirectX thì đã có hdn rồi:
Xem link: http://www.caulacbovb.com/forum/viewtopic.php?f=23&t=26
Sửa lần cuối bởi 1 vào ngày 1045007 với 0 lần sửa trong tổng số.
Xếp hình cổ điển for Android-https://play.google.com
♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀
Hình đại diện của thành viên
1045007
Thành viên danh dự
Thành viên danh dự
Bài viết: 551
Ngày tham gia: Thứ 2 09/06/2008 3:35 pm
Đến từ: TP Cần Thơ
Has thanked: 2 times
Been thanked: 61 times
Tiếp xúc:

Re: Sử Dụng Lớp Graphics - Vẽ Những Nét Cơ Bản

Gửi bài by 1045007 »

2. Nét lớn có thể thay đổi kích thước

Khai báo thêm biến pensize kích thước của nét cần vẽ:

Mã: Chọn tất cả

Dim pensize As Single = 2
Lưu ý: có 2 trạng thái vẽ là click là vẽ và vừa kéo chuột vừa vẽ. Nên ta phải bắt 2 trường hợp này một cách riêng biệt để nét vẽ không đè lên nhau.
Nét chấm:

Mã: Chọn tất cả

    Private Sub pixelchangesize(ByVal e As System.Windows.Forms.MouseEventArgs)        point = New Point(e.X, e.Y)        gp.FillRectangle(New Pen(c).Brush, (point.X - pensize / 2), (point.Y - pensize / 2), pensize, pensize)    End Sub
Nét vừa kéo vừa vẽ:

Mã: Chọn tất cả

    Private Sub PixelChangeSizeDrag(ByVal e As System.Windows.Forms.MouseEventArgs)        point = New Point(e.X, e.Y)        mousepath.AddLine(point, point)        gp.DrawPath(New Pen(c, pensize), mousepath)    End Sub
Giải thích về 2 thủ tục trên (Xem hình)
3.PNG
3.PNG (4.24 KiB) Đã xem 22572 lần
Với 1: điểm nhấn vẽ là chấm đỏ trên hình 1, trông có vẽ bất tiện vì điểm nhấn vẽ và nét vẽ hiển thị không cân đối.
Với 2: dời nét vẽ hiển thị sao cho điểm nhấn vẽ nằm tại giao điểm của như hình 2.
Thủ tục MyDraw(e) được viết lại như sau:

Mã: Chọn tất cả

    Private Sub MyDraw(ByVal e As System.Windows.Forms.MouseEventArgs)        If line = "pixel" Then            pixelDrag(e)        ElseIf line = "pixelchangesize" Then            PixelChangeSizeDrag(e)        End If        Me.pic.Invalidate()    End Sub
Sự kiện MouseDown được viết lại như sau:

Mã: Chọn tất cả

    Private Sub pic_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles pic.MouseDown        If e.Button = Windows.Forms.MouseButtons.Left Then            draw = True            If line = "pixel" Then                pixel(e)                pixelDrag(e)            ElseIf line = "pixelchangesize" Then                pixelchangesize(e)                PixelChangeSizeDrag(e)            End If            Me.pic.Invalidate()        End If    End Sub
Để kiểm tra những gì ta đã làm, cho thêm vào Form một ComboBox có Name là cb_size, Viết code:

Mã: Chọn tất cả

    Private Sub cb_size_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cb_size.SelectedIndexChanged        pensize = Me.cb_size.SelectedItem    End Sub
Kết Quả:
4.PNG
4.PNG (21.49 KiB) Đã xem 22573 lần
Sửa lần cuối bởi 1 vào ngày 1045007 với 0 lần sửa trong tổng số.
Xếp hình cổ điển for Android-https://play.google.com
♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀
Hình đại diện của thành viên
Kasper
Guru
Guru
Bài viết: 1063
Ngày tham gia: Thứ 6 16/05/2008 10:54 am
Has thanked: 2 times
Been thanked: 76 times
Tiếp xúc:

Re: Sử Dụng Lớp Drawing2D - Vẽ Những Nét Cơ Bản

Gửi bài by Kasper »

Tiếp đi bạn, làm thành một cái Paint = .net luôn đi :D :D
Lành tợ tòng, ác tợ hoa,
Nhà hòa muôn việc đều nên.
Hình đại diện của thành viên
1045007
Thành viên danh dự
Thành viên danh dự
Bài viết: 551
Ngày tham gia: Thứ 2 09/06/2008 3:35 pm
Đến từ: TP Cần Thơ
Has thanked: 2 times
Been thanked: 61 times
Tiếp xúc:

Re: Sử Dụng Lớp Graphics - Vẽ Những Nét Cơ Bản

Gửi bài by 1045007 »

3. Nét tròn


Cũng với ý tưởng mousepath, mà làm sao mà pixel lại tròn ? Ta chỉ tưởng tượng ra thôi. Là vầy, chấm đại 1 điểm sau đó lấy tiếp 4 điểm xung quanh, nhìn giống dấu + hơn!
5.PNG
5.PNG (2.37 KiB) Đã xem 22516 lần
Nhìn kỹ hình trên nhé! Chính xác là có 5 pixel: vàng, đỏ, xanh, xanh lá và 1 cái pixel lộn xộn. Do tôi tăng kích thước của mỗi ô lên 1 đơn vị nên nhìn thấy cái pixel lộn xộn hầu như bị đè lên bởi 4 pixel lân cận.
Việc tăng khích lên là có cơ sở nó làm giảm lượng pixel ta cần vẽ nhưng mật độ thì không thay đổi. Như hình trên cái pixel lộn xộn là không cần thiết nửa vậy ta xóa nó đi và nó cũng chính là điểm nhấn của chuột.

Vậy cần khai thêm 4 đối tượng sau:

Mã: Chọn tất cả

Dim path1 As New GraphicsPathDim path2 As New GraphicsPathDim path3 As New GraphicsPathDim path4 As New GraphicsPath
Thủ tục PixelFullDrag(e) được viết như sau:

Mã: Chọn tất cả

Private Sub PixelFullDrag(ByVal e As System.Windows.Forms.MouseEventArgs)        point = New Point(e.X, e.Y)        path1.AddLine(New Point(point.X, point.Y - 1), New Point(point.X, point.Y - 1))        path2.AddLine(New Point(point.X + 1, point.Y), New Point(point.X + 1, point.Y))        path3.AddLine(New Point(point.X, point.Y + 1), New Point(point.X, point.Y + 1))        path4.AddLine(New Point(point.X - 1, point.Y), New Point(point.X - 1, point.Y))         gp.DrawPath(New Pen(c, 2), path1)        gp.DrawPath(New Pen(c, 2), path2)        gp.DrawPath(New Pen(c, 2), path3)        gp.DrawPath(New Pen(c, 2), path4)    End Sub
Và PixelFull(e):

Mã: Chọn tất cả

    Private Sub PixelFull(ByVal e As System.Windows.Forms.MouseEventArgs)        point = New Point(e.X, e.Y)        gp.FillRectangle(New Pen(c).Brush, point.X - 1, point.Y - 1 - 1, 2, 2)        gp.FillRectangle(New Pen(c).Brush, point.X + 1 - 1, point.Y - 1, 2, 2)        gp.FillRectangle(New Pen(c).Brush, point.X - 1, point.Y + 1 - 1, 2, 2)        gp.FillRectangle(New Pen(c).Brush, point.X - 1 - 1, point.Y - 1, 2, 2)    End Sub
Thủ tục MyDraw(e) được viết lại như sau:

Mã: Chọn tất cả

    Private Sub MyDraw(ByVal e As System.Windows.Forms.MouseEventArgs)        If line = "pixel" Then            pixelDrag(e)        ElseIf line = "pixelchangesize" Then            PixelChangeSizeDrag(e)        ElseIf line = "pixelfull" Then            PixelFullDrag(e)        End If        Me.pic.Invalidate()    End Sub
Trong sự kiện MouseDown viết tiếp dòng này:

Mã: Chọn tất cả

...............ElseIf line = "pixelfull" Then                PixelFull(e)                PixelFullDrag(e)            End If
Sau khi vẽ xong 1 nét ta Reset path lại:

Mã: Chọn tất cả

    Sub ResetPath()        mousepath.Reset()        path1.Reset()        path2.Reset()        path3.Reset()        path4.Reset()    End Sub Private Sub pic_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles pic.MouseUp        If draw = True Then            draw = False            ResetPath()        End If        End Sub
TẠM DỪNG Ở ĐÂY! BÀI SAU NÓI VỀ CÁC NÉT....?
Sửa lần cuối bởi 1 vào ngày 1045007 với 0 lần sửa trong tổng số.
Xếp hình cổ điển for Android-https://play.google.com
♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀
Hình đại diện của thành viên
1045007
Thành viên danh dự
Thành viên danh dự
Bài viết: 551
Ngày tham gia: Thứ 2 09/06/2008 3:35 pm
Đến từ: TP Cần Thơ
Has thanked: 2 times
Been thanked: 61 times
Tiếp xúc:

Re: Sử Dụng Lớp Graphics - Vẽ Những Nét Cơ Bản

Gửi bài by 1045007 »

HỆ SỐ ZOOM


Độ phóng đại là tỷ lệ kích thước của ảnh phóng đại so với ảnh gốc (ảnh ban đầu), được tính bằng kích thước của ảnh gốc (rộng, cao) nhân cho hệ số zoom n.
Từ bài này trở về sau mặc định trong các hàm tôi luôn tính sẵn hệ số zoom trong đó và chỉ nêu các hàm chính còn thao tác để vẽ thì các bạn đã hiểu, các bài viết trước các bạn sửa lại cho phù hợp.

Để khảo sát, ta thêm vào 2 biến:

Mã: Chọn tất cả

Public zoom As Single = 1 ‘hệ số ban đầu bằng 1Dim bmsize As Size ‘lưu kích thước ảnh thật
Ta thêm vào Form đối tượng ComboBox có Name là cb_zoom gồm các giá trị (1,2,4,8)

Mã: Chọn tất cả

    Private Sub cb_zoom_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cb_zoom.SelectedIndexChanged        If Me.cb_zoom.SelectedIndex = 0 Then            zoom = 1        ElseIf Me.cb_zoom.SelectedIndex = 1 Then            zoom = 2        ElseIf Me.cb_zoom.SelectedIndex = 2 Then            zoom = 4        Else            zoom = 8        End If        Me.pic.Size = New Size(bmsize.Width * zoom, bmsize.Height * zoom)    End Sub
Để dịch ngược lại giá trị thật:

Mã: Chọn tất cả

           Private Sub pic_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles pic_center.MouseMove            Me.lb_pixel.Text = "Điểm ảnh: ( " & (e.X \ zoom).ToString & " , " & (e.Y \ zoom).ToString & " )"           End Sub
Sửa lần cuối bởi 1 vào ngày 1045007 với 0 lần sửa trong tổng số.
Xếp hình cổ điển for Android-https://play.google.com
♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀
Hình đại diện của thành viên
1045007
Thành viên danh dự
Thành viên danh dự
Bài viết: 551
Ngày tham gia: Thứ 2 09/06/2008 3:35 pm
Đến từ: TP Cần Thơ
Has thanked: 2 times
Been thanked: 61 times
Tiếp xúc:

Re: Sử Dụng Lớp Graphics - Vẽ Những Nét Cơ Bản

Gửi bài by 1045007 »

II. Các Nét: Đường Thẳng, Hình Tròn, Hình Chữ Nhật…


1. Vẽ Đường Thẳng
Khái quát: đường thẳng, hình tròn, hình chữ nhật,… là những hình tương đối đặc biệt, đặc biệt ở đây không phải là ghê gốm gì mà ở chổ các nét này từ lúc đặt điểm chuột rồi kéo, đến lúc thôi nhấn chuột mới tạo nên một hình (cần vẽ) thật sự, và trong giữa 2 thời điểm đó có vô số các hình (không cần thiết) tạo ra. Vấn đề là chổ này, làm sao để chỉ lấy được những nét cần vẽ là thực sự cần thết.
- Có nhiều cánh khắc phục, mà cách này là một trong những cánh tôi thích nhất khi trình bày vì (ngoài cách này ra tôi chưa biết cách nào khác…ac ac).
Thế này: tạo 1 Picture khác tạm gọi là picture mặt nạ (pic_Mask), khi ấy ta vẽ vô tư lên pic_Mask này đến lúc xong rồi vẽ lại hình này vào pic thật của ta.
- Đại khái là vậy, để đơn giản tôi sử dụng nốt thuộc tính BackGoundImage của pic để làm điều này.
Cần khai báo:

Mã: Chọn tất cả

Dim bmdown As Bitmap 'lưu ảnh khi chuột vừa nhấn xuống
Thủ tục MouseDown viết lại tiếp…

Mã: Chọn tất cả

             .....             ElseIf line = "line" Then                point = New Point(e.X / zoom, e.Y / zoom)                bmdown = New Bitmap(bm)                Me.pic.BackgroundImage = bmdown            End If
Và Mouseup…

Mã: Chọn tất cả

            If line = "line" Then                Me.pic.BackgroundImage = Nothing                gp.DrawImage(bmdown, 0, 0)                gp.DrawLine(New Pen(c), New Point(point.X / zoom, point.Y / zoom),  New Point(e.X / zoom, e.Y / zoom))            End If
Thủ tục chính MyLine(e)

Mã: Chọn tất cả

    Private Sub MyLine(ByVal e As System.Windows.Forms.MouseEventArgs)        gp.Clear(Color.Empty)  gp.DrawLine(New Pen(c), New Point(point.X / zoom, point.Y / zoom),  New Point(e.X / zoom, e.Y / zoom))        End Sub
Sửa lần cuối bởi 1 vào ngày 1045007 với 0 lần sửa trong tổng số.
Xếp hình cổ điển for Android-https://play.google.com
♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀
Hình đại diện của thành viên
1045007
Thành viên danh dự
Thành viên danh dự
Bài viết: 551
Ngày tham gia: Thứ 2 09/06/2008 3:35 pm
Đến từ: TP Cần Thơ
Has thanked: 2 times
Been thanked: 61 times
Tiếp xúc:

Re: Sử Dụng Lớp Graphics - Vẽ Những Nét Cơ Bản

Gửi bài by 1045007 »

2. Hình Chữ Nhật


- Cũng giống với cách vẽ đường thẳng, xuất phát từ điểm bắt đầu và điểm kết thúc, nhưng lúc này không phải nối 2 điểm lại mà ta đi xác định điểm kết thúc nằm ở vị trí nào so với điểm bắt đầu: bên trái, bên phải, phía trên, phía dưới, bên phải phía dưới, bên phải phía trên…
- Mục đích của việc xác định vị trí đó nhằm tính khoảng cách giữa 2 điểm và thể hiện hình chữ nhật một cách phù hợp
- Tiến hành khai báo:

Mã: Chọn tất cả

    'Lấy hình chữ nhật hiện tại    Dim rec As Rectangle
Khoản cách 2 điểm A & B

Mã: Chọn tất cả

    Private Function Distance(ByVal A As Point, ByVal B As Point) As Integer        Return CType(Math.Sqrt((B.X - A.X) ^ 2 + (B.Y - A.Y) ^ 2), Integer)    End Function
Thủ tục vẽ hình chữ nhật

Mã: Chọn tất cả

    Private Sub Rectangle(ByVal e As System.Windows.Forms.MouseEventArgs)        Dim npoint As New Point(e.X / zoom, e.Y / zoom)        gp.Clear(Color.Empty)        Dim teampoint As Point        If npoint.X > point.X And npoint.Y > point.Y Then            teampoint = New Point(point.X, point.Y)        ElseIf npoint.X < point.X And npoint.Y < point.Y Then            teampoint = New Point(npoint.X, npoint.Y)        ElseIf npoint.X > point.X And npoint.Y < point.Y Then            teampoint = New Point(point.X, npoint.Y)        ElseIf npoint.X < point.X And npoint.Y > point.Y Then            teampoint = New Point(npoint.X, point.Y)        End If        rec = New Rectangle(teampoint, New Size(Distance(point, New Point(npoint.X, point.Y)), Distance(point, New Point(point.X, npoint.Y))))        gp.DrawRectangle(New Pen(c, pensize), rec)     End Sub
Sự kiện MouseUp sửa:

Mã: Chọn tất cả

            .............            If line = "rectangle" Then                Me.pic.BackgroundImage = Nothing                gp.DrawImage(bmdown, 0, 0)                gp.DrawRectangle(New Pen(c, pensize), rec) ' rec: HCN được lấy trong lúc vẽ            End If

3. Hình tròn
- Tương tự hình chữ nhật, sửa lại là DrawElip
Sửa lần cuối bởi 1 vào ngày 1045007 với 0 lần sửa trong tổng số.
Xếp hình cổ điển for Android-https://play.google.com
♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀
Hình đại diện của thành viên
1045007
Thành viên danh dự
Thành viên danh dự
Bài viết: 551
Ngày tham gia: Thứ 2 09/06/2008 3:35 pm
Đến từ: TP Cần Thơ
Has thanked: 2 times
Been thanked: 61 times
Tiếp xúc:

Re: Sử Dụng Lớp Graphics - Vẽ Những Nét Cơ Bản

Gửi bài by 1045007 »

III. Lấy Màu và Tô Màu


1. Lấy Màu

- Đối tượng bm cho ta phương thức GetPixel(x,y) kiểu trả về là một màu tại điểm được chỉ định
- Lấy màu không giống với các nét vẽ mà ta đã trình bày ở trên, chỉ cần click chuột là lấy không cần phải Drag chuột, đồng thời kiểm tra xem màu vừa lấy có trùng với màu trong suốt hay không nếu có thì bỏ qua.
Thủ Tục GetColor(e) được viết như sau:

Mã: Chọn tất cả

'Lay mau____________    Private Sub GetColor(ByVal e As System.Windows.Forms.MouseEventArgs)        Try            point = New Point(e.X / zoom, e.Y / zoom)            If bm.GetPixel(point.X, point.Y) <> Color.FromArgb(0, 0, 0, 0) Then                c = bm.GetPixel(point.X, point.Y)                Me.lb_color.BackColor = c                Me.bt_Color.ForeColor = c            End If        Catch ex As Exception        End Try    End Sub
Bạn đưa thủ tục này vào sự kiện Pic_MouseDown(..) của Picturebox không cần phải đưa vào thủ tục MyDraw(e)
Sửa lần cuối bởi 1 vào ngày 1045007 với 0 lần sửa trong tổng số.
Xếp hình cổ điển for Android-https://play.google.com
♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀
Hình đại diện của thành viên
1045007
Thành viên danh dự
Thành viên danh dự
Bài viết: 551
Ngày tham gia: Thứ 2 09/06/2008 3:35 pm
Đến từ: TP Cần Thơ
Has thanked: 2 times
Been thanked: 61 times
Tiếp xúc:

Re: Sử Dụng Lớp Graphics - Vẽ Những Nét Cơ Bản

Gửi bài by 1045007 »

2. Tô màu vùng khép kín

- Lớp Graphics cung cấp cho ta khá đầy đủ các phương thức tô màu, cũng như các phương thức vẽ, các phương thức này luôn đứng đầu bởi tiếp đầu ngữ Fill…
- Để tô màu 1 hình chữ nhật ta dùng: FillRectangle(…), hình tròn FillElip(…) ...
- Nhìn chung, các phương thức tô màu trên chỉ tô những vùng chưa xác định hoặc các vùng ta đã biết trước Region của nó. Vậy để tô một vùng khép kín ngẫu nhiên hay chưa xác định được Region các bạn tham khảo 1 Class trích xuất từ thư viện gdi32.

Mã: Chọn tất cả

' Tham khao ham API cua thu vien gdi32Public Class FillColor #Region " FloodFill"     Private Structure BITMAPINFOHEADER        Dim biSize As Integer        Dim biWidth As Integer        Dim biHeight As Integer        Dim biPlanes As Short        Dim biBitCount As Short        Dim biCompression As Integer        Dim biSizeImage As Integer        Dim biXPelsPerMeter As Integer        Dim biYPelsPerMeter As Integer        Dim biClrUsed As Integer        Dim biClrImportant As Integer    End Structure     ' Truy cap thu vien    Private Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hdc As IntPtr) As IntPtr    Private Declare Function CreateDIBSection Lib "gdi32" (ByVal hdc As IntPtr, ByRef pBitmapInfo As BITMAPINFOHEADER, ByVal un As Integer, ByRef lplpVoid As IntPtr, ByVal handle As Integer, ByVal dw As Integer) As IntPtr    Private Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As IntPtr, ByVal x As Integer, ByVal y As Integer, ByVal nWidth As Integer, ByVal nHeight As Integer, ByVal hSrcDC As IntPtr, ByVal xSrc As Integer, ByVal ySrc As Integer, ByVal dwRop As Integer) As Integer    Private Declare Function ExtFloodFill Lib "gdi32" (ByVal hdc As IntPtr, ByVal X As Integer, ByVal Y As Integer, ByVal crColor As Integer, ByVal wFillType As Integer) As Integer    Private Declare Function CreateSolidBrush Lib "gdi32" (ByVal crColor As Integer) As IntPtr    Private Declare Function GetPixel Lib "gdi32" (ByVal hdc As IntPtr, ByVal X As Integer, ByVal Y As Integer) As Integer    Private Declare Function SelectObject Lib "gdi32" (ByVal hdc As IntPtr, ByVal hObject As IntPtr) As IntPtr    Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As IntPtr) As Integer    Private Declare Function DeleteDC Lib "gdi32" (ByVal hdc As IntPtr) As Integer    Private Declare Function GdiFlush Lib "gdi32" Alias "GdiFlush" () As Integer    Private Const SRCCOPY As Integer = &HCC0020      Public Sub FloodFill(ByRef bm As Bitmap, ByVal col As Color, ByVal Pt As Point)        If bm Is Nothing Then Exit Sub        Dim srcDC As IntPtr = CreateCompatibleDC(IntPtr.Zero)        Dim dstDC As IntPtr = CreateCompatibleDC(IntPtr.Zero)        Dim dstBMI As BITMAPINFOHEADER        With dstBMI            .biBitCount = 24            .biHeight = bm.Height            .biSize = System.Runtime.InteropServices.Marshal.SizeOf(dstBMI)            .biWidth = bm.Width            .biPlanes = 1        End With        Dim dstBits As IntPtr        Dim mbmpGetHbitmap As IntPtr = bm.GetHbitmap        'Select the bitmap into an HDC        Dim Obmp As IntPtr = SelectObject(srcDC, mbmpGetHbitmap)        'Create a DIB        Dim dstBMP As IntPtr = CreateDIBSection(dstDC, dstBMI, 0, dstBits, 0, 0)        Dim Obmp2 As IntPtr = SelectObject(dstDC, dstBMP)        'Place our bitmap in the DIB        BitBlt(dstDC, 0, 0, bm.Width, bm.Height, srcDC, 0, 0, SRCCOPY)        GdiFlush()        'Create a brush to use to FloodFill        Dim mBrush As IntPtr = CreateSolidBrush(System.Drawing.ColorTranslator.ToOle(col))        Dim hmm As IntPtr = SelectObject(dstDC, mBrush)        'Fill with color        ExtFloodFill(dstDC, Pt.X, Pt.Y, GetPixel(dstDC, Pt.X, Pt.Y), 1)        'Get the bitmap back with the Filled Color        bm = Bitmap.FromHbitmap(dstBMP)        'Go berserk clearing memory        'ExtFloodFill has a bad reputation for gobbling up memory        'if you dont clean up properly        DeleteObject(mBrush)        DeleteObject(SelectObject(dstDC, mBrush))        DeleteObject(SelectObject(dstDC, dstBMP))        DeleteObject(SelectObject(srcDC, mbmpGetHbitmap))        DeleteObject(hmm)        DeleteObject(dstBits)        DeleteObject(Obmp2)        DeleteObject(Obmp)        DeleteObject(dstBMP)        DeleteDC(dstDC)        DeleteDC(srcDC)        mbmpGetHbitmap = Nothing        hmm = Nothing        dstBits = Nothing        Obmp2 = Nothing        Obmp = Nothing        dstBMP = Nothing        dstDC = Nothing        srcDC = Nothing        dstBMI = Nothing    End Sub #End RegionEnd Class
- Sử Dụng: Do tham số bm của phương thức FloodFill được chuyền theo kiểu tham chiếu làm thay đổi tham số đầu vào nên khi sử dụng phương thức này nó sẽ tạo ra một bitmap làm che lắp bm đang vẽ và chúng ta không thể tiếp tục...

- Thủ tục FillColor(e) được viết như sau:

Mã: Chọn tất cả

Private Sub FillColor(ByVal e As System.Windows.Forms.MouseEventArgs)        Try            Dim f_fill As New FillColor            f_fill.FloodFill(Me.pic.Image, c, New Point(e.X / zoom, e.Y / zoom))            ' Xoa bitmap cua ham FloodFill            bm = New Bitmap(Me.pic.Image)            Me.pic.Image = bm            gp = Graphics.FromImage(bm)        Catch ex As Exception        End Try    End Sub
Sửa lần cuối bởi 1 vào ngày 1045007 với 0 lần sửa trong tổng số.
Xếp hình cổ điển for Android-https://play.google.com
♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀
Hình đại diện của thành viên
vo_minhdat2007
Quản trị
Quản trị
Bài viết: 2227
Ngày tham gia: Chủ nhật 17/07/2005 1:40 am
Has thanked: 13 times
Been thanked: 87 times
Tiếp xúc:

Re: Sử Dụng Lớp Drawing2D - Vẽ Những Nét Cơ Bản

Gửi bài by vo_minhdat2007 »

Xin giúp em chút nhé : Em tạo 1 mạng lưới khoảng 100 ô. Tuy nhiên em tạo label Loading ở trên che hết hoạt động và hiện %, tuy nhiên khi unload cái Label thì toàn bộ các đường vẽ... tiêu hết :( . Trường hợp ko có cái Label thì OK. Có cách nào không hay đành làm cái Label ở form khác?
Hình đại diện của thành viên
1045007
Thành viên danh dự
Thành viên danh dự
Bài viết: 551
Ngày tham gia: Thứ 2 09/06/2008 3:35 pm
Đến từ: TP Cần Thơ
Has thanked: 2 times
Been thanked: 61 times
Tiếp xúc:

Re: Sử Dụng Lớp Graphics - Vẽ Những Nét Cơ Bản

Gửi bài by 1045007 »

Vẽ trong sự kiện paint thì không có việc bị mất.
Nếu vẽ trên Bitmap thì dùng Invalidate() cập nhật lại.
Sửa lần cuối bởi 1 vào ngày 1045007 với 0 lần sửa trong tổng số.
Xếp hình cổ điển for Android-https://play.google.com
♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀
Hình đại diện của thành viên
vo_minhdat2007
Quản trị
Quản trị
Bài viết: 2227
Ngày tham gia: Chủ nhật 17/07/2005 1:40 am
Has thanked: 13 times
Been thanked: 87 times
Tiếp xúc:

Re: Sử Dụng Lớp Drawing2D - Vẽ Những Nét Cơ Bản

Gửi bài by vo_minhdat2007 »

Code đây :

Mã: Chọn tất cả

For i As Integer = 0 To 9            For j As Integer = 0 To 9                PGr.DrawImage(My.Resources.Square, New RectangleF(10 + 30 * i, 10 + 30 * j, 30, 30))                CGr.DrawImage(My.Resources.Square, New RectangleF(10 + 30 * i, 10 + 30 * j, 30, 30))            Next        Next
Dù đặt sự kiện nào (trừ Paint) đều bị mất sau khi load, còn đặt trong sự kiện Paint thì nó lại vẽ nhiều lần (trong form còn vài picturebox khác)!
Hình đại diện của thành viên
1045007
Thành viên danh dự
Thành viên danh dự
Bài viết: 551
Ngày tham gia: Thứ 2 09/06/2008 3:35 pm
Đến từ: TP Cần Thơ
Has thanked: 2 times
Been thanked: 61 times
Tiếp xúc:

Re: Sử Dụng Lớp Graphics - Vẽ Những Nét Cơ Bản

Gửi bài by 1045007 »

Vẽ lại nhiều lần là đúng rồi! vì mỗi lần active form thì form dc vẽ lại lúc này nó không nhận dc đối tượng đồ họa đã vẽ! nên ta đặc trong Paint(e), Lấy cái e này vẽ!

Trong Form còn vài PictureBox khác là sao nhỉ? nói rõ xem sao?
Xem thử cái này:
Tập tin đính kèm
Project.rar
(256.79 KiB) Đã tải về 750 lần
Sửa lần cuối bởi 1 vào ngày 1045007 với 0 lần sửa trong tổng số.
Xếp hình cổ điển for Android-https://play.google.com
♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀
Hình đại diện của thành viên
1045007
Thành viên danh dự
Thành viên danh dự
Bài viết: 551
Ngày tham gia: Thứ 2 09/06/2008 3:35 pm
Đến từ: TP Cần Thơ
Has thanked: 2 times
Been thanked: 61 times
Tiếp xúc:

Re: Sử Dụng Lớp Graphics - Vẽ Những Nét Cơ Bản

Gửi bài by 1045007 »

IV. Lưu Ảnh
- Cho vào Form 1 saveFileDialog và 1 MainMenuTrip.
- Để lưu ảnh ta dùng phương thức save của đối tượng bm: bm.Save(FileName,ImageFormat).
- Lưu ảnh là phần quan trọng trong quá trình vẽ ảnh, đôi khi đang vẽ vô tình nhấn vào nút close của Form thì mọi thứ ta đã làm cũng vô tình biến mất. Vậy hãy xác định rõ trạng thái lưu hay chưa lưu để phản hồi lại sự kiện Closing của Form.
- Các biến cần khai báo:

Mã: Chọn tất cả

Dim saved As Boolean = True ‘Giữ trạng thái đã saveMe.SaveFileDialog1.Filter = "Bitmap file|*.bmp|jpg file|*.jpg|png file|*.png" ‘Khai bộ lọc gồm 3 loại định dạng
Thủ tục SaveBitmap():

Mã: Chọn tất cả

private Sub SaveBitmap()        If SaveFileDialog1.FilterIndex = 1 Then            bm.Save(SaveFileDialog1.FileName, ImageFormat.Bmp)        ElseIf SaveFileDialog1.FilterIndex = 2 Then            bm.Save(SaveFileDialog1.FileName, ImageFormat.Jpeg)        Else            bm.Save(SaveFileDialog1.FileName, ImageFormat.Png)        End If        saved = True ‘set giá trị đã save là TrueEnd Sub
Munu file/save as được chọn:

Mã: Chọn tất cả

Private Sub mn_saveas_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mn_saveas.Click        Try            If Me.SaveFileDialog1.ShowDialog() = Windows.Forms.DialogResult.OK Then                SaveBitmap()            End If        Catch ex As Exception            MsgBox(ex.Message)        End TryEnd Sub
Phản hồi sự kiện Closing của Form:

Mã: Chọn tất cả

Private Sub f_paint_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing        If saved = False Then            Dim re As DialogResult            re = MessageBox.Show("Bạn có muốn lưu lại không ?", "Thong Bao", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Warning)            If re = Windows.Forms.DialogResult.Yes Then                If Me.SaveFileDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then                    SaveBitmap()                Else                    e.Cancel = True                End If            ElseIf re = Windows.Forms.DialogResult.No Then                e.Cancel = False            Else                e.Cancel = True            End If        End IfEnd Sub
Tuần tự của sự kiện Closing như sau:
Đóng Form:
- Kiểm tra đã save chưa?
+ đã save --> không làm gì, thoát.
+ chưa save: hỏi có muốn save hay không hay hủy bỏ thao tác đóng form
# Nếu yes:
@ Nếu save: thoát
@ Nếu cancel: không thoát, không save
# Nếu No: thoát.
# Nếu Cancel: hủy bỏ thao tác đóng Form
Xếp hình cổ điển for Android-https://play.google.com
♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀
Hình đại diện của thành viên
1045007
Thành viên danh dự
Thành viên danh dự
Bài viết: 551
Ngày tham gia: Thứ 2 09/06/2008 3:35 pm
Đến từ: TP Cần Thơ
Has thanked: 2 times
Been thanked: 61 times
Tiếp xúc:

Re: Sử Dụng Lớp Graphics - Vẽ Những Nét Cơ Bản

Gửi bài by 1045007 »

V. UnDo - Redo
- Trong quá trình vẽ, việc lùi lại (undo) bước vừa vẽ hay hủy thao tác lùi lại (redo) là một phần quan trọng giúp ta đỡ phải tốn thời gian khi phải ngồi vẽ lại từ đầu. Đương nhiên việc undo hay redo không tự nhiên sẵn có. Để làm được công việc này bạn cần phải lưu vào đâu đó để khi cần chúng ta đem sử dụng lại chúng.
- Đối với hình ảnh hay các kiểu dữ liệu khác cần khai báo mảng đối tượng phù hợp với kiểu dữ liệu cần lưu. Để undo hay redo lại được nhiều lần tùy thuộc vào cách lập trình của chúng ta, lưu nhiều tốn tài nguyên hệ thống nhiều, lưu ít tốn tài nguyên ít và ở đây không bàn về vấn đề tài nguyên hệ thống.
- Để tiến hành cần khai báo các biến sau:

Mã: Chọn tất cả

    ' Cac bien Undo    Dim bmUndo As Bitmap ‘biến lưu ảnh cần undo    Dim listBMUndo(127) As Bitmap ‘danh sách ảnh undo    Dim nUndo As Short = -1 ‘vị trí undo
Thủ tục lưu ảnh Undo nếu số lượng ảnh cần lưu là < 128 ảnh:

Mã: Chọn tất cả

Private Sub SaveUndo()            If nUndo <= 127 Then                bmUndo = New Bitmap(bm)                nUndo += 1                listBMUndo(nUndo) = bmUndo                saved = False             End If End Sub
- Ví trí để đặt thủ tục này là khi kết thúc một nét vẽ để cho ta một hình ảnh xác định hay chính là sự kiện MouseUp của pictureBox

Mã: Chọn tất cả

Private Sub pic_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles pic.MouseUp        If draw = True Then            draw = False            ResetPath()           ……………………………………                  ……………………………………            SaveUndo()        End If    End Sub
- Thao tác Undo – Redo

Mã: Chọn tất cả

Private Sub mn_undo_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mn_undo.Click        Try            nUndo -= 1            bm = New Bitmap(CType(listBMUndo(nUndo), Bitmap))            Me.pic.Image = bm            gp = Graphics.FromImage(bm)        Catch ex As Exception            nUndo += 1        End Try    End Sub     Private Sub mn_redo_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mn_redo.Click        Try            nUndo += 1            bm = New Bitmap(CType(listBMUndo(nUndo), Bitmap))            Me.pic.Image = bm            gp = Graphics.FromImage(bm)        Catch ex As Exception            nUndo -= 1        End Try     End Sub
- Đây là cách làm đơn giản nhất, vì sao chúng ta nói thế? Khẳng định một điều rằng: làm như vầy CT chúng ta chiếm rất nhiều tài nguyên nếu CT sử dụng lâu vì quá nhiều ảnh được lưu và điều đó là dư thừa bởi trong quá trình vẽ ảnh cần kết xuất chỉ có 1, phần còn lại để làm gì?
- Thay vào đó các bạn có thể cải tiến bằng cách xây dựng một mảng vòng, những ảnh không còn sử dụng sẽ được chồng lên bởi ảnh mới -> số lượng ảnh lưu là ít -> tốc độ CT nhanh hơn.

Bài viết sẽ còn tiếp tục với phần 2: Edit
Xếp hình cổ điển for Android-https://play.google.com
♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀♂♀
tungtot_vl
Thành viên chính thức
Thành viên chính thức
Bài viết: 11
Ngày tham gia: Thứ 5 02/04/2009 10:03 am

Re: Sử Dụng Lớp Graphics - Vẽ Những Nét Cơ Bản

Gửi bài by tungtot_vl »

mình mới vào nghề chưa rành vb lắm. bạn chỉ giúp mình cái này nhé.
có cách nào để chia Picture box này thành n hàng và n cột không anh
vi dụ tạo 1 Picture box và chia nó thành 10 hàng, 10 cột (100cell). giống như tạo các ô lưới trong MSHFlexGrid. khi ta click chuột vào ô nào thì sẽ tạo màu cho ô đó. các ảnh load vào cũng được phân mảnh dưới dạng cell như trên. độ rộng các cell có thể thay đổi được.
bạn biết thì giúp mình nhé!
Đăng trả lời

Quay về