PixeLook
Development Group

See also:

[Image analysis]

[Vector editor]

[IPL wrapper]

[AVI - demo]

[Samples]

[ ZL.DLL ]

Monitor page
for changes

it's private
powered by
ChangeDetection

 

4

Tutorial 4. Working with raster layers                               Next | Previous

Raster layers can be useful for non-standard visualizing of image regions. In this tutorial we will process a small image region under the mouse. A raster layer will be used to visualize a result of region processing.

Setting up a raster layer

Start a new application (File/New/Application). Drop a TZImageBox and TZRasterLayer components from the PixeLook palette page onto the main form. Set the following properties of  ZRasterLayer1 in the Object Inspector:

    Parent = ZImageBox1, this attaches the raster layer to an image window;
    Active = true, this activates the layer, so that it can accept mouse messages
    PixelFormat = pf8bit, for simplicity, we only work with 8-bit images
    Transparency.Mode = [tmTransparent], this indicates that some regions of the raster layer will be transparent. The color black defines transparent regions.
    Transparency.TranspColor = clBlack, Black color defines transparent regions.

Image visualization via TZDataBitmap object

Now we read an image into the ZImageBox1. In this example we do not use the TZBitmapLink component. We connect an image file with an image window directly via the TZDataBitmap object. First, declare this object in the form class:

      private
      
    { Private declarations }
       BM:TZDataBitmap;
      ......

Then we read an image in FormCreate (do not forget to destroy the image!):

    procedure TForm1.FormCreate(Sender: TObject);
    begin
      BM:=TZDataBitmap.CreateOpen(mmDisk,'c:\work\images\lena256.bmp');
      ZImageBox1.Bitmap:=BM;
    end;

    procedure
    TForm1.FormDestroy(Sender: TObject);
    begin
      BM.Free;
    end;

Dynamic changing of a raster layer

Now we create the OnMouseMove event handler to respond to the mouse moving:

    procedure TForm1.ZRasterLayer1MouseMove(Sender: TObject;
      Shift: TShiftState; X, Y: Double);
    var xx,yy:integer;
    begin
     
    // delete previous region
      ZRasterLayer1.ImageRect:=Rect(0,0,0,0);
      ZRasterLayer1.Invalidate;
     
      xx:=trunc(x);
      yy:=trunc(y);

      //check if the mouse is inside the image
      if (xx<0) or (xx>=BM.DimX) or (yy<0) or (yy>=BM.DimY) then exit;

      //create a new region. A 40x40 rectangle is used as an example
      ZRasterLayer1.ImageRect:=Rect(xx-20,yy-20,xx+20,yy+20);
    end;

When a new region is created in a raster layer the OnNewRect event occurs. Using this event we create a specific processing of the new region, and update this region on the screen:

    procedure TForm1.ZRasterLayer1NewRect(Sender: TObject);
    begin
      with ZRasterLayer1 do
      begin
       ProcessRect(BM,ImageRect,Bitmap);
    // our image processing procedure
       invalidate;
      end;
    end;

Image processing examples

Now we implement some examples of image processing whose results are visualized by the raster layer. The procedure ProcessRect takes the original image BM, processes it in the ImageRect region and places the result into the raster layer’s Bitmap image.

The first example simply inverts the image in the region:

    procedure ProcessRect(InIm:TZDataBitmap; R:TRect; OutIm:TZDataBitmap);
    var P1,P2:PByteArray;
       x,y:integer;
       b:byte;
    begin
      for y:=R.Top to R.Bottom do
      if (y>=0) and (y<InIm.DimY) then
      begin
       P1:=InIm.ScanLine[y];
       P2:=OutIm.ScanLine[y-R.Top];
       for x:=R.Left to R.Right do
       if (x>=0) and (x<InIm.DimX) then
       begin
         b:=255-P1[x];
         if b=0 then b:=1;
         P2[x-R.Left]:=b;
       end;
      end;
    end;

The second example is more complex. It computes a histogram of the image inside a region, then equalizes it and visualizes the results of equalization. In this example the region is a circle with radius 20.

var Hist:array[0..255] of integer;

procedure ProcessRect(InIm:TZDataBitmap; R:TRect; OutIm:TZDataBitmap);
var P1,P2:PByteArray;
   x,y:integer;
   xc,yc:integer;
   b:byte;
begin
 
// determine a center of the region and check if it lies in the image
  xc:=(R.Left+R.Right) div 2;
  yc:=(R.Top+R.Bottom) div 2;
  if (xc<0) or (xc>=InIm.DimX) or (yc<0) or (yc>=InIm.DimY) then;

 
// compute a histogram inside a circle
  FillChar(Hist[0],sizeof(Hist),0);
  for y:=R.Top to R.Bottom do
  if (y>=0) and (y<InIm.DimY) then
  begin
   P1:=InIm.ScanLine[y];
   for x:=R.Left to R.Right do
   if (x>=0) and (x<InIm.DimX) and ((x-xc)+sqr(y-yc) < 400) then
       inc(Hist[P1[x]]);
  end;

 
// histogram equalization
  for x:=1 to 255 do
   inc(Hist[x],Hist[x-1]);
  for x:=0 to 255 do
   Hist[x]:=trunc(Hist[x]/Hist[255]*255);

 
// backprojection of the equalized histogram to the image
  for y:=R.Top to R.Bottom do
  if (y>=0) and (y<InIm.DimY) then
  begin
   P1:=InIm.ScanLine[y];
   P2:=OutIm.ScanLine[y-R.Top];
   for x:=R.Left to R.Right do
   if (x>=0) and (x<InIm.DimX) then
   begin
     b:=0;
    
// only the circle of radius 20 is not transparent
     if sqr(x-xc)+sqr(y-yc) < 400 then
     begin
       b:=Hist[P1[x]];
       if b=0 then b:=1;
     end;
     P2[x-R.Left]:=b;
   end;
  end;
end;

[Home] [News] [Features] [Components] [Screenshots] [Tutorials] [Download] [Order] [Contact us]

© Copyright PixeLook Development Group, 2002-2003. All rights reserved

Delphi™ is registered trademark of Borland Software Corporation.
Intel and Pentium are registered trademark of Intel Corporation.
PhotoShop is a trademark of Adobe Systems Inc.
All other trademarks are the property of their respective owners