Put (Graphics)
Copies an image on to another image or screen
Syntax
`
Put [target, ] [ [STEP](x, y), source [, (x1, y1)-[STEP](x2, y2) ] [, method [, ( alphaval|value|blender [, param]) ] ]
`
Parameters
`target`
is the address of the buffer where the image is to be drawn. If it's omitted, the image gets blitted to screen. See below.
`[STEP](x, y)`
specify offsets from the upper-left corner of the destination buffer, or screen, that the image gets drawn to. `STEP` indicates that `(x, y)` offsets are relative to the current graphics cursor position.
`source`
is the address of the buffer of the image to be drawn. See below.
`(x1, y1)-[STEP](x2, y2)`
specify a rectangular area in the source buffer to draw. If omitted, the entire buffer is drawn. `STEP` indicates that `x2` and `y2` are relative to `x1` and `y1`, respectively.
`method`
specifies the method used to draw the image to the destination buffer, and can be any one of the following (the default method is `XOR`):
Background-independent methods
`PSet` : Source pixel values are copied without modification.
`PRESET` : Source pixel values are 1's-complement negated before being copied.
`Trans` : Source pixel values are copied without modification. Does not draw source pixels of mask color. See below.
Background-dependent methods
`And (Graphics Put)` : Destination pixels are bitwise `And`ed with source pixels. See below.
`Or` : Destination pixels are bitwise `Or`ed with source pixels. See below.
`Xor` : Destination pixels are bitwise `Xor`ed with source pixels. See below.
`Alpha` : Source is blended with a transparency factor specified either in the `value` parameter, or in the image's individual pixels. See below.
`Add`: Source is multiplied by a value and added with saturation to the destination. See below.
`Custom` : Uses a user-defined function to perform blending the source with the destination. See below.
`value`
is a `0..255` value specifying the transparency value for an `ADD` or `ALPHA` method blit.
`blender`
specifies the address of a user-defined function to be called in a `CUSTOM` method blit. See below.
`param`
specifies a parameter to pass to the custom blender.
Description
The `Put` statement can be used to draw an image onto another image or screen. The `x` and `y` coordinates are affected by the last call to the `View` and `Window` statements, and plotted image respects the current clipping region set by last call to the `View` statement. The source image can overflow the destination buffer or screen (then the copied image is clipped accordingly).
Valid Image Buffers
The `source` and `target` image buffers must be valid image buffers. Valid image buffers are created using the `Get` or `ImageCreate` statements. Valid image buffers can be specified in a `Put` statement using an array name with optional index (but never with empty parentheses), or a pointer with optional index.
Drawing methods
Depending on the method used, the existing pixel values in the destination buffer are used to calculate the pixel values that are actually drawn. The `PSET`, `PRESET` and `TRANS` methods do not use the destination buffer for calculating final pixel values, while the `AND`, `OR`, `XOR`, `ALPHA` and `ADD` methods do. Images that are drawn with these latter methods will look differently depending on the content of the destination buffer.
Different pixel formats
The pixel format of an image buffer must be compatible with the current graphics mode color depth; that is, if you acquire an image using `Get` and you later change screen mode via the `Screen (Graphics)` statement, the image data may not be valid in the new graphics mode, and you may not be able to draw it on the screen. You should note however that you will always be able to draw image buffers onto other image buffers via `Put` as long as these buffers were created with the same depth.
The `AND`, `OR` and `XOR` methods produce different results depending on the current color depth, as pixels are stored in different formats; see Internal pixel formats for details.
Mask Color
The `TRANS`, `ALPHA` and `ADD` methods do not draw pixels in the source image that use the mask color. The mask color depends on target (being it an image buffer or the screen) depth: in depths up to 8 bpp (paletted modes) it is equal to color index `0`, while in hi/truecolor depths (16 and 32 bpp) it is equal to magenta, which is `RGB(255, 0, 255)`. Note that in 32 bpp modes the alpha value of a color does not affect the identification of the transparent color; only the lower 24 bits are used to identify it. See Internal pixel formats for details.
Alpha drawing
The `ALPHA` method can be used in two modes. If the `value` parameter is specified, this is used to specify the level of transparency for the whole image to be drawn; a value of 0 will draw a completely transparent image, whereas a value of 255 will draw a completely solid one. This mode works only when drawing onto hi/truecolor targets (16 and 32 bpp).
If the `value` parameter is omitted, the `ALPHA` method will take the alpha level value on a per-pixel basis, allowing to draw images with an alpha channel (certain parts of the image can be made more or less transparent than others). This mode works only with 32 bpp image buffers, as this is the only color depth that allows for an embedded alpha value in each pixel.
Dealing with the alpha channel
Normally `Put` only allows to draw image buffers onto targets with the same depth, but there is an exception. When drawing an 8 bpp image buffer onto a 32 bpp target and the `ALPHA` method is used, the 8 bpp source image is drawn into the alpha channel of the 32 bpp target. This allows to easily set the whole alpha channel of an image without having to deal with low level access of its pixel data.
Custom Blend Function
The `CUSTOM` method uses a user-defined function to calculate the final pixel values to be drawn to the destination buffer. This function will be called once for every pixel of the source image, and will receive the source and destination pixel values, and a data pointer passed by the `Put` function. The pixel value returned will be the value used to draw to the destination buffer. The function has the form:
`Declare Function identifier ( ByVal source_pixel As ULong, ByVal destination_pixel As ULong, ByVal parameter As Any Ptr ) As ULong`
`identifier` is the name of the function. Can be anything.
`source_pixel` is the current pixel value of the source image.
`destination_pixel` is the current pixel value of the destination image.
`parameter` is the parameter that is passed by the `Put` command. It should be a data `Pointer`. If omitted, its value will be zero.
Example
The following program gives a simple example of how to `Put` an image to the screen, including setting up an image buffer, and freeing its memory after.
`
'' set up the screen and fill the background with a color
ScreenRes 320, 200, 32
Paint (0, 0), RGB(64, 128, 255)
'' set up an image and draw something in it
Dim img As Any Ptr = ImageCreate( 32, 32, RGB(255, 0, 255) )
Circle img, (16, 16), 15, RGB(255, 255, 0), , , 1, f
Circle img, (10, 10), 3, RGB( 0, 0, 0), , , 2, f
Circle img, (23, 10), 3, RGB( 0, 0, 0), , , 2, f
Circle img, (16, 18), 10, RGB( 0, 0, 0), 3.14, 6.28
'' PUT the image in the center of the screen
Put (160 - 16, 100 - 16), img, Trans
'' free the image memory
ImageDestroy img
'' wait for a keypress
Sleep
`
The following example shows how to allocate memory for an image, draw that image using various methods, including a custom blender, and free the memory for the image:
`
Declare Function checkered_blend( ByVal src As ULong, ByVal dest As ULong, ByVal param As Any Ptr ) As ULong
Screen 14, 32 '' set 320*240*32 gfx mode
Dim As Any Ptr sprite
Dim As Integer counter = 0
sprite = ImageCreate( 32, 32 ) '' allocate memory for 32x32 sprite
Line sprite, ( 0, 0 )-( 31, 31 ), RGBA(255, 0, 0, 64), bf '' draw a sprite ...
Line sprite, ( 4, 4 )-( 27, 27 ), RGBA(255, 0, 0, 192), bf
Line sprite, ( 0, 0 )-( 31, 31 ), RGB(0, 255, 0), b
Line sprite, ( 8, 8 )-( 23, 23 ), RGBA(255, 0, 255, 64), bf
Line sprite, ( 1, 1 )-( 30, 30 ), RGBA(0, 0, 255, 192)
Line sprite, ( 30, 1 )-( 1, 30 ), RGBA(0, 0, 255, 192)
Cls
Dim As Integer i : For i = 0 To 63 '' draw the background
Line( i,0 )-( i,240 ), RGB( i * 4, i * 4, i * 4 )
Next i
'' demonstrate all drawing methods ...
Put( 8,14 ), sprite, PSet
Put Step( 16,20 ), sprite, PReset
Put Step( -16,20 ), sprite, And
Put Step( 16,20 ), sprite, Or
Put Step( -16,20 ), sprite, Xor
Put Step( 16,20 ), sprite, Trans
Put Step( -16,20 ), sprite, Alpha, 96
Put Step( 16,20 ), sprite, Alpha
Put Step( -16,20 ), sprite, Add, 192
Put Step( 16,20 ), sprite, Custom, @checkered_blend, @counter
'' print a description near each demo
Draw String (100, 26), "<- pset"
Draw String Step (0, 20), "<- preset"
Draw String Step (0, 20), "<- and"
Draw String Step (0, 20), "<- or"
Draw String Step (0, 20), "<- xor"
Draw String Step (0, 20), "<- trans"
Draw String Step (0, 20), "<- alpha (uniform)"
Draw String Step (0, 20), "<- alpha (per pixel)"
Draw String Step (0, 20), "<- add"
Draw String Step (0, 20), "<- custom"
ImageDestroy( sprite ) '' free allocated memory for sprite
Sleep : End 0
'' custom blender function: chequered put
Function checkered_blend( ByVal src As ULong, ByVal dest As ULong, ByVal param As Any Ptr ) As ULong
Dim As Integer Ptr counter
Dim As ULong pixel
counter = Cast(Integer Ptr, param)
pixel = IIf(((*counter And 4) Shr 2) Xor ((*counter And 128) Shr 7), src, dest)
*counter += 1
Return pixel
End Function
`
Differences from QB

- `target` is new to FreeBASIC
- The `TRANS`, `ALPHA`, `ADD` and `CUSTOM` methods are new to FreeBASIC
- FB uses a different image format internally, which is unsupported by QB
- QB throws a run-time error instead of clipping out-of-bounds images
- In QB, only arrays can be specified as source images

See also

- `Custom (Graphics Put)`
- `Put (File I/O)`
- `Get (Graphics)`
- `ImageCreate`
- `Alpha`
- Internal pixel formats