DrawTiledImage(ImageID, X, Y, Width, Height)

Got an idea for enhancing PureBasic? New command(s) you'd like to see?
eesau
Enthusiast
Enthusiast
Posts: 589
Joined: Fri Apr 27, 2007 12:38 pm
Location: Finland

DrawTiledImage(ImageID, X, Y, Width, Height)

Post by eesau »

A function to draw an image tiled on the output would be useful.
Seymour Clufley
Addict
Addict
Posts: 1264
Joined: Wed Feb 28, 2007 9:13 am
Location: London

Post by Seymour Clufley »

But you could code that in seconds...!
JACK WEBB: "Coding in C is like sculpting a statue using only sandpaper. You can do it, but the result wouldn't be any better. So why bother? Just use the right tools and get the job done."
eesau
Enthusiast
Enthusiast
Posts: 589
Joined: Fri Apr 27, 2007 12:38 pm
Location: Finland

Post by eesau »

I know, and I have! I still think that a native solution would be better than my own version.
User avatar
Kaeru Gaman
Addict
Addict
Posts: 4826
Joined: Sun Mar 19, 2006 1:57 pm
Location: Germany

Post by Kaeru Gaman »

I don't think so.
it would not be faster, and having the same tile all over is just a special case.
oh... and have a nice day.
eesau
Enthusiast
Enthusiast
Posts: 589
Joined: Fri Apr 27, 2007 12:38 pm
Location: Finland

Post by eesau »

Please feel free to post your versions of this to tips & tricks then, since the solution I came up with wasn't very good. Hence the feature request.

I don't think it's a special case either, I use it all the time. Maybe that just makes *me* the special case though :)
User avatar
Kaeru Gaman
Addict
Addict
Posts: 4826
Joined: Sun Mar 19, 2006 1:57 pm
Location: Germany

Post by Kaeru Gaman »

I would do it that way:

Code: Select all

Procedure DrawTiledImage(ImageNr, X, Y, Width, Height)
  Protected n.l, t.l
  Protected w.l = ImageWidth(ImageNr)
  Protected h.l = ImageHeight(ImageNr)
  For t=1 To Height
    For n=1 To Width
      DrawImage( ImageID(ImageNr), X + n*w, Y + t*h )
    Next
  Next
EndProcedure
oh... and have a nice day.
Seymour Clufley
Addict
Addict
Posts: 1264
Joined: Wed Feb 28, 2007 9:13 am
Location: London

Post by Seymour Clufley »

I haven't tested this, but:

Code: Select all

Procedure DrawTiledImage(img, bx, by, dWidth, dHeight) 
  If Not dWidth : dWidth=OutputWidth() : EndIf
  If Not dHeight : dHeight=OutputHeight() : EndIF
  tw = ImageWidth(img) 
  th = ImageHeight(img) 
  dy = by
  Repeat
      dx=bx
      Repeat
          DrawImage(ImageID(img),dx,dy)
          dx+tw
      Until dx+tw>dWidth
      dy+th
Until dy+th>dHeight
EndProcedure
JACK WEBB: "Coding in C is like sculpting a statue using only sandpaper. You can do it, but the result wouldn't be any better. So why bother? Just use the right tools and get the job done."
eesau
Enthusiast
Enthusiast
Posts: 589
Joined: Fri Apr 27, 2007 12:38 pm
Location: Finland

Post by eesau »

Thanks, but those are not right. The width and height should be pixels, not times the image should be tiled.
Seymour Clufley
Addict
Addict
Posts: 1264
Joined: Wed Feb 28, 2007 9:13 am
Location: London

Post by Seymour Clufley »

In my code, the width and height are pixels.
JACK WEBB: "Coding in C is like sculpting a statue using only sandpaper. You can do it, but the result wouldn't be any better. So why bother? Just use the right tools and get the job done."
eesau
Enthusiast
Enthusiast
Posts: 589
Joined: Fri Apr 27, 2007 12:38 pm
Location: Finland

Post by eesau »

Seymour Clufley wrote:In my code, the width and height are pixels.
They are, but say if the width is 10 pixels wider than the width of the image to be drawn, it doesn't draw those 10 pixels. The X, Y, Width and Height parameters define the area that should be fully filled with the tiled image.
User avatar
Kaeru Gaman
Addict
Addict
Posts: 4826
Joined: Sun Mar 19, 2006 1:57 pm
Location: Germany

Post by Kaeru Gaman »

I have a code ready, but not yet tested... do you want to see it anyways?
oh... and have a nice day.
eesau
Enthusiast
Enthusiast
Posts: 589
Joined: Fri Apr 27, 2007 12:38 pm
Location: Finland

Post by eesau »

Sure, why not :)
User avatar
Kaeru Gaman
Addict
Addict
Posts: 4826
Joined: Sun Mar 19, 2006 1:57 pm
Location: Germany

Post by Kaeru Gaman »

my idea was to create a tiled big image in advance to spare this time while drawing the tiled area.

Code: Select all

;******************************************************
;***
;*** CreateTiledImage( ImageNr.i, TileNr.i, Width.l, Height.l, Depth.l, LeftX.l = 0, TopY.l = 0, TileWidth.l = 0, TileHeight.l = 0 )
;***
;******************************************************
;***
;*** ImageNr.i      - Number of the Image to create (can be #PB_Any)
;*** TileNr.i       - Number of the Image giving the Tile (must be valid)
;*** Width.l        - Width of the Image to create
;*** Height.l       - Height of the Image to create
;*** Depth.l        - Depth of the Image to create (optional)
;*** LeftX.l        - Number of Pixels to X-shift into the first Row of Tiles (optional)
;*** TopY.l         - Number of Pixels to Y-shift into the first Line of Tiles (optional)
;*** TileWidth.l    - Resize Tile to this Width (optional)
;*** TileHeight.l   - Resize Tile to this Height (optional)
;***
;******************************************************
;***
;*** Creates a new Image wich is Tiled with the given Image.
;***
;*** ReturnValue    - analogue to CreateImage()
;***
;******************************************************
;***
;*** by Kaeru Gaman, 2009-08-27
;*** PureBasic Ver. 4.40
;***
;******************************************************

Procedure CreateTiledImage( ImageNr.i, TileNr.i, Width.l, Height.l, Depth.l = 32, LeftX.l = 0, TopY.l = 0, TileWidth.l = 0, TileHeight.l = 0 )
  Protected RetVal.i
  Protected.l n,t, Rows, Lines
  RetVal =  CreateImage( ImageNr, Width, Height, Depth )
  If RetVal And TileNr
    If ImageNr = #PB_Any
      ImageNr = RetVal
    EndIf
    If TileWidth = 0
      TileWidth = ImageWidth( TileNr )
    EndIf
    If TileHeight = 0
      TileHeight = ImageHeight( TileNr )
    EndIf
    Rows = Int( ( Width + LeftX - 1 ) / TileWidth + 1 )
    Lines = Int( ( Height + TopY - 1 ) / TileHeight + 1 )
    StartDrawing( ImageOutput( ImageNr ) )
      For t=1 To Lines
        For n=1 To Rows
          DrawImage( ImageID( TileNr ), n * TileWidth - LeftX, t * TileHeight - TopY, TileWidth, TileHeight )
        Next
      Next
    StopDrawing()
  EndIf
  ProcedureReturn RetVal
EndProcedure
please test it intensively and give feedback. ;)
oh... and have a nice day.
eesau
Enthusiast
Enthusiast
Posts: 589
Joined: Fri Apr 27, 2007 12:38 pm
Location: Finland

Post by eesau »

For reference, here's my current implementation. Probably not very efficient, because of the GrabImages. Can be used inside a StartDrawing()/StopDrawing() -block, which is important.

Code: Select all

Procedure ImageDrawTiled ( Image , X , Y , Width , Height )

	Protected TimesX = Width / ImageWidth ( Image )
	Protected TimesY = Height / ImageHeight ( Image )
	Protected LeftX = Width % ImageWidth ( Image )
	Protected LeftY = Height % ImageHeight ( Image )

	Protected CounterX
	Protected CounterY
	Protected Temporary
	
	For CounterX = 0 To TimesX - 1
	
		For CounterY = 0 To TimesY - 1
		
			DrawImage ( ImageID ( Image ) , X + CounterX * ImageWidth ( Image ) , Y + CounterY * ImageHeight ( Image ) )
					
		Next
		
	Next
	
	If LeftX
	
		Temporary = GrabImage ( Image , #PB_Any , 0 , 0 , LeftX , ImageHeight ( Image ) )
		
		If Temporary
						
			For CounterY = 0 To TimesY - 1
			
				DrawImage ( ImageID ( Temporary ) , X + CounterX * ImageWidth ( Image ) , Y + CounterY * ImageHeight ( Image ) )
			
			Next		
		
			FreeImage ( Temporary )
		
		EndIf
		
	EndIf
	
	If LeftY
	
		Temporary = GrabImage ( Image , #PB_Any , 0 , 0 , ImageWidth ( Image ) , LeftY )
		
		If Temporary
						
			For CounterX = 0 To TimesX - 1
			
				DrawImage ( ImageID ( Temporary ) , X + CounterX * ImageWidth ( Image ) , Y + CounterY * ImageHeight ( Image ) )
			
			Next		
		
			FreeImage ( Temporary )
		
		EndIf	
	
	EndIf
	
	If LeftX And LeftY
	
		Temporary = GrabImage ( Image , #PB_Any , 0 , 0 , LeftX , LeftY )
	
		If Temporary

			DrawImage ( ImageID ( Temporary ) , X + CounterX * ImageWidth ( Image ) , Y + CounterY * ImageHeight ( Image ) )
		
			FreeImage ( Temporary )
		
		EndIf
			
	EndIf
		
EndProcedure
User avatar
Kaeru Gaman
Addict
Addict
Posts: 4826
Joined: Sun Mar 19, 2006 1:57 pm
Location: Germany

Post by Kaeru Gaman »

I chose the 'Create'-approach, because it simplyfies the clipping extremely.
plus, if you need the same tilefield more than once, you only need to create it once.
disadvantage is that it has it's own start/stop-drawing.
oh... and have a nice day.
Post Reply