Groups | Blog | Home
all groups > dotnet drawing api > july 2004 >

dotnet drawing api : Update on DrawImage speeds for pixel formats


Frank Hileman
7/28/2004 10:52:36 AM
This sounds consistent with what we discovered when optimizing VG.net.

Regards,
Frank Hileman

check out VG.net: www.vgdotnet.com
Animated vector graphics system
Integrated Visual Studio .NET graphics editor

[quoted text, click to view]
Hi,

For anyone interested, got some timings on copies using different pixel
formats, and the results are (if I've got my methodology right) surprising.
Code below.
It loads a file from disk, converts it to the image format specified by
copyFrom and then copies a little bit of it a hundred times into an image
whose format is specified by copyTo.

What I found was that if either of the input params was not Format32bppPArgb
I was getting times of around 12 - 16 seconds (with a 2000 X 3000 image to
start with) dependent on the input params. Outputting to PArgb was always
faster.

If both formats were Format32bppPArgb it was two thousand times faster
(0.005 seconds). Am I doing something wrong or is this a recognised
'feature'? It seems almost insane that anyone could engineer something that
gave times like this.

Steve


Code's in C++, and I haven't checked it in anything else. Compiled with
/clr. Optimization gives small increase in performance (from 15 seconds to
11 with every optimization available) for the slow ones, nothing for the
premultiplied alpha image.


void CopyRGBToRGB( PixelFormat copyFrom, PixelFormat copyTo )
{
Image *fromFile = Image::FromFile( S"C:\\SomeFile.tif" );
Bitmap *sourceImage;
if ( fromFile->PixelFormat != copyFrom )
{
sourceImage = new Bitmap( fromFile->Width, fromFile->Height,
copyFrom );
Graphics *e = Graphics::FromImage( sourceImage );
e->DrawImageUnscaled( fromFile, 0, 0 );
}
else
{
sourceImage = dynamic_cast< Bitmap * >(fromFile);
}
// Now we have our source.
Bitmap *destinationImage = new Bitmap( fromFile->Width,
fromFile->Height, copyTo );
Graphics *destGraphics = Graphics::FromImage( destinationImage );
destGraphics->InterpolationMode = InterpolationMode::NearestNeighbor;
destGraphics->CompositingMode = CompositingMode::SourceCopy;
destGraphics->CompositingQuality = CompositingQuality::HighSpeed;
destGraphics->SmoothingMode = SmoothingMode::HighSpeed;
int iterations = 100;

Console::WriteLine( "Ready! Doing copies from {0} to {1}, {2} times",
__box( copyFrom ), __box( copyTo ), __box( iterations ) );

Rectangle littleBit( 0, 0, 100, 100 );
for ( int timesRound = 0; timesRound < 3 ; timesRound++ )
{
// timer->Start()
for ( int i = 0 ; i < iterations ; i++ )
{
destGraphics->DrawImage( sourceImage, littleBit, littleBit,
GraphicsUnit::Pixel);
}
// double finished = timer->Stop();
// Console::WriteLine( "Finished (trial {0}). Time was {1}",
__box( timesRound ), __box( finished ) );
}
}

Steve McLellan
7/28/2004 12:56:03 PM
Hi,

For anyone interested, got some timings on copies using different pixel =
formats, and the results are (if I've got my methodology right) =
surprising. Code below.
It loads a file from disk, converts it to the image format specified by =
copyFrom and then copies a little bit of it a hundred times into an =
image whose format is specified by copyTo.

What I found was that if either of the input params was not =
Format32bppPArgb I was getting times of around 12 - 16 seconds (with a =
2000 X 3000 image to start with) dependent on the input params. =
Outputting to PArgb was always faster.

If both formats were Format32bppPArgb it was two thousand times faster =
(0.005 seconds). Am I doing something wrong or is this a recognised =
'feature'? It seems almost insane that anyone could engineer something =
that gave times like this.

Steve


Code's in C++, and I haven't checked it in anything else. Compiled with =
/clr. Optimization gives small increase in performance (from 15 seconds =
to 11 with every optimization available) for the slow ones, nothing for =
the premultiplied alpha image.


void CopyRGBToRGB( PixelFormat copyFrom, PixelFormat copyTo )
{
Image *fromFile =3D Image::FromFile( S"C:\\SomeFile.tif" );
Bitmap *sourceImage;
if ( fromFile->PixelFormat !=3D copyFrom )
{
sourceImage =3D new Bitmap( fromFile->Width, fromFile->Height, =
copyFrom );
Graphics *e =3D Graphics::FromImage( sourceImage );
e->DrawImageUnscaled( fromFile, 0, 0 );
}
else
{
sourceImage =3D dynamic_cast< Bitmap * >(fromFile);
}
// Now we have our source.
Bitmap *destinationImage =3D new Bitmap( fromFile->Width, =
fromFile->Height, copyTo );
Graphics *destGraphics =3D Graphics::FromImage( destinationImage );
destGraphics->InterpolationMode =3D =
InterpolationMode::NearestNeighbor;
destGraphics->CompositingMode =3D CompositingMode::SourceCopy;
destGraphics->CompositingQuality =3D CompositingQuality::HighSpeed;
destGraphics->SmoothingMode =3D SmoothingMode::HighSpeed;
int iterations =3D 100;

Console::WriteLine( "Ready! Doing copies from {0} to {1}, {2} =
times", __box( copyFrom ), __box( copyTo ), __box( iterations ) );
=20
Rectangle littleBit( 0, 0, 100, 100 );
for ( int timesRound =3D 0; timesRound < 3 ; timesRound++ )
{
// timer->Start()
for ( int i =3D 0 ; i < iterations ; i++ )
{
destGraphics->DrawImage( sourceImage, littleBit, littleBit, =
GraphicsUnit::Pixel);
}
// double finished =3D timer->Stop();
// Console::WriteLine( "Finished (trial {0}). Time was {1}", =
__box( timesRound ), __box( finished ) );
}
AddThis Social Bookmark Button