Use TPictureClip custom component to extract portions of a matrix of pictures and assign the "cell picture" to another picture control.
TPictureClipWhat I have in mind, is to create a new Delphi component that allows you to extract portions of a matrix of pictures (images) and assign the "cell picture" to another image component, or to another component that has the Canvas property to draw on.
The TPictureClip control will store multiple images that can be used by other Delphi controls. All images are contained in a single bitmap. Selected regions can then be 'clipped' from the bitmap and, for example, used with a TImage control to create animations.
Note: The TPictureClip control is similar to the TImageList, however, they differ in that all image resources in the TPictureClip component must be contained in a single bitmap whereas the TImageList control is a collection of separate bitmaps.
... New ControlBefore we get to the code, if you are not familiar with custom component building in Delphi, try reading the article Custom Component Development, we need some of the info in this article to understand the methods we will use below.
For the start we have to derive our component from, naturally enough, the TImage. Reason: we want a control that is prepared to take a picture property. Again, if you are not sure how to derive a new component from an existing one, read the following HowTo: How To Create the Basic Unit for a New Component (these are the steps to crating a new graphics component from TImage).
TPictureClip = class(TImage)To accomplish our task, we can divide the image contained in the TPictureClip picture property into a specified number of rows and columns. The rows and columns create cells which can then be accessed using an Index number. The cells are indexed beginning at 0 and increase from left to right and top to bottom using the GraphicCell property, precisely from 0 to (Cols * Rows) - 1.
Now, we have to create a function GetCellGraphic which will extract a portion of a picture and assign it to another picture property.
... type TPictureClip = class(TImage) private FRows:Integer; FCols:Integer; FPicture:TPicture; function GetCellGraphic (Index:Integer):TPicture; public constructor Create(AOwner: TComponent) ; override; destructor Destroy; override; property GraphicCell[Index:Integer]:TPicture read GetCellGraphic; published property Rows:Integer read FRows write FRows; property Cols:Integer read FCols write FCols; end; ...
function TPictureClip.GetCellGraphic(Index:Integer):TPicture; var BWidth, BHeight : Integer; SrcRect, DestRect : TRect; begin BWidth := Picture.Width div FCols; BHeight := Picture.Height div FRows; DestRect := Rect(0, 0, BWidth, BHeight) ; SrcRect.Left := (Index mod Cols) * BWidth; SrcRect.Top := (Index div Cols) * BHeight; SrcRect.Right := SrcRect.Left + BWidth; SrcRect.Bottom := SrcRect.Top + BHeight; FPicture.Bitmap.Width := BWidth; FPicture.Bitmap.Height := BHeight; FPicture.Bitmap.Canvas.CopyRect(DestRect, Canvas, SrcRect) ; GetCellGraphic := FPicture; end;