Categories
Delphi

The Delphi Essential Selection

The following are what I personally
consider the essential 3rd part components and libraries that are need to build
a Delphi Application. You may well disagree, but this is what I have tended to
standardise on and have found useful.

Tnt Unicode Controls

You want your application to be used by as many
people as possible so lets make it store it's data as unicode and use a set of
components that support unicode perfectly. The Tnt Unicode controls provides
unicode versions of all the components found on Standard, Additional, Win32, and
Dialogs pallette tabs.

Tnt Controls can be found at http://www.tntware.com/delphicontrols/

Virtual Tree View

The VirtualTreeView controls, VirtualStringTree and
VirtualDrawTree provide the only tree control you'll need. Full Implemented in
Delphi, and developed over 3 years, this little baby is superb. It is unicode
compliant, integrates with the tntUnicode editors, and supports the virtual
paradigm so loading a tree up with a million nodes is no problem.

In
addition it is probably one of the most customisable controls you'll come
across, allowing you easily to override paint routines to provide the perfrect
presentation that you need. It should be noted also that there is an extremely
loyal and developled following of users of the VirtualTreeView and there are
some great resources and example applications on teh delphi-gems
site.

Virtual Tree View can be found at http://www.delphi-gems.com/VirtualTreeview/

TPNGImage

The TPNGImage units provide PNG reading and writing support
for Delphi. It integrates and registers iteself as a TGraphic descendant and
allows access to scanline and a scanline for the alpha transparency as
well.
This implementation can be a little slow at times if you are trying to
implement large png images with full alpha support, but it is exellent for
creating transparent forms with nice anti-aliased edges.
See my splash
screen article
for a great use of the TPNGImage unit.

TPNGImage is
free, opensource and available from http://pngdelphi.sourceforge.net/

Turbopower Lockbox

LockBox is a cross-platform toolkit for data
encryption. It contains routines & components for use with Borland Delphi,
C++Builder, & Kylix. It provides support for Blowfish, RSA, MD5, SHA-1, DES,
triple- DES, Rijndael, & digital signing of messages. If you need to do
encryption or signing then these libraries are faast and free.

Lockbox is
opensource and available from http://sourceforge.net/projects/tplockbox/

Turbopower Abbrevia

Abbrevia is a compression toolkit for Borland
Delphi, C++Builder, & Kylix. It supports PKZIP 4, Microsoft CAB, TAR, &
gzip formats & the creation of self-extracting archives. It includes visual
components that simplify the manipulation of ZIP files.

Abbrevia is
opensource and is available from http://sourceforge.net/projects/tpabbrevia/

Categories
Delphi

How to split an image with Alpha into a bitmap and mask image in GDI+

The following code provides a routine for splitting out a source image with an Alpha channel into two images, the first holding the RGB information and the second as a Grayscale mask image.
The routine uses the GDI+ bitmap’s Lockbits method to provide fast access to the image data.
This routine is available in the GDIPExtensions unit which is part of GDI+ Controls.

function SplitAlpha(Source: TGPBitmap; var Bitmap: TGPBitmap;
  var Mask: TGPBitmap): boolean;

  procedure SetGrayScale(palette: PColorPalette);
  var
    i: integer;
  begin
    for i := 0 to Palette.Count - 1 do
    begin
      palette.Entries[i] := MakeColor(i, i, i);
    end;
  end;
var
  SourcePixelFormat: PixelFormat;
  w, h: cardinal;
  x, y: cardinal;
  sbmd: TBitmapData;
  bbmd: TBitmapData;
  mbmd: TBitmapData;
  r: TGPRect;
  sImageStart: PByteArray;
  spixelpos
    : integer;
  sPixel: pARGB;
  bImageStart: PByteArray;
  bpixelpos: integer;
  bPixel: PRGBTriple;
  mImageStart: PByteArray;
  mpixelpos: integer;
  mPixel: pByte;
  Palette: pColorPalette;
  PaletteSize: cardinal;
begin
  Bitmap := nil;
  Mask := nil;
  if not assigned(Source) then raise EImageProcessError.create('No sourceimage assigned');
  if (source.GetWidth = 0) or (source.GetHeight = 0) then raise  EImageProcessError.create('Height and width of source image must be greater than zero');

  SourcePixelFormat := source.GetPixelFormat;
  if not IsAlphaPixelFormat(SourcePixelFormat) then raise EImageProcessError.create('Source image does not have alpha channel');

  w := Source.GetWidth;
  h := source.GetHeight;

  Bitmap := TGPBitmap.Create(w, h, PixelFormat32bppRGB);
  Mask := TGPBitmap.Create(w, h, PixelFormat8bppIndexed);

  PaletteSize := mask.GetPaletteSize;
  Palette := AllocMem(PaletteSize);

  mask.GetPalette(Palette, PaletteSize);
  SetGrayScale(Palette);
  mask.SetPalette(Palette);
  FreeMem(Palette, PaletteSize);

  r := MakeRect(0, 0, integer(w), integer(h));
  source.LockBits(r, ImageLockModeRead, PixelFormat32bppARGB, sbmd);
  bitmap.LockBits(r, ImageLockModeWrite, PixelFormat32bppRGB, bbmd);
  mask.LockBits(r, ImageLockModeWrite, PixelFormat8bppIndexed, mbmd);

  sImageStart := sbmd.Scan0;
  bImageStart := bbmd.Scan0;
  mImageStart := mbmd.Scan0;
  for y := 0 to sbmd.Height - 1 do
  begin
    for x := 0 to sbmd.Width - 1 do
    begin
      spixelpos := (y * cardinal(sbmd.Stride)) +
        (x * 4);
      sPixel := @sImageStart[sPixelPos];
      bpixelpos := (y * cardinal(bbmd.Stride))
        + (x * 4);
      bPixel := @bImageStart[bPixelPos];
      mpixelpos := (y * cardinal(mbmd.Stride))
        + (x);
      mPixel := @mImageStart[mPixelPos];
      bPixel.rgbtRed := (spixel^
        and
        $FF0000) shr 16;
      bPixel.rgbtGreen := (spixel^ and $00FF00)
        shr
        8;
      bPixel.rgbtBlue := (spixel^ and $0000FF);
      mpixel^ := (spixel^ and ALPHA_MASK)
        shr
        ALPHA_SHIFT;
    end;
  end;
  source.UnlockBits(sbmd);
  bitmap.UnlockBits(bbmd);
  mask.UnlockBits(mbmd);
  result := true;
end;