views:

656

answers:

5

Hello,

How do I tile a image in a Timage in Delphi?

Why I need it: Instead of creating more TImages at runtime,I could create one and store my image there knowing that it will be 'fit' until it reaches TImage's height and width.

Please suggest any ideas to do this.

Thank you!

EDIT: Please note,I'm not asking for streching the image,but fitting.

A: 

By "fitting" do you mean "tiling"? As far as I know, TImage does not support this out of the box. You'd have to manually draw your picture on the TImage's Canvas in a repeating pattern.

Dmitry Brant
Yes,that's what I mean.
John
Perhaps an example?
John
+2  A: 

You could set the canvas.brush.bitmap := to the image of the tile. then canvas.fillrect(canvas.cliprect) to tile the whole canvas with the selected tile image. I haven't done it in a long time and I am not able to check if this is really how it's done in Delphi right now, but I am pretty sure this is what you're after.

Peter Perháč
+2  A: 

Delphi installation comes with a Demo named 'Bitmap' (you can find the project in Help dir.).

It uses the following method to draw a tiled image:

procedure TBmpForm.FormPaint(Sender: TObject);
var
  x, y: Integer;
begin
  y := 0;
  while y < Height do
  begin
    x := 0;
    while x < Width do
    begin
      // Bitmap is a TBitmap.
      //  form's OnCreate looks like this:
      //    Bitmap := TBitmap.Create;
      //    Bitmap.LoadFromFile('bor6.bmp');
      //  or you can use Canvas.Draw(x, y, Image1.Picture.Bitmap),
      //  instead of Canvas.Draw(x, y, Bitmap);
      //
      Canvas.Draw(x, y, Bitmap); //Bitmap is a TBitmap. 
      x := x + Bitmap.Width; // Image1.Picture.Bitmap.Width;
    end;
    y := y + Bitmap.Height; // Image1.Picture.Bitmap.Height;
  end;
end;

Hope that helps!

Olaf
+2  A: 

The following is the function that I have used, taking an existing TImage component and tiling it over a target canvas:

procedure TileImage(const Source:tImage;
    Target: TCanvas;
    TargetHeight,TargetWidth:integer);
// Tiles the source image over the given target canvas
var
  X, Y: Integer;
  dX, dY: Integer;
begin
  dX := Source.Width;
  dY := Source.Height;
  Y := 0;
  while Y < TargetHeight do
    begin
      X := 0;
      while X < TargetWidth do
        begin
          Target.Draw(X, Y, Source.Picture.graphic);
          Inc(X, dX);
        end;
      Inc(Y, dY);
    end;
end;

Because a tLabel exposes a canvas, you can do tricks like the following:

TileImage(Image1,Label1.Canvas,Label1.Height,Label1.Width);
skamradt
+3  A: 

Assuming your image is a bitmap and loaded into the TImage you can use the following

procedure TmyForm.Button1Click(Sender: TObject);
    var mybmp:TBitmap;
begin
    mybmp:= TBitmap.Create();
    try
        mybmp.Assign(Image1.Picture.Bitmap);

        Image1.Picture.Bitmap.SetSize(Image1.Width,Image1.Height);
        Image1.Canvas.Brush.Bitmap := mybmp;
        Image1.Canvas.FillRect(Image1.BoundsRect);

        mybmp.FreeImage;
    finally
        FreeandNil(mybmp)
    end;
end;

Some notes:

If you save the image after titling it you will save the titled version not the original.

Image1.Canvas and Image1.Picture.Bitmap.Canvas are one and the same, that's why you need to resize the bitmap before painting on the canvas.

If you try and assign the bitmap in the TImage to the brush without assigning it to another bitmap object first like so Image1.Canvas.Brush.Bitmap := Image1.Picture.Bitmap you get an exception "not enough storage".

Re0sless
This is much easier than most solutions calling Draw repeatedly inside a doubly-nested for-loop. Also, this code doesn't exceed it's drawing beyond the given rectangle. Thumbs up!
PatrickvL