# Pixel routines

I want to be able to quikely run through all the pixels in an image/canvas so I can change them, or do whatever I want, and at the moment, all I do is:

for x:=0 to 50 do begin
for y:=0 to 50 do begin
MyCanvas.pixels[x,y]:=RGB(random(255),random(255),random(255));
end;
end;

...but this goes very slowly.  Is there a faster method?  I don't know if this is very hard, but will raise the points if it is worth it.
LVL 1
###### Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Commented:
Using the pixels method is slow but you can speed things up by making sure that everything is done in memory rather than on screen. If that isn't fast enough (or you're already doing it), switch over to using scanlines. They aren't easy to use but once you get the hang of them then it's a doddle and works like lightning.

The Neil

PS Yes, I'd raise the points
0
Commented:
Canvas.pixels[x,y]:=random(16581375) would make a small difference.

with 0..500 it takes about 0.3 seconds here... ...too slow?

You'll have to loop, this bottleneck you can't really make shorter, assembly?

I don;t know why, but you should call Randomize; before you call Random;

procedure TForm1.Button1Click(Sender: TObject);
var
x,y : integer;
begin
Randomize;
for x:=0 to 500 do
begin
for y:=0 to 500 do
begin
Canvas.pixels[x,y]:=random(16581375);//RGB(); //random(255),random(255),random(255));
end;
end;
end;

Floris.
0
Commented:
hi bogieman

try to use ScanLine metod
ScanLine metod is very faster than canvas.pixel

for example

procedure xxx(tmpBitmap: TBitmap);
var tmpBuffer:PByteArray;
i, j: Integer;
begin

tmpBitmap.PixelFormat:=pf24bit;
for j:=0 to tmpBitmap.Height-1 do
begin
tmpBuffer:=tmpBitmap.ScanLine[j];
for i:=0 to tmpBitmap.Width-1 do
begin
tmpBuffer[i+0]:=255;
tmpBuffer[i+1]:=255;
tmpBuffer[i+2]:=255;
end;
end;
end;
0

Experts Exchange Solution brought to you by

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Commented:
just a couple of points to consider:

1)Moving to a scanline (of DIB) solution would require rewriting your pixel access function for every possible pixel format, this is not a prob if you know what the pf is going to be

2)there is some overhead (however slight) with calling a method, if you do not want to code your own dib class (not too difficult if you're comfortable with the win32 api) you could change the above to:

procedure xxx(tmpBitmap: TBitmap);
var tmpBuffer:PByteArray;
i, j, delta: Integer;
begin

tmpBitmap.PixelFormat:=pf24bit;
tmpBuffer := tmpBitmap.scanline[0];
delta := integer(tmpBitmap.scanline[1])-integer(tmpbuffer);
for j:=0 to tmpBitmap.Height-1 do
begin
for i:=0 to tmpBitmap.Width-1 do
begin
tmpBuffer[i+0]:=255;
tmpBuffer[i+1]:=255;
tmpBuffer[i+2]:=255;
end;
tmpBuffer := PByteArray(integer(tmpBuffer)+delta);
end;
end;

it should be noted, though that the above makes very little difference, and if you're going to resort to hacking the vcl that way, it would be safer/cleaner/more elegant to code your own DIB class (has other pro's as well)

GL
Mike
0
Author Commented:
Cheers - that was all I needed.
0
###### It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Delphi

From novice to tech pro — start learning today.