[fpc-pascal] Performance problems with Image Conversions
Michael Van Canneyt
michael at freepascal.org
Sun Feb 24 11:44:42 CET 2013
On Sat, 23 Feb 2013, Andrew Brunner wrote:
> Hi guys,
>
> I just finished (a beta) of a collage app for Aurawin. I'm seeing a huge
> load on my servers when scaling images using the Image factory classes for
> JPEG, and PNG.
>
> Prefix:
> 6 Core AMD 64 32GB RAM Ubuntu 12.10 x64
> 8 Core AMD 64 32GB RAM Ubuntu 12.10 x64
> FPC/Lazarus daily svn/trunk
>
> Overview:
> 1.) end-user grabs references to files (stored on my server)
> 2.) back-end core object scales camera photos to something more net friendly
> 512px max to scale.
> 3.) server streams photos back to client over the web and
> 4.) server assembles XML stream of Mime encoded file data for things like
> https://aurawin.com/cb?3
Try to get rid of the XML, it is always going to be slow.
Using XML can slow your applications with a factor 6.
If you are mime-encoding an image, it'll be even more.
> Specifics
>
> The pics in this sample take about 30 seconds to go from their originals to
> 512px. The app waits for the collage to save to the cloud. The problem gets
> worse for larger collages with more images.
>
> iX,iY are no larger than 512
>
> class function Image.Transform(Stream:TStream; var
> sContentType,srcKind,dstKind:string; var iX,iY:Integer):boolean;
> var
> FReader : TFPCustomImageReader;
> FWriter : TFPCustomImageWriter;
> cReader : TFPCustomImageReaderClass;
> cWriter : TFPCustomImageWriterClass;
> Factor : Double;
> FTransparent : boolean;
> dstImg : TFPMemoryImage;
> srcImg : TFPMemoryImage;
> srcCanvas : TFPImageCanvas;
> dstCanvas : TFPImageCanvas;
>
>
> procedure FreeImageData;
> begin
> if (srcCanvas<>nil) then
> srcCanvas.Free();
Do a FreeAndNil(srcCanvas) here.
1. Free already checks if the pointer is not nil.
You do not need to check again.
2. FreeAndNil will make sure the pointer is Nil
> srcImg:=TFPMemoryImage.Create(0,0);
Do not use TFPMemoryImage.
It is a catch-all memory format, not optimized at all, using 64 bits for the images.
Instead, use e.g. TFPCompactImgRGBA8Bit if you need alpha or TFPCompactImgRGB8Bit if you do not need Alpha.
> dstImg:=TFPMemoryImage.Create(iX,iY);
> dstImg.UsePalette:=false;
> dstCanvas:=TFPImageCanvas.create(dstImg);
> dstCanvas.StretchDraw(0,0,iX,iY,srcImg);
Phew, this is also a real killer.
Do not draw on a canvas with stretchdraw. That will be slow as well;
Rather, attempt to manipulate the image in memory by doing a stretch directly.
Choose an algorithm which is fast. The default interpolation will result in
quite a lot of calculations.
Michael.
More information about the fpc-pascal
mailing list