[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Allan McLemore

10/24/2004 4:30:00 PM

Hi there,

I have made an image box which includes magnification features. All
works well except I have noticed a bottle neck when viewing images that are
very large (via high maginification).

The magnified image only gets created once so I can pin point the bottle
neck down to 1 line, and it's the DrawImage routine via the destinations
graphics object. Anyway, regardless of this, I have timed the method at
small image sizes and at large image sizes and the large ones take
considerably longer.

My question is how can I speed up drawImage??


Call iGraphics.DrawImage(cBmpAfterMagnification, pRecDestRectangle,
pRecViewPortal, GraphicsUnit.Pixel)

This is the line in question, the objects are as follows,

cBmpAfterMagnification = Source image
pRecDestRectangle = Destination rectangle, always starts at (0,0)
pRecViewPortal = Source rectangle, can be anywhere in the image at the
same dimensions of the destination rectangle

Anyway, with small images (960 x 1280) this line can complete in
something like 0-16ms, with an image 3 times the size it will complete in
roughly 110-150ms. I have tried using the GDI API but have had problems
with getting the device context for both graphics objects. But anyway,
surely this routine shouldn't slow down this much, or is there a way to
speed it up?

Cheers in advance for any help!

Nick.


2 Answers

James Westgate

10/24/2004 4:41:00 PM

0

Hi Nick,

People find DrawIMage slow becuase they generally compare it to functions
like BitBlt in the old GDI API. There are a humber of reasons why it is much
slower:

1. The GDI Bitblt call is hardware accelerated, all GDI+ inc DrawImage is
not.
2. If your source and destination rectangle are different, DrawImage will
scale the bits from the source image to the target image using the
graphics.InterpolationMode setting, so you get high quality but slower
draws.
3. DrawImage may need to convert from one PixelFormat to another. The
internal PixelFormat is 32bppparg (32 bits per pixel pre multiplied alpha
rgb) . Draws will work considerably quicker if your source image is in this
format (Parameter on the Bitmap Constructor)

You can use DrawImageUnscaled to get past the scaling bottleneck, and/or set
InterpolationMode to NearestNeighbour. It depends on how you are scaling the
images and how they are loaded. There tends to be a problem in GDI+ with
larger images becuase they have to be loaded into memory by the appropriate
image decoder first.

If you want to do some direct BitBlitting using unmanaged code, then check
this link:

http://support.crainiate.net/?s=Knowledge%20Base/Control%20Creation%20FAQ/b...

James

--
Create interactive diagrams and flowcharts with ERM Diagram at
http://www.cra...

Take the ERM Tour at http://www.flowchartc...

"Nak" <a@a.com> wrote in message
news:ujmN$aeuEHA.948@tk2msftngp13.phx.gbl...
> Hi there,
>
> I have made an image box which includes magnification features. All
> works well except I have noticed a bottle neck when viewing images that
> are very large (via high maginification).
>
> The magnified image only gets created once so I can pin point the
> bottle neck down to 1 line, and it's the DrawImage routine via the
> destinations graphics object. Anyway, regardless of this, I have timed
> the method at small image sizes and at large image sizes and the large
> ones take considerably longer.
>
> My question is how can I speed up drawImage??
>
>
> Call iGraphics.DrawImage(cBmpAfterMagnification, pRecDestRectangle,
> pRecViewPortal, GraphicsUnit.Pixel)
>
> This is the line in question, the objects are as follows,
>
> cBmpAfterMagnification = Source image
> pRecDestRectangle = Destination rectangle, always starts at (0,0)
> pRecViewPortal = Source rectangle, can be anywhere in the image at the
> same dimensions of the destination rectangle
>
> Anyway, with small images (960 x 1280) this line can complete in
> something like 0-16ms, with an image 3 times the size it will complete in
> roughly 110-150ms. I have tried using the GDI API but have had problems
> with getting the device context for both graphics objects. But anyway,
> surely this routine shouldn't slow down this much, or is there a way to
> speed it up?
>
> Cheers in advance for any help!
>
> Nick.
>


Allan McLemore

10/24/2004 5:12:00 PM

0

Hi there,

> 1. The GDI Bitblt call is hardware accelerated, all GDI+ inc DrawImage is
> not.

Yup I am aware of this, that is why I tried to get a comparrison, but
failed obtaining the HDC of the source image with an "Invalid Parameter"
exception.

> 2. If your source and destination rectangle are different, DrawImage will
> scale the bits from the source image to the target image using the
> graphics.InterpolationMode setting, so you get high quality but slower
> draws.

They are both exactly the same size, basically I am just obtaining a
section of the source image that fits in my "viewport" and then using
drawimage to display it.

> 3. DrawImage may need to convert from one PixelFormat to another. The
> internal PixelFormat is 32bppparg (32 bits per pixel pre multiplied alpha
> rgb) . Draws will work considerably quicker if your source image is in
> this format (Parameter on the Bitmap Constructor)

I've just assured that all bitmap objects created use the same pixel
format as the original image, I recieved a few ms speed improvement, but
nothing major. I have an average of about 109ms to draw a section of an
image 3 x (960,1280).

> You can use DrawImageUnscaled to get past the scaling bottleneck, and/or
> set InterpolationMode to NearestNeighbour. It depends on how you are
> scaling the images and how they are loaded. There tends to be a problem in
> GDI+ with larger images becuase they have to be loaded into memory by the
> appropriate image decoder first.

As I said, the *scaled* image is only being created once, not every
redraw, basically I have 2 bitmaps in memory, 1 the destination, and 1 the
source, and I'm taking a section the size of the destination bitmap from the
source bitmap and displaying it with displayimage.

> If you want to do some direct BitBlitting using unmanaged code, then check
> this link:
>
> http://support.crainiate.net/?s=Knowledge%20Base/Control%20Creation%20FAQ/b...
>

I've had a go at using BitBlt but I can't get the HDC for the source
object (cBmpAfterMagnification associated graphics object). I just get
"Invalid Parameter" exception, not quite sure what this means as I can't
find any references to it in the docs or on google.

I've just tried using drawImageUnscaled and this takes even longer than
drawImage because it is having to draw the entire object (I presume). I've
even used SetClip on the destination object to limit where the image is
drawn but still no luck.

But anyway, if that is how it is meant to be then so be it :-( I'll
poke at it for a bit and hope for the best before I give in!

Cheers loads for the advice!

Nick.