Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Wanet Telecoms Ltd on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

DrawImage is little bit to slow

Status
Not open for further replies.

Frush

Programmer
Jun 27, 2002
75
CA
Hi, I'm creating a "mini paint" application something very simple with hand drawing straight line curve line and an ereaser.

I have some problem with my "straight line" and "curve line". If you ever played with MsPaint(I guess you did) you know how the straight line work. Trying to reproduce the effect of a "growing" line is quite easy.

1. Backup the original image
2. Load this image every time there is a mousemove event giving the impression the line is slowly growing as you move your mouse.

this is the code I'm currently using to do so :


'============================================
If tmpbitmap Is Nothing Then
tmpbitmap = New Bitmap(m_bitmap.Width, m_bitmap.Height)
graphics = graphics.FromImage(tmpbitmap)

graphics.DrawImage(m_bitmap, New Rectangle(0, 0, _
tmpbitmap.Width, tmpbitmap.Height), 0, 0, m_bitmap.Width, _
m_bitmap.Height, GraphicsUnit.Pixel)

graphics = graphics.FromImage(m_bitmap)
Else

graphics.DrawImage(tmpbitmap, New Rectangle(0, 0, _
m_bitmap.Width, m_bitmap.Height), 0, 0, tmpbitmap.Width, _
tmpbitmap.Height, GraphicsUnit.Pixel)

graphics = graphics.FromImage(m_bitmap)
End If
'======================================================

my main problem right now is when my image is too big DrawImage is way to slow to do the job and theres a little "lag" everytime I move the mouse,

So here is my question is there a better way to create a copy of a bitmap?


Ps: Excuse my poor english
 
Well, heres an idea. I'm not up to speed with this by any means. However in some gaming applications I have written we just re-drew the 'changed' pixels. Maybe that will work for you here.

 
Look at Paint.Net an opensource program that can give you good tips on how to do this.


Christiaan Baes
Belgium

My Blog
"In a system where you can define a factor as part of a third factor, you need another layer to check the main layer in case the second layer is not the base unit." - jrbarnett
 
The fastest way to draw an image would be BitBlt.

You would first load the image into memory (Image class can be used), then using its memory pointer and the destination pointer (Image/Picture box or form) you can use the GDI32 api to copy the image across.

Have a look at:
Most (if not all) systems have this built into the Northbridge, so the processor isn't even used to perform this function (Memory->GPU).
 
I have PAINT.NET here tryed to find where they "draw" but since I cant open the main form and I'm not so good with C# + there is over 150,000 line of code .. well I havent found what I was looking for.

For BitBlt tryed it and I did read this article but for some reason I fail at using it I really dont understand why. Ill redo the code I used and paste it here maybe you can help me.
 
ok so I took this example and modified it a bit to test what I was trying to do and my conclusion so far is

Picturebox.CreateGraphics <> Graphics.fromImage(bitmap)

Private Function copyRect(ByVal src As Bitmap, ByVal rect As RectangleF) As Bitmap
Dim srcPic As Graphics = Graphics.FromImage(src) 'Get a Graphics Object from the form
Dim srcBmp As New Bitmap(src.Width, src.Height, srcPic) 'Create a EMPTY bitmap from that graphics
Dim srcMem As Graphics = Graphics.FromImage(srcBmp) 'Create a Graphics object in memory from that bitmap
Dim HDC1 As IntPtr = srcPic.GetHdc 'get the IntPtr's of the graphics
Dim HDC2 As IntPtr = srcMem.GetHdc 'get the IntPtr's of the graphics

'get the picture
BitBlt(HDC2, 0, 0, src.Width, src.Height, HDC1, 0, 0, 13369376)

'Clone the bitmap so we can dispose this one
copyRect = DirectCast(srcBmp.Clone(), Bitmap)


'Clean Up
srcPic.ReleaseHdc(HDC1)
srcMem.ReleaseHdc(HDC2)
srcPic.Dispose()
srcMem.Dispose()
srcMem.Dispose()
End Function

Private Function copyRect(ByVal src As PictureBox, ByVal rect As RectangleF) As Bitmap
Dim srcPic As Graphics = src.CreateGraphics 'Get a Graphics Object from the form
Dim srcBmp As New Bitmap(src.Width, src.Height, srcPic) 'Create a EMPTY bitmap from that graphics
Dim srcMem As Graphics = Graphics.FromImage(srcBmp) 'Create a Graphics object in memory from that bitmap
Dim HDC1 As IntPtr = srcPic.GetHdc 'get the IntPtr's of the graphics
Dim HDC2 As IntPtr = srcMem.GetHdc 'get the IntPtr's of the graphics

'get the picture
BitBlt(HDC2, 0, 0, src.Width, src.Height, HDC1, 0, 0, 13369376)

'Clone the bitmap so we can dispose this one
copyRect = DirectCast(srcBmp.Clone(), Bitmap)


'Clean Up
srcPic.ReleaseHdc(HDC1)
srcMem.ReleaseHdc(HDC2)
srcPic.Dispose()
srcMem.Dispose()
srcMem.Dispose()
End Function


Private Sub dstCopy_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles dstCopy.Click
dest.Image = CType(copyRect(CType(src.Image, Bitmap), New RectangleF(0, 0, 50, src.Height)), Bitmap).Clone 'Fail
' dest.Image = CType(copyRect(src, New RectangleF(0, 0, 50, src.Height)), Bitmap).Clone 'Work
End Sub
==========================================

you can see that the only difference btw the 2 functions is the way I get srcPic graphics
 
Well, heres an idea. I'm not up to speed with this by any means. However in some gaming applications I have written we just re-drew the 'changed' pixels. Maybe that will work for you here."

I'm trying this right and even if I'm only redrawing a very small portion of the image I find the result to be slow .. really dont understand why
 
Sorry I have been very busy working today, the bitblt does work when you can get it going.

I modified someone's code to make it stream lined, and got a program that can capture one screen and put it on another, and got 30-50 frames per second @ 1280x1024 resolution.

I'll try to modify it to what you need and post some code.

But re-reading your original post, have you used the following line on your form/object?
Me.SetStyle(ControlStyles.DoubleBuffer Or ControlStyles.UserPaint, True)

Also try using regions to invalidate the picture box or form when the user is moving the line around, just as lotharious suggested. I'll try and dig out some of this code from a past project.
 

Yep, im creating a paint control so I put those in the load of the the control.

bitBlt seem to work fine with stuff "on" the screen but my bitmap is in memory and every time I tryed to copy it with bitblt I get a "black image". I read somewhere that you could copy and paste anything with bitblt but I havent been able to make it work. I also read somewhere that bitblt is 10~15% faster than DrawImage and I doubt it will be enough but its worth trying.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top