home *** CD-ROM | disk | FTP | other *** search
- unit maskgenerator;
-
- interface
-
- uses
- Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
- StdCtrls, ComCtrls, Buttons, ExtCtrls, CoolForm, ExtDlgs;
-
- type
- TFormMaskGenerator = class(TForm)
- SpeedButton1: TSpeedButton;
- SpeedButton2: TSpeedButton;
- SpeedButton3: TSpeedButton;
- Panel1: TPanel;
- CoolForm1: TCoolForm;
- Image1: TImage;
- OpenDialog1: TOpenPictureDialog;
- SpeedButton4: TSpeedButton;
- SaveDialog1: TSaveDialog;
- procedure SpeedButton1Click(Sender: TObject);
- procedure SpeedButton2Click(Sender: TObject);
- procedure SpeedButton3Click(Sender: TObject);
- procedure Image1MouseMove(Sender: TObject; Shift: TShiftState; X,Y: Integer);
- procedure Image1MouseDown(Sender: TObject; Button: TMouseButton;Shift: TShiftState; X, Y: Integer);
- procedure BitMapChange(Sender:TObject);
- procedure FormCreate(Sender: TObject);
- procedure SpeedButton4Click(Sender: TObject);
- private
- oldleft,oldtop:integer;
- generating:boolean;
- public
- OriginalRegionSize:integer;
- OriginalRegiondata:pRGNData;
- rgn1:hrgn;
- procedure SaveOriginalRegionData;
- destructor destroy; override;
- end;
-
- var
- FormMaskGenerator: TFormMaskGenerator;
-
-
- implementation
-
- {$R *.DFM}
-
- procedure TFormMaskGenerator.SpeedButton1Click(Sender: TObject);
- begin
- if Opendialog1.Execute then image1.Picture.bitmap.LoadFromFile(opendialog1.filename);
- end;
-
-
- // This method is necessary to react to changes in the size of the bitmap
- procedure TFormMaskGenerator.BitMapChange(Sender:TObject);
- var
- tr2,temprgn:hrgn;
- x:pxform;
- begin
- if not generating then
- begin
- // This is the transformation matrix to be used in the region generating process
- // will be used in future releases
- x:=new(pxform);
- x.eM11:=1;
- x.eM12:=0;
- x.eM21:=0;
- x.eM22:=1;
- x.eDx:=-oldleft;
- x.eDy:=-oldtop;
-
- // the original region is created (the generator form only)
- temprgn:=ExtCreateRegion(x,originalRegionSize,OriginalRegionData^);
- image1.width:=image1.picture.bitmap.width;
- image1.height:=image1.picture.bitmap.height;
- clientwidth:=image1.Left+image1.Width;
- clientHeight:=image1.Top+image1.Height;
- if clientwidth<=150 then ClientWidth:=150;
- if clientHeight<=150 then ClientHeight:=150;
-
- // a region for the bitmap is created
- tr2:=CreateRectRgn(image1.left,image1.top,image1.left+image1.width,image1.top+image1.height);
- // the two regions are combined
- CombineRgn(temprgn,temprgn,tr2,RGN_OR);
- // set the new region
- DeleteObject(CoolForm1.Mask.fregion);
- CoolForm1.Mask.Fregion:=tempRgn;
- SetWindowRgn(handle,temprgn,true);
- // clean up
- DeleteObject(tr2);
- image1.repaint;
- dispose(x);
- end;
- end;
-
-
- // this method is called by the Propertyeditor to backup the maskgenerator`s mask generated at design-time
- procedure TFormMaskGenerator.SaveOriginalRegionData;
- begin
- // clean up
- if OriginalRegionData<>nil then
- begin
- freemem(OriginalRegionData);
- OriginalRegionData:=nil;
- end;
- // save original mask information
- oldleft:=left;
- oldtop:=top;
- OriginalRegionsize:=GetRegionData(CoolForm1.Mask.Fregion,0,nil);
- getmem(OriginalRegionData,OriginalRegionsize);
- getregiondata(CoolForm1.Mask.FRegion,OriginalRegionsize,OriginalRegiondata);
- end;
-
- destructor TFormMaskGenerator.destroy;
- begin
- // clean up
- if OriginalRegionData<>nil then
- begin
- freemem(originalregiondata);
- end;
- OriginalRegionData:=nil;
- inherited;
- end;
-
-
- procedure TFormMaskGenerator.SpeedButton2Click(Sender: TObject);
- begin
- close;
- end;
-
- // This is called when the User clicks the OK Button
- procedure TFormMaskGenerator.SpeedButton3Click(Sender: TObject);
- var
- // stream : TFileStream;
- size : integer;
- // rgndata : pRGNData;
- x,y : integer;
- transparentcolor : tcolor;
- rgn2 : hrgn;
- startx,endx : integer;
- R : TRect;
-
- begin
- if Panel1.Color = clNone then
- Begin
- ShowMessage('You must select the colour to be masked out.'#13+
- 'Click on the mask colour in the bitmap. '#13 +
- '(It will appear in the square to the right of the load button).');
- Exit;
- End;
- generating:=true;
- // clean up
- if rgn1<>0 then deleteObject(rgn1);
- rgn1 := 0;
- // set the transparent color
- transparentcolor:=Panel1.color;
- // if necessary, load another mask (don`t know why again... should be redundant)
- if opendialog1.filename<>'' then image1.picture.bitmap.loadfromfile(opendialog1.filename);
-
- // for every line do...
- for y := 0 to image1.Picture.Height-1 do
- begin
- // don`t look as if we were locked up
- Application.ProcessMessages;
- x:=0;
- endx:=x;
- // no flicker
- lockWindowUpdate(FormMaskGenerator.handle);
- repeat
- // look for the beginning of a stretch of non-transparent pixels
- while (image1.picture.bitmap.canvas.pixels[x,y]=transparentcolor) and (x<=image1.picture.width) do
- inc(x);
- startx:=x;
- // paint the pixels up to here black
- for size:=endx to startx do image1.picture.bitmap.canvas.pixels[size,y]:=image1.picture.bitmap.canvas.pixels[size,y] xor $FFFFFF;
- // look for the end of a stretch of non-transparent pixels
- inc(x);
- while (image1.picture.bitmap.canvas.pixels[x,y]<>transparentcolor) and (x<=image1.picture.width) do
- inc(x);
- endx:=x;
- // do we have some pixels?
- if startx<>image1.Picture.Width then
- begin
- if endx= image1.Picture.Width then dec(endx);
- // do we have a region already?
- if rgn1 = 0 then
- begin
- // Create a region to start with
- rgn1:=createrectrgn(startx+1,y,endx,y+1);
- end else
- begin
- // Add to the existing region
- rgn2:=createrectrgn(startx+1,y,endx,y+1);
- if rgn2<>0 then combinergn(rgn1,rgn1,rgn2,RGN_OR);
- deleteobject(rgn2);
- end;
- // Paint the pixels white
- for size:=startx to endx do image1.picture.bitmap.canvas.pixels[size,y]:=image1.picture.bitmap.canvas.pixels[size,y] xor $FFFFFF;
- end;
- until x>=image1.picture.width-1;
- // flicker on
- lockwindowUpdate(0);
- // tell windows to repaint only the line of the bitmap we just processed
- R.top:=image1.top+y;
- r.Bottom:=image1.top+y+1;
- r.left:=image1.left;
- r.right:=image1.left+image1.Width;
- invalidaterect(formmaskgenerator.handle,@R,false);
- formmaskgenerator.Update;
- end;
- generating:=false;
- close;
- end;
-
-
- procedure TFormMaskGenerator.Image1MouseMove(Sender: TObject; Shift: TShiftState; X,Y: Integer);
- begin
- if ssLeft in Shift then
- begin
- panel1.color:=image1.picture.bitmap.canvas.pixels[x,y];
- end;
- end;
-
-
- procedure TFormMaskGenerator.Image1MouseDown(Sender: TObject; Button: TMouseButton;Shift: TShiftState; X, Y: Integer);
- begin
- panel1.color:=image1.picture.bitmap.canvas.pixels[x,y];
- end;
-
-
- procedure TFormMaskGenerator.FormCreate(Sender: TObject);
- begin
- image1.picture.OnChange:=BitMapChange;
- end;
-
- procedure TFormMaskGenerator.SpeedButton4Click(Sender: TObject);
- var
- size : integer;
- rgndata : pRGNData;
- writer : TFileStream;
-
- begin
- If SaveDialog1.Execute then
- begin
- if (rgn1<>0) then
- begin
- writer :=TFileStream.Create (SaveDialog1.Filename, fmCreate);
- // get the region data`s size
- size:=getregiondata (rgn1, 0, nil);
- getmem (rgndata, size);
- // get the data itself
- getregiondata(rgn1, size, rgndata);
- // write it
- writer.write (size, sizeof(size));
- writer.write (rgndata^, size);
- freemem(rgndata, size);
- writer.Free;
- end;
- end;
- end;
-
- end.
-