unit filterStackSmasher;
(* ***** BEGIN LICENSE BLOCK *****
* Copyright (C) 2004 Durand Emmanuel
* Copyright (C) 2004 Burgel Eric
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Contact :
* filters@edurand.com
* filters@burgel.com
*
* ***** END LICENSE BLOCK ***** *)
{
eburgel (filters@burgel.com)
}
{ ***********************************************************
Combine all images from a Stack into a single image.
*************************************************************}
interface
uses
filter, fparameters, image;
type
TFilterStackSmasher = class(TFilter)
public
constructor Create(); override;
destructor Destroy; override;
procedure Run(); override;
procedure setParameterImages( const aName: String; const aImages: ArrayOfPBitmap32); override;
private
parameterImagesIn : TParameterImages;
outputparameterImageOut : TParameterImage;
inImages : ArrayOfPBitmap32 ;
imageOuts : ArrayOfPBitmap32;
outImage : PBitmap32;
procedure _run();
procedure deleteImages;
end;
implementation
uses
imageIO ;
constructor TFilterStackSmasher.Create() ;
begin
inherited Create() ;
parameterImagesIn := addParameterImages('inImages', 'inImages') ;
outputparameterImageOut := addOutputParameterImage('outImage', 'outImage');
outImage:=nil;
end;
destructor TFilterStackSmasher.Destroy;
begin
deleteImages;
inherited;
end;
procedure TFilterStackSmasher.deleteImages;
begin
image.freeImage(outImage);
end;
procedure TFilterStackSmasher.setParameterImages( const aName: String; const aImages: ArrayOfPBitmap32);
begin
inherited;
if aName='inImages' then begin
deleteImages;
end;
end;
procedure TFilterStackSmasher.Run();
begin
inImages := parameterImagesIn.Images ;
if (inImages<>nil) then begin
_run();
end;
end;
procedure TFilterStackSmasher._run();
Var
i : Integer ;
imageIn : PBitmap32 ;
maxWidth : Integer ;
maxHeight : Integer ;
color : TColorRec ;
pSrc : Array of PColor32Array ;
increments : Array of Array of Integer ;
pDst : PColor32Array ;
x, y, y2 : Integer ;
R, G, B : Cardinal ;
sR, sG, sB : Cardinal ;
Nbr : Word ;
divisor : Cardinal ;
begin
Nbr := Length(inImages) ;
divisor := $10000 div Nbr ;
maxWidth := 0 ;
maxHeight := 0 ;
setLength(increments, Nbr) ;
if outImage = nil then Begin
// look for the max width and height
for i := 0 to Nbr-1 do Begin
setLength(increments[i], maxWidth) ;
imageIn := inImages[i] ;
if imageIn.Width > maxWidth Then maxWidth := imageIn.Width ;
if imageIn.Height > maxHeight Then maxHeight := imageIn.Height ;
end ;
outImage := createImage(maxWidth, maxHeight) ;
End else Begin
maxWidth := imageOuts[0].Width ;
maxHeight := imageOuts[0].Height ;
End ;
for i := 0 to Nbr-1 do Begin
setLength(increments[i],maxWidth-1) ;
For x := 0 to maxWidth-2 do Begin
increments[i][x] := (inImages[i].Width*(x+1) div maxWidth)-(inImages[i].Width*x div maxWidth) ;
End ;
End ;
setLength(pSrc, Nbr) ;
// now combining all images
For y := 0 to maxHeight-1 do Begin
for i := 0 to Nbr-1 do Begin
y2 := inImages[i].Height*y div maxHeight ;
pSrc[i] := scanLine(inImages[i], y2) ;
End ;
pDst := scanLine(outImage, y) ;
For x := 0 to maxWidth-1 do Begin
sR := 0 ;
sG := 0 ;
sB := 0 ;
for i := 0 to Nbr-1 do Begin
//x2 := inImages[i].width*x div maxWidth ;
//R := TColorRec(pSrc[i]^[x2]).Red ;
//G := TColorRec(pSrc[i]^[x2]).Green ;
//B := TColorRec(pSrc[i]^[x2]).Blue ;
R := TColorRec(pSrc[i]^[0]).Red ;
G := TColorRec(pSrc[i]^[0]).Green ;
B := TColorRec(pSrc[i]^[0]).Blue ;
inc(sR, R) ;
inc(sG, G) ;
inc(sB, B) ;
inc(pSrc[i], increments[i][x]) ;
End ;
sR := sR * divisor div $10000 ;
sG := sG * divisor div $10000 ;
sB := sB * divisor div $10000 ;
color.Red := sR ;
color.Green := sG ;
color.Blue := sB ;
pDst[0] := Color.value ;
inc(pDst) ;
End ;
End ;
setOutputParameterImage('outImage',outImage);
end;
end.