[Last Call] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 596
  • Last Modified:

ScanLine, what is it used for?

D3 says "ScanLine is used only with DIBs (Device Independent Bitmaps) for image editing tools that do low level pixel work." I used the (help) example and it worked but didn't make much sense or reason. So, I'm looking for "scanline" sample code that actually lets you change and/or move  pixels in a meaningful purpose, such as drawing or painting a "scanline" at a time. See the D3 sample, it's not to useful.
   
0
sz3905
Asked:
sz3905
  • 3
  • 3
1 Solution
 
jorgen.hojdmoCommented:
Hi!

The only thing you can do with a "ScanLine" is to get access to singel pixels one row in a Bitmap. When it comes to drawing lines in the bitmap using scanlines, you have to implement the linedrawing algorithm yourself. For drawing, use the canvas instead. The pixelvalues you get access to is of type byte (in 256 color mode) and says nothing about what color it represents. If you want to paint with a specific color, you must put that color in the bitmapinfo structure and use its index as pixelvalue or assign a new HPalette to the bitmap, with YOUR colors in it.  

here is an example to turn a bitmap upsidedown:

procedure TForm1.Button1Click(Sender: TObject);

var
  x,y : integer;
  BitMap : TBitMap;
  P1,P2 : PByteArray;
  tmp: :byte;
begin
  BitMap := TBitMap.create;
  try
    BitMap.LoadFromFile('C:\Program Files\Borland\Delphi 3\Images\Splash\256color\factory.bmp');
    for y := 0 to (BitMap.height -1) div 2 do  // loop through half the bitmap
    begin
      P1 := BitMap.ScanLine[y]; // get access to row y
      P2 := BitMap.ScanLine[BitMap.height - y]
      for x := 0 to BitMap.width -1 do  //swap rows
        tmp := P1[x];  // same as getpixel[x,y], if that function existed
        P1[x] := P2[x];
        P2[x] := tmp;
    end;
  canvas.draw(0,0,BitMap); //Draw bitmap on canvas
  finally
    BitMap.free;
  end;
end;
0
 
sz3905Author Commented:
Greetings Jorgen,
I'm sorry, but your example is almost the same as the D3 sample. And drawing lines on a canvas, or in a bitmap is simple enough, but I dont need to that. D3 says scanline is used "for image editing tools that do low level pixel work". Are you saying that swapping pixel rows in a bitmap is as "low level" as it gets?
/Steve S.
0
 
jorgen.hojdmoCommented:
Hi Again!

What I say is that the only thing you can do with scanline is to get access to single pixels. This is as "low level" as it can be.
The swopping of rows was just an example of moving pixels. I could have sent you a program that warps the image, but it would only have used scanlines to access single pixels. I'm sorry, I might have misunderstod what you where asking for. If you would like to paint on the bitmap, then assing the desired pixels a value. This is low level pixel work.

In Delphi 2 you could access pixels only through the Pixels property, but it was very slow. This is much faster.
 
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
sz3905Author Commented:
Hello Again Jorgen,
Thx for the quick answer. Let me explain what I'm trying to do and if you understand it, good maybe you can help, if not that's okay too(see ** below). I have one offscreen mageX.picture.bitmap(not a file). I would like to move/paint/redraw one visible row at a time from imageX to another Tcanvas X,y position. The position is the bottom row of a trect scroll window, this "line of pixels" would then be scrolled upward by one pixel. The X,y is static and never changes. Kinda like painting one row at a time @ the same position. Must the paint or draw be done using a method of the Tcanvas?
 
** You said "I could have sent you a program that warps the image, but it would only have used scanlines to access single pixels." perhaps this could get me started. You send it, the points are yours.
Thx again!
/steve s
0
 
jorgen.hojdmoCommented:
Hi!
This should do it. You don't have to access the pixels. Accessing the pixels directly makes things more complicated.

..replace with your canvases-> DestCanvas,SrcCanvas: TCanvas;

DestRect,SrcRect: TRect;

DestRect = Rect(x1,y1,x1+width-1,y1+1);
for x2 := 0 to SrcCanvas.Width - 1 do begin
.. your code for scrolling
  SrcRect = Rect(x2,y2,x2+width-1,y2+1);
  DestCanvas.CopyRect(DestRect, SrcCanvas, SrcRect);
end;

This will work only if you recieve no repaint events to the control, because the repaint event will clear the canvas. If it isn't a bitmap, that is.

You could use the winAPI to do it, but then it would take som more code, without any gain. Check the help for StrechDIBits if you want to dive in to the horror of WinAPI Graphics.

0
 
sz3905Author Commented:
Still interested in you warp code?
thx!
sbsullivan@ucdavis.edu
0

Featured Post

Important Lessons on Recovering from Petya

In their most recent webinar, Skyport Systems explores ways to isolate and protect critical databases to keep the core of your company safe from harm.

  • 3
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now