tags:

views:

146

answers:

1

Hello,
I am working with Delphi. I am using bmp.ScanLine[] in my code. My code is as follows :

   bmp := TBitmap.Create;
   bmp.Height := imgMain.Height;
   bmp.Width := imgMain.Width;
   for i := 0 to imgMain.Height - 1 do begin
      prgb := bmp.ScanLine[i];
      p1 := imgMain.ScanLine[i];
      for j := 0 to imgMain.Width - 1 do begin
         //Some code
      end;
   end;

Here, imgMain is of TBitmap type. My problem is when I execute this code, it takes too much time on the lines

prgb := bmp.ScanLine[i];
p1 := imgMain.ScanLine[i];

Please, tell me where I am wrong?

+2  A: 

Hmm, something can be gained (introducing rowpitch, see below) but that is not too much. Probably changing the for loop to a while loop that does pointer increment and compares with a pointer value of the last pixel

   // from memory, might need an additional typecast here or there.

   // will typically be negative
   scanline0:=imga.scanline[0];
   rowpitchimga:=integer(imga.scanline[1])-integer(scanline0);  // bytes to jump row.

   prgb1 :=scanline0;
   for i:=0 to imgmain.height-1;
     begin
       prgbend:=prgb1;
       inc(prgbend,width);  // if prgbend, it will be with sizeof(prgb1^)
       while(prgb1<prbend) do // smaller then, since prgb1[] is 0 based.
         begin
           // do your thing
           inc(prgb1);
         end;      
       prgb1:=prgbend;
       inc(pointer(prgb1),rowpitch-width*sizeof(prgb1^));  // skip alignmentbytes
       inc(pointer(prgbend),rowpitch);
     end;

See also http://stackoverflow.com/questions/848025/rotating-bitmaps-in-code for a routine that does things like this to rotate an image fast.

Allocating bmps all the time can be expensive too, specially if they are large, use pools to avoid repeated allocation.

Marco van de Voort
That's the way to do it. You're right.Don't forget to use NativeInt instead of Integer if you want your code to be ready with 64 bit compiler! No Troll here:rowpitchimga:=NativeInt(imga.scanline[1])-NativeInt(scanline0);Before Delphi 2007, you'll have to define type NativeInt=integer;
A.Bouchez
It's actually defined as ptruint, and it already runs on 64-bit. It was originally developed using Free Pascal. Why Embarcadero chose a different identifier, I don't know
Marco van de Voort
Hey @Marco, sorry for late reply. Yes, this can be a solution. But one more thing I observed is that if I only write `p1 := imgMain.Scanline[i];` then it will not take so much time. So, it is just taking time in `prgb := bmp.Scanline[i];`. Here, imgMain is a bitmap which is copied from TImage bitmap using `TBitmap.Assign();`.
Himadri
There was something with Delphi bitmaps being windows based (handle allocated with windows) and not (device independant iirc). It might be the conversion between the two types that delays.
Marco van de Voort