2008. január 15., kedd

How to blend two TBitmap's (3)


Problem/Question/Abstract:

I was wondering how I could overlay/ transpose an image over another while taking account the transparent background. Basically, what I want to do is to allow my client to place a transparent logo (an overlay image) unto their other image. Each time I tried to do that, I keep getting the rectangular background.

Answer:

Here is some code to merge two bitmaps. It is not exactly what you are looking for, but it is a place to start. You would need to check for the transparency color and skip those pixels and only operate on the rect of the smaller bitmap.

{ ... }
MaxPixelCount = 65536;

type
  TRGBArray = array[0..MaxPixelCount - 1] of TRGBTriple;
  pRGBArray = ^TRGBArray;

function MergeBitmap(const BitmapA: TBitmap; const WeightA: Cardinal;
  const BitmapB: TBitmap; const WeightB: Cardinal): TBitmap;
var
  i, j: Integer;
  RowA: pRGBArray;
  RowB: pRGBArray;
  RowTween: pRGBArray;
  SumWeights: Cardinal;

  function WeightPixels(const pixelA, pixelB: Cardinal): Byte;
  begin
    Result := Byte((WeightA * pixelA + WeightB * pixelB) div SumWeights)
  end;

begin
  SumWeights := WeightA + WeightB;
  Result := TBitmap.Create;
  Result.Width := BitmapA.Width;
  Result.Height := BitmapA.Height;
  Result.PixelFormat := pf24bit;
  if WeightA = 0 then
    Result.Canvas.Draw(0, 0, BitmapB)
  else if WeightB = 0 then
    Result.Canvas.Draw(0, 0, BitmapA)
  else if SumWeights > 0 then
  begin
    for j := 0 to Result.Height - 1 do
    begin
      RowA := BitmapA.Scanline[j];
      RowB := BitmapB.Scanline[j];
      RowTween := Result.Scanline[j];
      for i := 0 to Result.Width - 1 do
      begin
        with RowTween[i] do
        begin
          rgbtRed := WeightPixels(rowA[i].rgbtRed, rowB[i].rgbtRed);
          rgbtGreen := WeightPixels(rowA[i].rgbtGreen, rowB[i].rgbtGreen);
          rgbtBlue := WeightPixels(rowA[i].rgbtBlue, rowB[i].rgbtBlue)
        end;
      end;
    end;
  end;
end;

Nincsenek megjegyzések:

Megjegyzés küldése