I have big problem with GDI+... We're creating graphics ActiveX component by
API functions, and now we need rewrite this one to .NET component... Problem
is with performance in .NET...
For example, this code painting 10000 lines to Form1 in Viasual Basic.NET
using GDI+ :
-- Pentium III 860 MHz 512 RAM
!!!!! - cca 1.666 second !!!!
Imports System.Drawing
Imports System.Drawing.Imaging
Public Class Form1
Inherits System.Windows.Forms.Form
#Region " Windows Form Designer generated code "
...
#End Region
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
Dim b As New Bitmap(1000, 1000)
Dim g As Graphics
g = Graphics.FromImage(b)
Dim i As Integer
Dim pen As New Pen(New Color().Black)
Dim t As DateTime = Now
For i = 1 To 10000
g.DrawLine(pen, 0, 0, 1000, 1000)
Next
g.Dispose()
Me.BackgroundImage = b
MsgBox("End - " & Now.Subtract(t).TotalSeconds & " second")
End Sub
End Class
And second example in Visual Basic 6.0 with Windows API :
!!!!! - cca 0,243 second !!!!
Option Explicit
Private Declare Function CreateCompatibleBitmap Lib "gdi32" (ByVal hdc As
Long, ByVal nWidth As Long, ByVal nHeight As Long) As Long
Private Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hdc As
Long) As Long
Private Declare Function DeleteDC Lib "gdi32" (ByVal hdc As Long) As Long
Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long)
As Long
Private Declare Function SelectObject Lib "gdi32" (ByVal hdc As Long,
ByVal hObject As Long) As Long
Private Declare Function LineTo Lib "gdi32" (ByVal hdc As Long, ByVal X As
Long, ByVal Y As Long) As Long
Private Declare Function MoveToEx Lib "gdi32" (ByVal hdc As Long, ByVal X
As Long, ByVal Y As Long, lpPoint As Any) As Long
Private Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, ByVal
X As Long, ByVal Y As Long, ByVal nWidth As Long, ByVal nHeight As Long,
ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As
Long) As Long
Private Declare Function CreatePen Lib "gdi32" (ByVal nPenStyle As Long,
ByVal nWidth As Long, ByVal crColor As Long) As Long
Private Sub Command1_Click()
Dim CompDC As Long, mBitmap As Long, i As Long, pen As Long
Dim tmrs As Double
CompDC = CreateCompatibleDC(Me.hdc)
mBitmap = CreateCompatibleBitmap(Me.hdc, 1000, 1000)
DeleteObject SelectObject(CompDC, mBitmap)
tmrs = Timer
pen = CreatePen(0, 1, vbRed)
BitBlt CompDC, 0, 0, 1000, 1000, CompDC, 0, 0, vbWhite
For i = 1 To 10000
SelectObject CompDC, pen
MoveToEx CompDC, 0, 0, 0&
LineTo CompDC, 1000, 1000
Next i
BitBlt Me.hdc, 0, 0, 1000, 1000, CompDC, 0, 0, vbSrcCopy
tmrs = Timer - tmrs
MsgBox tmrs
DeleteDC CompDC
End Sub
Please help me, because I don't use GDI+ and .NET Framework. In this example
is GDI+ very slow :-((( And I need rewrite component to .NET with identical
performance.
Thanks
Regards
Igor Stanek
> I have big problem with GDI+... We're creating graphics ActiveX component
by
> API functions, and now we need rewrite this one to .NET component...
Problem
> is with performance in .NET...
>
> Please help me, because I don't use GDI+ and .NET Framework. In this
example
> is GDI+ very slow :-((( And I need rewrite component to .NET with
identical
> performance.
GDI+ does not have identical performance as compared to GDI. Therefore,
you will not get identical performance if you use GDI+. For identical
performance, call identical function - PInvoke to GDI.
If you want to stick with GDI+, you can probably get a little better
performance by setting SmoothingMode to None, and PixelOffsetMode to None.
Thanks,
- John
Microsoft Developer Support
This posting is provided "AS IS" with no warranties, and confers no rights.
Visit http://www.microsoft.com/security for current information on security.
it comes to this, that, I must use a Windows API in my graphics component
(to draw some plans of areals, etc.)... Hmmm, how I can draw to memory (to
some DeviceContext ???) in .NET? Because, when I using API, that I'm
dependent to MS Windows (and their API) and no only .NET Framework......
Thanx
Igor Stanek
"John Hornick [MS]" <JHor...@online.microsoft.com> wrote in message
news:nOdb0HZXCHA.1260@cpmsftngxa08...
As an interesting test, I switched the g.DrawLine to a
System.Windows.Forms.ControlPaint.DrawReversibleLine; it was 254%
faster than DrawLine, which is rather funny since DrawReversibleLine
should be doing far more work to read a pixel, xor it, and write it
back.
As a final test, I ported your VB6/GDI code to VB.NET/GDI interop. It
was 3400% faster than the GDI+ version. Moral of the story, avoid
GDI+ for anything that needs speed, unless you're willing to bet
Microsoft will release a GDI+ 2.0 with hardware acceleration within
your product's lifetime.
I'm still waiting for somebody from Microsoft to explain GDI+
performance to me; I think I'm way over that 72 hour guarantee from my
previous posts on the subject.
Have a nice day,
Robert W. Grubbs
> it comes to this, that, I must use a Windows API in my graphics component
> (to draw some plans of areals, etc.)... Hmmm, how I can draw to memory (to
> some DeviceContext ???) in .NET? Because, when I using API, that I'm
> dependent to MS Windows (and their API) and no only .NET Framework......
To draw on a memory Bitmap, use something like this pseudocode:
Bitmap b = new Bitmap( width, height, PixelFormat.32bppPARGB );
Graphics g = Graphics.FromImage( b );
// Draw on g
g.Dispose();
Also, you can LockBits() on a Bitmap and do whatever you want to the
memory.
-Brian
"Igor Stanek" <i.st...@termoklima.sk> wrote in message
news:eMxuLkVXCHA.2528@tkmsftngp12...
BTW, ControlPaint performs no clipping (it's horribly promiscuous -
draws on top of anything!), which may be way it outperforms Graphics.
Ken Brady, Principal Developer
www.audioonyx.com
C++ Programmer, biochemist, and occasional musician
I have found a solution that works for me. Firstly, try using the drawpath
method. Of all the different ways to draw multiple joined lines, this method
is the quickest.
Secondly, and by far the most importantly, render to a bitmap in memory then
copy the bitmap to your output form. There was a huge increase in
performance doing it this way.
I'm also working in VB.net, so if you need example code, let me know
Regards,
Chris
"Igor Stanek" <i.st...@termoklima.sk> wrote in message
news:eMxuLkVXCHA.2528@tkmsftngp12...