_PUTIMAGE

From QB64 Phoenix Edition Wiki
Revision as of 20:35, 19 April 2026 by RhoSigma (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

_PUTIMAGE puts an area of a source image to an area of a destination image in one operation, like GET and PUT.


Syntax

_PUTIMAGE [STEP] [(dx1, dy1)-[STEP][(dx2, dy2)]][, sourceHandle&][, destHandle&][, ][STEP][(sx1, sy1)[-STEP][(sx2, sy2)]][, _SMOOTH]

Sample usage

_PUTIMAGE 'full source image to fit full destination area after _SOURCE and _DEST are set
_PUTIMAGE , sourceHandle&, destHandle& 'size full source to fit full destination area
_PUTIMAGE (dx1, dy1), sourceHandle&, destHandle& 'full source to top-left corner destination position
_PUTIMAGE (dx1, dy1)-(dx2, dy2), sourceHandle&, destHandle& 'size full source to destination coordinate area
_PUTIMAGE (dx1, dy1), sourceHandle&, destHandle&, (sx1, sy1)-(sx2, sy2) 'portion of source to the top-left corner of the destination page
_PUTIMAGE , sourceHandle&, destHandle&, (sx1, sy1)-(sx2, sy2) 'portion of source to full destination area
_PUTIMAGE (dx1, dy1)-(dx2, dy2), sourceHandle&, destHandle&,(sx1, sy1) 'right side of source from top-left corner to destination


Note: The top-left corner position designates the leftmost and topmost portion of the image to use.


Parameters

  • Relative coordinates to a previous graphical object can be designated using STEP as opposed to literal surface coordinates (version 1.000 and up).
  • Coordinates dx and dy map the box area of the destination area to use. When omitted the entire desination area is used. If only one coordinate is used, the source is placed with its original dimensions. Coordinates can be set to flip or resize the image.
    • dx1 = the column coordinate at which the insertion of the source will begin (leftmost); when larger than dx2, reverses image.
    • dy1 = the row coordinate at which the insertion of the source will begin (topmost); when larger than dy2, inverts image.
    • dx2 = the column coordinate at which the insertion of the source will end (rightmost); further apart, widens image.
    • dy2 = the row coordinate at which the insertion of the source will end (bottommost); closer together, shrinks image
  • sourceHandle& = the LONG handle of the source image created with _NEWIMAGE, _LOADIMAGE or _COPYIMAGE.
  • destHandle& = the LONG handle of the destination image may be created with _NEWIMAGE, SCREEN or destination 0.
  • Coordinates sx and sy GET the box area of the source image to transfer to the destination image, page or screen:
    • sx1 = the column coordinate of the left-most pixel to include of the source. When omitted, the entire image is used
    • sy1 = the row coordinate of the upper-most pixel to include of the source. When omitted, the entire image is used
    • sx2 = the column coordinate of the right-most pixel to include of the source. Can be omitted to get rest of image.
    • sy2 = the row coordinate of the bottom-most pixel to include of the source. Can be omitted to get rest of image.
  • _SMOOTH applies linear filtering (version 1.000 and up).
Note: The PUT options PSET, PRESET, AND, OR and XOR are not available with _PUTIMAGE. QB64 can use transparency of colors to achieve the same results.


Description

  • _PUTIMAGE can be used without any handle parameters if the _SOURCE and/or _DEST are already defined.
  • If the area of the source is bigger or smaller than the area of the destination then the image is adjusted to fit that area.
  • Supports 32 bit alpha blending, color key transparency, true type fonts, stretching, mirroring/flipping, and a variety of graphics file formats including gif, png, bmp & jpg. 32 bit screen surface backgrounds (black) have zero _ALPHA and are transparent when placed over other surfaces. Use CLS or _DONTBLEND to make a new surface background _ALPHA 255 or opaque.
  • Text surface support:
    • Text source -> text destination is supported as a cell copy operation (character + color attribute).
    • Text source -> graphics destination is supported on 4bpp, 8bpp and 32bpp destinations.
    • Text source -> graphics performs copy/mirror/flip and clipping, but not scaling. If an explicit destination rectangle is passed, its size must match the text cell dimensions (cell width x font width, cell height x font height).
    • Graphics source -> text destination is invalid and raises Illegal function call.
    • Text source -> graphics destination below 4bpp is invalid and raises Illegal function call.
    • Text surface color-key transparency is honored using the 16-bit text cell value (character + attribute). Use _CLEARCOLOR to set and _CLEARCOLOR_(function) to get the color-key.
    • For text source -> graphics, glyph rendering uses the text surface font. Built-in text fonts use the built-in bitmap glyphs; loaded monospace fonts (via _LOADFONT) are rendered as glyph bitmaps.
  • All graphical surfaces, including screen pages, can be acted upon in the same manner, and are referred to as "images".
  • Hardware images (created using mode 33 via _LOADIMAGE or _COPYIMAGE) can be used as the source or destination.
  • To place a hardware image on the _HARDWARE1 surface (according to the _DISPLAYORDER) simply specify 1 as destHandle&.
  • Handles are used to identify graphical surfaces. Positive values are used to refer to screen pages. -1 (negative one) indicates an invalid surface. It is recommended to store image handles in LONG variables. Passing an invalid handle generates an "Invalid handle" error.
  • When handles are not passed (or cannot be passed) to subs/functions then the default destination image or source image is referenced. These are set to the active page when the SCREEN statement is called, but can be changed to any image. So it is possible to read from one image using POINT and write to a different one with PSET.
  • PRINTed text cannot be transferred and positioned accurately. Use _PRINTSTRING for graphical text or font placement.
  • Images are not deallocated when the SUB or FUNCTION they are created in ends. Free them with _FREEIMAGE.
  • It is important to free discarded or unused images with _FREEIMAGE to prevent CPU memory overflow errors.


Availability

  • Text (SCREEN 0) surface support was added in QB64-PE v4.5.0.


Examples

Example 1:

 SCREEN 13
 a& = _NEWIMAGE(640, 200, 13) ' creates a 640 * 200 image with the LONG handle a&
 _DEST a& ' makes image a& the default drawing output.
 LINE (10, 10)-(100, 100), 12, BF ' draws a filled box (BF) into destination
 _PUTIMAGE (0, 0)-(320, 200), a&, 0, (0, 0)-(320, 200)
Explanation:
1) A graphics mode is set by using SCREEN 13 which can use up to 256 colors.
2) A new image is created that is 640 X 200 and uses the palette compatible with SCREEN 13 (256 colors).
3) _DEST a& makes the image with handle 'a&' the default image to draw on instead of the screen (which is _DEST 0).
4) Next a filled box (BF) is drawn from 10, 10 to 100, 100 with red color (12) to the destination image (set by _DEST a&)
5) Now we put the image from 0, 0 to 320, 200 from the image with the handle 'a&' to the screen (always handle 0) and puts this image into the coordinates 0, 0 to 320, 200. If we want to stretch the image we can alter these coordinates.
Note: All arguments are optional. If you want to simply put the whole image of the source to the whole image of the destination then you omit the area (x, y)-(x2, y2) on both sides, the last line of the example can be replaced by _PUTIMAGE , a&, 0 which indeed will stretch the image since image a& is bigger than the screen (the screen is 320 * 200 and a& is 640 * 200)


Example 2: You don't need to do anything special to use a .PNG image with alpha/transparency. Here's a simple example:

SCREEN _NEWIMAGE(640, 480, 32)
CLS , _RGB(0, 255, 0)
i = _LOADIMAGE("QB64.PNG") 'any 32 bit image (ie. with alpha channel)
_PUTIMAGE (0, 0), i ' places image at upper left corner of window w/o stretching it

Explanation: When QB64 loads a 256 color .PNG file containing a transparent color, that color will be treated as transparent when _PUTIMAGE is used to put it onto another image. So actually, you can use a 256-color .PNG file containing transparency information in a 256 color screen mode in QB64.


Example 3: Flipping and enlarging an image with _PUTIMAGE by swapping or increasing the desination coordinates.

DEFLNG A-Z
dest_handle = _NEWIMAGE(640, 480, 32)
SCREEN dest_handle  '32 bit Screen 12 dimensions
source_handle = _LOADIMAGE("QB64.PNG", 32) 'any 32 bit image (ie. with alpha channel)
dx1 = 0: dy1 = 0
dx2 = _WIDTH(source_handle) - 1: dy2 = _HEIGHT(source_handle) - 1 'image dimensions - 1
LOCATE 29, 33: PRINT "Press any Key!";
'normal image coordinate values based on the dimensions of the image:
_PUTIMAGE (dx1, dy1)-(dx2, dy2), source_handle, dest_handle
LOCATE 20, 34: PRINT "Normal layout"
LOCATE 24, 10: PRINT "_PUTIMAGE (dx1, dy1)-(dx2, dy2), source_handle, dest_handle"
K$ = INPUT$(1)
'to flip the image on the x axis, swap the dx coordinate values:
_PUTIMAGE (dx2, dy1)-(dx1, dy2), source_handle, dest_handle
LOCATE 20, 34: PRINT "Flip by X axis"
LOCATE 24, 10: PRINT "_PUTIMAGE (dx2, dy1)-(dx1, dy2), source_handle, dest_handle"
K$ = INPUT$(1)
'to flip image on y axis, swap the dy coordinate values:
_PUTIMAGE (dx1, dy2)-(dx2, dy1), source_handle, dest_handle
LOCATE 20, 34: PRINT "Flip by Y axis"
LOCATE 24, 10: PRINT "_PUTIMAGE (dx1, dy2)-(dx2, dy1), source_handle, dest_handle "
K$ = INPUT$(1)
'to flip both, swap both the dx and dy coordinate values:
_PUTIMAGE (dx2, dy2)-(dx1, dy1), source_handle, dest_handle
LOCATE 20, 34: PRINT "Flip on both axis"
LOCATE 24, 10: PRINT "_PUTIMAGE (dx2, dy2)-(dx1, dy1), source_handle, dest_handle"
K$ = INPUT$(1)
'to enlarge, double the second set of values plus any offset of the first coordinates:
_PUTIMAGE (dx1, dy1)-((2 * dx2) + dx1, (2 * dy2) + dy1), source_handle, dest_handle
LOCATE 20, 34: PRINT "Double image size"
LOCATE 24, 2:
PRINT "_PUTIMAGE (dx1, dy1)-((2 * dx2) + dx1, (2 * dy2) + dy1), s_handle, d_handle
END
Adapted from code by Darth Who


Example 4: Using _PUTIMAGE to scroll a larger image created on a separate _NEWIMAGE screen page with QB64.

RANDOMIZE TIMER
ws& = _NEWIMAGE(2560, 1440, 32) 'large image page
s& = _NEWIMAGE(1280, 720, 32)' program screen

_DEST ws& 'create large image of random filled circles
FOR i = 1 TO 50
    x = RND(1) * 2560
    y = RND(1) * 1440
    clr& = _RGB32(RND(1) * 255, RND(1) * 255, RND(1) * 255)
    CIRCLE (x, y), RND(1) * 300, clr&
    PAINT (x, y), clr&
NEXT
PRINT "This is a demo of some screen scrolling.   Use the number pad keys to scroll.  4 goes left, 6 goes right.  8 up, 2 down. ESC key will close this program."
x = 0: y = 0
SCREEN s&

DO
    CLS
    _PUTIMAGE (0, 0), ws&, 0, (x, y)-(x + 1279, y + 719)
    a$ = INKEY$
    SELECT CASE a$
        CASE "4": x = x - 10: IF x < 0 THEN x = 0
        CASE "6": x = x + 10: IF x > 1280 THEN x = 1280
        CASE "8": y = y - 10: IF y < 0 THEN y = 0
        CASE "2": y = y + 10: IF y > 720 THEN y = 720
        CASE CHR$(32): SYSTEM
    END SELECT
    _DISPLAY
LOOP
Code example by SMcNeill


Example 5: _PUTIMAGE can be used with no parameters at all if the _SOURCE and _DEST are already set.

SCREEN 13
h& = _NEWIMAGE(640, 480, 256)
_DEST h&
_PRINTSTRING (10, 10), "This _PUTIMAGE used no parameters!"
_SOURCE h&
_DEST 0
_PUTIMAGE
END

Example 6: Text surface to graphics destination (floating text panel)

_DEFINE A-Z AS LONG
OPTION _EXPLICIT

CONST SCREEN_W = 1024
CONST SCREEN_H = 600
CONST VIEW_OFFSET = 32
CONST PANEL_COLS = 32
CONST PANEL_ROWS = 6

DIM screenHandle AS LONG: screenHandle = _NEWIMAGE(SCREEN_W, SCREEN_H, 32)
SCREEN screenHandle
$RESIZE:SMOOTH
_ALLOWFULLSCREEN _SQUAREPIXELS , _SMOOTH
_TITLE "Draggable Live SCREEN 0 Clock Panel Demo"

DIM bg AS LONG: bg = _NEWIMAGE(SCREEN_W, SCREEN_H, 32)
DIM panel AS LONG: panel = _NEWIMAGE(PANEL_COLS, PANEL_ROWS, 0)

DIM AS LONG cellW, cellH

DIM fontHandle AS LONG: fontHandle = _LOADFONT("liberation/LiberationMono-Regular.ttf", 16, "monospace")
IF fontHandle < 1 THEN
    fontHandle = _LOADFONT("Courier New.ttf", 16, "monospace")
END IF
IF fontHandle < 1 THEN
    fontHandle = _LOADFONT("lucon.ttf", 16, "monospace")
END IF
IF fontHandle > 0 THEN
    _FONT fontHandle, panel
    cellW = _FONTWIDTH(fontHandle)
    cellH = _FONTHEIGHT(fontHandle)
ELSE
    _FONT 16, panel
    cellW = 8
    cellH = 16
END IF

DIM panelWpx AS LONG: panelWpx = PANEL_COLS * cellW
DIM panelHpx AS LONG: panelHpx = PANEL_ROWS * cellH
DIM panelX AS LONG: panelX = 40
DIM panelY AS LONG: panelY = 40

_DEST bg

CLS , _RGB32(16, 22, 30)

DIM y AS LONG
FOR y = 0 TO _HEIGHT(bg) - 1
    LINE (0, y)-(_WIDTH(bg) - 1, y), _RGB32(20 + y \ 8, 30 + y \ 6, 45 + y \ 5)
NEXT

DIM x AS LONG
FOR x = -128 TO _WIDTH(bg) STEP 64
    LINE (x, 0)-(x + 200, _HEIGHT(bg) - 1), _RGBA32(255, 255, 255, 10)
NEXT

FOR y = 40 TO _HEIGHT(bg) - 1 STEP 80
    CIRCLE (_SHR(_WIDTH(bg), 1), y), 120, _RGBA32(255, 220, 120, 20)
NEXT

_DEST 0

VIEW SCREEN(VIEW_OFFSET, VIEW_OFFSET)-(SCREEN_W - VIEW_OFFSET, SCREEN_H - VIEW_OFFSET), , _RGB32(255, 255, 0, 255)

DIM dragging AS _BYTE
DIM AS LONG dragOffX, dragOffY

DO
    DO WHILE _MOUSEINPUT
    LOOP

    DIM mx AS LONG: mx = _MOUSEX
    DIM my AS LONG: my = _MOUSEY

    IF _MOUSEBUTTON(1) THEN
        IF dragging THEN
            panelX = mx - dragOffX
            panelY = my - dragOffY
        ELSE
            IF mx >= panelX _ANDALSO mx < panelX + panelWpx _ANDALSO my >= panelY _ANDALSO my < panelY + panelHpx THEN
                dragging = _TRUE
                dragOffX = mx - panelX
                dragOffY = my - panelY
            END IF
        END IF
    ELSE
        dragging = _FALSE
    END IF

    _DEST panel
    CLS
    COLOR 15, 1
    LOCATE 1, 1: PRINT "======== Floating Panel ========";
    COLOR 14, 1
    LOCATE 3, 9: PRINT "Date: "; DATE$;
    LOCATE 4, 10: PRINT "Time: "; TIME$;
    COLOR 7, 1
    IF dragging THEN
        LOCATE 6, 13: PRINT "Dragging";
    ELSE
        LOCATE 6, 7: PRINT "Drag with left mouse";
    END IF
    _DEST 0

    _PUTIMAGE (0, 0), bg
    _PUTIMAGE (panelX, panelY), panel

    _DISPLAY
    _LIMIT 60
LOOP UNTIL _KEYHIT = _KEY_ESC

IF fontHandle > 0 THEN
    _FONT 16, panel
    _FREEFONT fontHandle
END IF

_FREEIMAGE panel
_FREEIMAGE bg

SYSTEM


More examples


See also



Navigation:
Main Page with Articles and Tutorials
Keyword Reference - Alphabetical
Keyword Reference - By usage
Report a broken link