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

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();
    if (dstCanvas<>nil) then
      dstCanvas.Free();
    if (FReader<>nil) then
      FReader.Free();
    if FWriter<>nil then
      FWriter.Free();
    if srcImg<>nil then
      srcImg.Free();
    if dstImg<>nil then
      dstImg.Free();
  end;
begin
  Result:=false;
  if SameText(srcKind,Image.Kind.GIF.Name) then begin
    sContentType:=hHTTP.ctPNG;
    dstKind:=Image.Kind.PNG.Name;
    FTransparent:=true;
  end else if SameText(srcKind,Image.Kind.PNG.Name) then begin
    dstKind:=Image.Kind.PNG.Name;
    FTransparent:=true;
  end else begin
    sContentType:=hHTTP.ctJPG;
    dstKind:=Image.Kind.JPG.Name;
    FTransparent:=false;
  end;
  cReader:=FPImage.ImageHandlers.ImageReader[srcKind];
  cWriter:=FPImage.ImageHandlers.ImageWriter[dstKind];
dstCanvas:=nil; srcCanvas:=nil; FReader:=nil; FWriter:=nil; srcImg:=nil; dstImg:=nil;
  Result:=(cReader<>nil) and (cWriter<>nil);
  if Result then begin
    Try
      FReader:=cReader.Create();
      FWriter:=cWriter.Create();

      if SameText(dstKind,Image.Kind.PNG.Name) then begin
        TFPWriterPNG(FWriter).Indexed:=false;
        TFPWriterPNG(FWriter).UseAlpha:=true;
      end;

      srcImg:=TFPMemoryImage.Create(0,0);
      srcImg.UsePalette:=false;
      Stream.Position:=0;
      Try
        srcImg.LoadFromStream(Stream,FReader);
        Stream.Position:=0;

        if (srcImg.Width>=srcImg.Height) then begin
          Factor:=iX/srcImg.Width;
        end else begin
          Factor:=iY/srcImg.Height;
        end;

        if (srcImg.Width>iX) or (srcImg.Height>iY) then begin
          if FTransparent then begin
            if SameText(srcKind,Image.Kind.GIF.Name) then begin
              FTransparent:=TFPReaderGIF(FReader).Transparent;
              TFPWriterPNG(FWriter).UseAlpha:=true;
            end;
          end;

          iX:= Round(srcImg.Width * Factor);
          iY:= Round(srcImg.Height * Factor);

          dstImg:=TFPMemoryImage.Create(iX,iY);
          dstImg.UsePalette:=false;
          dstCanvas:=TFPImageCanvas.create(dstImg);
          dstCanvas.StretchDraw(0,0,iX,iY,srcImg);

          Stream.Size:=0;
          dstImg.SaveToStream(Stream,FWriter);
          Stream.Position:=0;
          Result:=true;
        end;
      Except
        Stream.Size:=0;
        Stream.Position:=0;
        Result:=false;
      end;
    Finally
      FreeImageData();
    end;
  end;
end;

Further, when a user views images via my preview app, I don't send the originals, I scale those too using the same methods. The speed is killing my server's performance.

Does anyone have any idea how to speed up the underlining code?

--
Andrew Brunner

Aurawin LLC
15843 Garrison Circle
Austin, TX 78717

https://aurawin.com

Aurawin is a great new way to store, share, and explore all your content
featuring our innovative cloud social computing platform.
_______________________________________________
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal

Reply via email to