Teek::Photo Class
CPU-side RGBA pixel buffer backed by Tk’s “photo image” format.
Despite the name, this is really a raw pixel manipulation surface. Tk has two built-in image types: “bitmap” (two colors ` transparency) and “photo” (full-color, 32-bit RGBA). The naming reflects Tk’s image type system, not the contents — a “photo” is just Tk’s term for a full-color pixel buffer.
Think of it as a software framebuffer: you pack RGBA bytes, write them in bulk, read them back, zoom/subsample, and blit to a canvas or label for display. All work is CPU-driven — there is no GPU acceleration.
The C methods (#put_block, #get_image, #get_pixel, etc.) call
Tk_PhotoPutBlock / Tk_PhotoGetImage directly, bypassing Tcl string
parsing for much better performance than the Tcl-level `$photo put+
command. Designed for games, visualizations, and real-time drawing.
Inherits: Object
Class Methods ↑
finalizer_for(name, app)
Builds the proc registered as this instance’s finalizer. Must not
close over self (the Photo instance) or any of its ivars
directly - a finalizer that references its own object keeps that
object permanently reachable, so it would never actually be
collected. name/app are plain local captures instead.
Finalizers can run on any thread, so the delete goes through
Interp#queue_for_main (fire-and-forget) rather than #tcl_eval,
which would block on a cross-thread queue wait if called from a
background thread - risky from inside a GC finalizer. The catch
means a concurrent explicit #delete (or an interpreter that’s
already torn down by the time this runs) is a silent no-op, not
an error with nowhere to go.
@api private
next_name
@api private
Instance Methods ↑
command(*args, **kwargs)
Invoke a photo subcommand not covered by a dedicated method above
(e.g. copy, read, write). Prepends the image name as the Tcl
command, exactly like Widget#command does for widgets.
Parameters
args— positional argumentskwargs— keyword arguments mapped to-key valuepairs
Returns String — the Tcl result
Example
# Subsample a copy of another photo
thumb = Teek::Photo.new(app)
thumb.command(:copy, source_photo, subsample: 4)
delete
Delete this photo image and free its resources.
Cancels the GC finalizer registered by #initialize - otherwise a
later collection could delete an unrelated image if this name gets
reused (e.g. an explicit name: passed to a later Photo).
Returns void
expand(width, height)
Expand image to at least the given dimensions. Will not shrink.
Parameters
widthInteger— minimum widthheightInteger— minimum height
Returns self
@note Has no effect on photos created with explicit width: / height:
options. Only works on auto-sized photos (those whose size was set by
writing pixel data). This is a Tk limitation.
get_image(x: nil, y: nil, width: nil, height: nil, unpack: false)
Read pixel data from the image.
Parameters
xInteger— source X offsetyInteger— source Y offsetwidthInteger, nil— region width (nil for full image)heightInteger, nil— region height (nil for full image)unpackBoolean— if true, return flat array of integers instead of binary string
Returns Hash — <code>data: String, width: Integer, height: Integer</code> or
<code>pixels: Array<Integer>, width: Integer, height: Integer</code> if unpack is true
get_pixel(x, y)
Read a single pixel.
Parameters
xInteger— X coordinateyInteger— Y coordinate
Returns Array<Integer> — [r, g, b, a] values (0-255)
initialize(app, name: nil, width: nil, height: nil, file: nil, data: nil, format: nil, palette: nil, gamma: nil)
Create a new photo image.
The underlying Tk image is automatically deleted once this Photo
object is garbage collected and nothing else references it - keep
it around (an ivar, a collection, etc.) for as long as you need the
image, the same contract as File or Socket. If only the image
name is kept (e.g. passed into a widget’s image:) and this
wrapper is dropped, the image can be reclaimed out from under that
reference; Tk shows a broken image rather than crashing, but the
image won’t come back - call #delete explicitly rather than
relying on GC timing if you need deterministic cleanup.
Parameters
appTeek::App— the application instancenameString, nil— Tcl image name (auto-generated if nil)widthInteger, nil— image width in pixelsheightInteger, nil— image height in pixelsfileString, nil— path to an image file to loaddataString, nil— base64-encoded image dataformatString, nil— image format (e.g. "png", "gif")paletteString, nil— palette specificationgammaFloat, nil— gamma correction value
Returns Photo — a new instance of Photo
put_block(pixel_data, width, height, x: 0, y: 0, format: :rgba, composite: :set)
Write RGBA pixel data to the image.
Parameters
pixel_dataString— binary string, 4 bytes (RGBA) per pixelwidthInteger— width of the pixel blockheightInteger— height of the pixel blockxInteger— destination X offsetyInteger— destination Y offsetformat:rgba, :argb— pixel formatcomposite:set, :overlay— compositing rule
Returns self
put_zoomed_block(pixel_data, width, height, x: 0, y: 0, zoom_x: 1, zoom_y: 1, subsample_x: 1, subsample_y: 1, format: :rgba, composite: :set)
Write RGBA pixel data with zoom and subsample.
Zoom replicates each pixel (zoom=3 makes each source pixel 3x3). Subsample skips source pixels (subsample=2 takes every other pixel).
Parameters
pixel_dataString— binary string, 4 bytes (RGBA) per pixelwidthInteger— source width in pixelsheightInteger— source height in pixelsxInteger— destination X offsetyInteger— destination Y offsetzoom_xInteger— horizontal zoom factorzoom_yInteger— vertical zoom factorsubsample_xInteger— horizontal subsample factorsubsample_yInteger— vertical subsample factorformat:rgba, :argb— pixel formatcomposite:set, :overlay— compositing rule
Returns self
set_size(width, height)
Set image dimensions. May crop or add transparent pixels.
Parameters
widthInteger— new widthheightInteger— new height
Returns self
to_s
Returns String — the Tcl image name
Attributes ↑
app [R]
Returns the value of attribute app.
name [R]
Returns the value of attribute name.