ImageEn, unit iexBitmaps

TIEBitmap.Scanline

TIEBitmap.Scanline


Declaration

property Scanline[row: integer]: pointer


Description

Retrieves an entire line of pixels at a time.
Result is a pointer. Its type will depend on the bitmap's PixelFormat:
Pixel Format Result Type
ie1g, ie8p, ie8g PByte
ie16g PWord
ie24RGB PRGB
ie32RGB PRGBA
ie48RGB PRGB48
ie32f PSingle
ieCMYK PCMYK
ieCIELab PCIELab

For Location=ieFile or PixelFormat=ieVirtual you can only use last line obtained from Scanline[] (consequently this is not thread safe).

Note:
For performance, the specified index is not checked for validity (exception will be raised if it is out-of-range).
Editing via scanline does not update Full, so if you are editing an alpha channel, you should call SyncFull after editing is completed


Demo

Demo  Demos\ImageEditing\EveryMethod\EveryMethod.dpr


Examples

// Convert image to gray-scale (PixelFormat must be ie24RGB)
// Same as TImageEnProc.ConvertToGray
var
  x, y: Integer;
  pPix: PRGB;
  Gray: Byte;
begin
  for y := 0 to ImageEnView1.IEBitmap.Height - 1 do
  begin
    pPix := ImageEnView1.IEBitmap.ScanLine[ y ];
    for x := 0 to ImageEnView1.IEBitmap.Width - 1 do
    begin
      Gray := (pPix^.R * IEGlobalSettings().RedToGrayCoef + pPix^.G * IEGlobalSettings().GreenToGrayCoef + pPix^.B * IEGlobalSettings().BlueToGrayCoef) div 100;
      pPix^.R := Gray;
      pPix^.G := Gray;
      pPix^.B := Gray;

      inc( pPix );
    end;
  end;
  ImageEnView1.Update();
end;


// Set all pixels within selection as red
// Same as ImageEnView1.SetSelectedPixelsColor
var
  x, y: Integer;
  pSel: pbyte;
  pPix: PRGB;
begin
  if ImageEnView1.SelectionMask.IsEmpty then
    raise Exception.create( 'Nothing selected' );

  if ImageEnView1.IEBitmap.PixelFormat <> ie24RGB then
    raise Exception.create( 'Not 24bit' );

  // Process selected area
  for y := 0 to ImageEnView1.SelectionMask.Height - 1 do
  begin
    pSel := ImageEnView1.SelectionMask.ScanLine[ y ];
    pPix := ImageEnView1.IEBitmap.ScanLine[ y ];

    case ImageEnView1.SelectionMask.BitsPerPixel of
      1:
        for x := 0 to ImageEnView1.SelectionMask.Width - 1 do
        begin
          // 1 Bit mask (values are 0 or 1)
          if (pbytearray(pSel)^[x shr 3] and IEBitMask1[x and $7]) <> 0 then
          begin
            pPix^.R := 255;
            pPix^.G := 0;
            pPix^.B := 0;
          end;
          inc( pPix );
        end;
      8:
        for x := 0 to ImageEnView1.SelectionMask.Width - 1 do
        begin
          // 8 Bit mask (values are 0 to 255)
          if pSel^ <> 0 then
          begin
            pPix^.R := 255;
            pPix^.G := 0;
            pPix^.B := 0;
          end;
          inc( pSel );
          inc( pPix );
        end;
    end;
  end;
  ImageEnView1.Update();
end;

// Create SVG by converting pixels to circles (PixelFormat must be ie24RGB)
// NOTE: THIS IS AN EXAMPLE ONLY and should only used for very small files
procedure SaveBitmapAsSVG(bmp: TIEBitmap; const DestFilename: string);
const
  SVG_Opening_Tag   = '<svg width="%dpx" height="%dpx" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">';
  SVG_Closing_Tag   = '</svg>';
  SVG_Circle_Tag    = '<circle cx="%d" cy="%d" r="1" fill="rgb(%d,%d,%d)"/>';
var
  ss : TStringList;
  x, y: Integer;
  pPix: PRGB;
begin
  ss := TStringList.create();
  try
    ss.Add( format( SVG_Opening_Tag, [ bmp.Width, bmp.Height ]));

    for y := 0 to bmp.Height - 1 do
    begin
      pPix := bmp.ScanLine[ y ];
      for x := 0 to bmp.Width - 1 do
      begin
        ss.Add( format( SVG_Circle_Tag, [ x, y, pPix^.R, pPix^.G, pPix^.B ]));
        inc( pPix );
      end;
    end;
    ss.Add( SVG_Closing_Tag );
    ss.SaveToFile( DestFilename );
  finally
    ss.Free;
  end;
end;

// Search the image for consecutive rows of mostly white
function FindConsecutiveWhiteRows(MinWhiteValue: Integer; MinConsecutiveWhiteRows: Integer; out WhiteRowsStart: Integer; out WhiteRowsEnd: Integer): Boolean;
var
  x, y: Integer;
  pPix: PRGB;
  Gray: Byte;
  rowIsWhite: Boolean;
  consecutiveWhiteRows: Integer;
begin
  Result := False;
  WhiteRowsStart := 0;
  WhiteRowsEnd   := 0;

  consecutiveWhiteRows := 0;
  for y := 0 to ImageEnView1.IEBitmap.Height - 1 do
  begin
    pPix := ImageEnView1.IEBitmap.ScanLine[ y ];
    rowIsWhite := True;
    for x := 0 to ImageEnView1.IEBitmap.Width - 1 do
    begin
      if (pPix^.R < White_MinWhiteValue ) or (pPix^.G < MinWhiteValue ) or (pPix^.B < MinWhiteValue ) then
      begin
        rowIsWhite := False;
        Break;
      end;
      inc( pPix );
    end;
    if rowIsWhite then
      inc( consecutiveWhiteRows )
    else
      consecutiveWhiteRows := 0;

    if consecutiveWhiteRows >= MinConsecutiveWhiteRows then
    begin
      Result := True;
      WhiteRowsStart := y - consecutiveWhiteRows + 1;
      WhiteRowsEnd   := y;
      exit;
    end;
  end;
end;


See Also

GetRow
FreeRow
GetSegment