Mega Code Archive

 
Categories / Delphi / Examples
 

Bitmaps

SOME USEFUL BITS OF CODE RELATING TO THE MANIPULATION OF BITMAPS See also IconsAndButtonBitMaps.txt THIS WORKS: (simple copy from TImage to TBitMap) procedure TDrawStyleObj.WriteBitMapFile(formImage: TImage; blocksW, blocksH: Integer; bmpFileName: String); {Copy the TImage passed to the procedure to a bitMap Canvas using Assign} var tempBitMapOne: Graphics.TBitMap; exeFileName : String; exeFilePath : String; begin tempBitMapOne := Graphics.TBitMap.Create; {it's one line of code if no scaling is involved} tempBitMapOne.Assign(formImage.Picture.BitMap); exeFileName := Application.ExeName; exeFilePath := ExtractFilePath(exeFileName); bmpFileName := exeFilePath + bitMapFileDir + bmpFileName + '.bmp'; tempBitMapOne.SaveToFile(bmpFileName); tempBitMapOne.Free; end; THIS WORKS: (copy from TImage to TBitMap with scaling) procedure TDrawStyleObj.WriteBitMapFile(formImage: TImage; blocksW, blocksH: Integer; bmpFileName: String); {Copy the TImage passed to the procedure to a bitMap Canvas using the StretchDraw function. Converting from TImages to TBitMaps can be fiddly but the StretchDraw method works OK here...} var destRect : TRect; tempBitMapOne: Graphics.TBitMap; exeFileName : String; exeFilePath : String; begin tempBitMapOne := Graphics.TBitMap.Create; tempBitMapOne.Width := 150; tempBitMapOne.Height := 150; destRect.Left := 0; destRect.Top := 0; destRect.Right := 150; destRect.Bottom := 150; tempBitMapOne.Canvas.CopyMode := cmSrcCopy; //note the syntax for using the StretchDraw method-> //StretchDraw expects a second parameter of TGraphic... tempBitMapOne.Canvas.StretchDraw(destRect, formImage.Picture.Graphic); exeFileName := Application.ExeName; exeFilePath := ExtractFilePath(exeFileName); bmpFileName := exeFilePath + bitMapFileDir + bmpFileName + '.bmp'; tempBitMapOne.SaveToFile(bmpFileName); tempBitMapOne.Free; end; THIS WORKS: (copy from TImage to TBitMap with scaling of the image and the bitmap both centred and also surrounded with a white border) procedure TDrawStyleObj.WriteBitMapFileNumberThree(formImage: TImage; blocksW, blocksH: Integer; bmpFileName: String); {Copy the TImage passed to the procedure to a bitMap Canvas using the StretchDraw function. Converting from TImages to TBitMaps can be fiddly but the StretchDraw method works OK here...} var destRect : TRect; tempBitMapOne: Graphics.TBitMap; exeFileName : String; exeFilePath : String; begin tempBitMapOne := Graphics.TBitMap.Create; {in Fox, the 'thumbnail' bitmaps are 250 by 200 pixels, so let's conform to the same dimensions for consistency's sake...} tempBitMapOne.Width := 250; tempBitMapOne.Height := 200; destRect.Left := 50; destRect.Top := 25; destRect.Right := 200; destRect.Bottom := 175; tempBitMapOne.Canvas.CopyMode := cmSrcCopy; //note the syntax for using the StretchDraw method-> //StretchDraw expects a second parameter of TGraphic... tempBitMapOne.Canvas.StretchDraw(destRect, formImage.Picture.Graphic); exeFileName := Application.ExeName; exeFilePath := ExtractFilePath(exeFileName); bmpFileName := exeFilePath + bitMapFileDir + bmpFileName + '.bmp'; tempBitMapOne.SaveToFile(bmpFileName); tempBitMapOne.Free; end; *************************************************************************************** MAKE A BITMAP NEGATIVE: Try this procedure TTest.Button1Click(Sender: TObject); var Rec := TRect; begin Rec.Left := 0; Rec.Top := 0; Rec.Right := Image1.Picture.Bitmap.Width; Rec.Botton := Image1.Picture.Bitmap.Height; Image1.Canvas.CopyMode := cmNotSrcCopy; Image1.Canvas.CopyRect(Rec,Image1.Canvas,Rec); end; { if image is negative one click change for not negative if image is not negative one click change for negative} *************************************************************************************** COMPLETE (HURRIED) PROGRAM TO SCALE A BITMAP unit MainUnit; //Richard Ebbs //ELIS October 2000 //wee buggy test app //to see 'ow 'orrible //(or otherwise) bitmaps //look when they are scaled interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, Buttons, StdCtrls; const zoomIncrement = 1.1; type TMainForm = class(TForm) TopPanel: TPanel; DrawArea: TImage; ZoomInSB: TSpeedButton; ZoomOutSB: TSpeedButton; DefaultButton: TButton; procedure FormCreate(Sender: TObject); procedure FormResize(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure ZoomInSBClick(Sender: TObject); procedure ZoomOutSBClick(Sender: TObject); procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); procedure DefaultButtonClick(Sender: TObject); private {private declarations} originalBitMap: TBitMap; drawnBitMap: TBitMap; currentScale: Real; procedure SetImageExtents; procedure FillDrawArea; procedure LoadBitMapFromDisk; procedure ScaleBitMap; procedure DrawScaledBitMap; public {public declarations} end; var MainForm: TMainForm; implementation {$R *.DFM} procedure TMainForm.FormCreate(Sender: TObject); begin currentScale := 1.0; SetImageExtents; originalBitMap := TBitMap.Create; drawnBitMap := TBitMap.Create; LoadBitMapFromDisk; DrawArea.Canvas.Draw(50, 50, originalBitMap); KeyPreview := True; //DrawScaledBitMap; //DrawArea.Refresh; end; procedure TMainForm.FormDestroy(Sender: TObject); begin originalBitMap.Free; drawnBitMap.Free; end; procedure TMainForm.FormResize(Sender: TObject); begin if (MainForm.Width > Screen.Width) then MainForm.Width := (Screen.Width - 1); if (MainForm.Height > Screen.Height) then MainForm.Height := (Screen.Height - 1); DrawArea.Width := MainForm.Width; DrawArea.Height := MainForm.Height; //FillDrawArea; //DrawScaledBitMap; //DrawArea.Refresh; end; procedure TMainForm.SetImageExtents; {sometimes you find that if you put a TImage on a form and use the TImage as a 'draw area' it won't resize properly when the form is resized. This may have to do with only a certain amount of space being reserved for the image in memory (and the values of TImage.Width/Height not always being congruent with 'internal bitmap.width/height'). This procedure attempts to get around these problems as here we expand the image to the screen's width at the outset so that this much maximum space is always available whatever resizing of the image we do later...} begin DrawArea.Width := Screen.Width; DrawArea.Height := Screen.Height; DrawArea.Canvas.MoveTo(0, 0); DrawArea.Canvas.Pen.Color := clWhite; DrawArea.Canvas.LineTo(DrawArea.Width, DrawArea.Height); DrawArea.align := alClient; end; procedure TMainForm.FillDrawArea; //set the drawing area background //colour to be white var imageRect: TRect; begin with DrawArea.Canvas do begin Brush.Color := clWhite; imageRect.Left := 0; imageRect.Top := 0; imageRect.Right := Screen.Width; imageRect.Bottom := Screen.Height; FillRect(imageRect); end; end; procedure TMainForm.LoadBitMapFromDisk; begin originalBitMap.LoadFromFile('Arnolfini.bmp'); end; procedure TMainForm.ScaleBitMap; //OK we don't need the tempBitMap //variable at all: we could just //copy from originalBitMap to //drawnBitMap but the heck... var tempWidth, tempHeight: Real; tempBitMap: TBitMap; newRect: TRect; begin tempBitMap := TBitMap.Create; tempWidth := (originalBitMap.Width * currentScale); tempHeight := (originalBitMap.Height * currentScale); newRect.Left := 0; newRect.Right := Round(tempWidth); newRect.Top := 0; newRect.Bottom := Round(tempHeight); tempBitMap.Width := Round(tempWidth); tempBitMap.Height := Round(tempHeight); tempBitMap.Canvas.StretchDraw(newRect, originalBitMap); //FillDrawArea; //DrawArea.Canvas.Draw(50, 50, tempBitMap); drawnBitMap.Width := tempBitMap.Width; drawnBitMap.Height := tempBitMap.Height; drawnBitMap.Assign(tempBitMap); tempBitMap.Free; end; procedure TMainForm.DrawScaledBitMap; begin FillDrawArea; DrawArea.Canvas.Draw(50, 50, drawnBitMap); end; procedure TMainForm.ZoomInSBClick(Sender: TObject); //zoom in begin currentScale := (currentScale * zoomIncrement); ScaleBitMap; DrawScaledBitMap; end; procedure TMainForm.ZoomOutSBClick(Sender: TObject); //zoom out begin currentScale := (currentScale * (1 / zoomIncrement)); ScaleBitMap; DrawScaledBitMap; end; procedure TMainForm.DefaultButtonClick(Sender: TObject); begin currentScale := 1.0; FillDrawArea; DrawArea.Canvas.Draw(50, 50, originalBitMap); end; procedure TMainForm.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); var keyChar: Char; begin keyChar := Char(Key); if ((keyChar = 'a') or (keyChar = 'A')) then begin currentScale := (currentScale * zoomIncrement); ScaleBitMap; DrawScaledBitMap; end; if ((keyChar = 'b') or (keyChar = 'B')) then begin currentScale := (currentScale * (1 / zoomIncrement)); ScaleBitMap; DrawScaledBitMap; end; if ((keyChar = 'd') or (keyChar = 'D')) then begin currentScale := 1.0; FillDrawArea; DrawArea.Canvas.Draw(50, 50, originalBitMap); end; end; end.