rtk.Image
¶
Utility class to manage REAPER images.
Note that this isn't a widget and rtk.Image
objects can't be added to containers. For
that, use rtk.ImageBox
instead. This is just a utility class to manipulate
REAPER-backed images at a low level.
Images are automatically freed as part of Lua garbage collection, with the underlying REAPER buffer released for use by future rtk.Image objects.
These constants are used with the mode
arguments in the various drawing methods.
They can be bitwise-ORed together.
rtk.Image.DEFAULT¶ | Default blending mode which considers both source and destination alpha channels. Most of the time this is what you want. |
rtk.Image.ADDITIVE_BLEND¶ | Blends source and destination by summing their color values together. |
rtk.Image.SUBTRACTIVE_BLEND¶ | Blends source and destination by subtracting the source color from the destination color. |
rtk.Image.NO_SOURCE_ALPHA¶ | Ignores the alpha channel from the source image treating all pixels as fully opaque when blitting onto the destination. Unless you need alpha blending, you should use this mode for improved performance. |
rtk.Image.NO_FILTERING¶ | When scaling images, filtering provides pixel interpolation to improve the quality but comes at a cost. This disables filtering so the scaling algorithm is nearest neighbor. |
rtk.Image.FAST_BLIT¶ | A combination of |
icon() | static | Create a new image either from an |
make_placeholder_icon() | static | Returns an icon with a red question mark that can be used to indicate icon load failure without aborting the program |
Create a new image either from an rtk.ImagePack
image name that was
registered, or, if not found, search for a png file
located in any of the image paths added via rtk.add_image_search_path()
.
The style
argument dictates the requested icon luminance (namely, dark
or light
).
and if not specified defaults to the current theme's icon style. Icons registered via
an rtk.ImagePack
can be assigned a style, and likewise image paths added with
rtk.add_image_search_path()
can indicate the style of icons found within that path.
If no icon is found for the requested style
, then the other style will be searched
as a fallback method. In this case, the icon will be recolored to be black if style
is dark
, or white if style
is light. But note in this case colored icons will be
turned monochromatic.
If ultimately no suitable icon can be located, an error is logged and nil is
returned. The caller can choose to use make_placeholder_icon()
in a pinch.
Icons previously registered via rtk.ImagePack
can also be accessed by this function.
If the rtk.ImagePack
contains multiple size variants of the icon, you can qualify
the icon name by adding a :<size>
suffix. For example, error:huge
would return
the huge variant of the error
icon (assuming such a variant had been added to the
ImagePack). See rtk.ImagePack:get()
for more details.
local img = rtk.Image.icon('undo', 'light')
name | (string) | Filename of the icon. If the file extension is omitted (which is preferred but not required) then |
style | (string or nil) | Either |
(rtk.Image or nil) | newly loaded image, or nil if icon could not be found (in which case an error is logged to the console) |
Returns an icon with a red question mark that can be used to indicate icon load failure without aborting the program.
local img = rtk.Image.icon('undo', 'light')
if not img then
img = rtk.Image.make_placeholder_icon(24, 24, 'light')
end
w | (number or nil) | desired image width, nil implies 24 |
h | (number or nil) | desired image height, nil implies 24 |
style | (string or nil) |
|
(rtk.Image) | the new image |
x | number | read-only |
The x offset within the underlying REAPER image as set by |
y | number | read-only |
The y offset within the underlying REAPER image as set by |
w | number or nil | read-only |
The width in pixels of the image as set by |
h | number or nil | read-only |
The height in pixels of the image as set by |
density | number | read/write |
The pixel density factor of the image, which controls how the image is drawn relative to
|
path | string or nil | read-only |
The image path that was passed to |
rotation | number | read-only |
The current rotation of the image in degrees as passed to |
id | number or nil | read-only |
The numeric id that represents the image buffer within REAPER |
rtk.Image() | Constructor to create a new image resource |
create() | Assigns a new image buffer with the specified dimensions |
load() | Loads an image from disk |
pushdest() | Pushes this image's buffer onto the stack for off-screen drawing |
popdest() | Pops this image's buffer off the stack for off-screen drawing |
clone() | Clones the current image contents into a new rtk.Image object with a new image buffer |
resize() | Resizes the current image to new dimensions |
scale() | Returns a new image with the current image scaled to the given resolution |
clear() | Clears the image either to the given color or to fully transparent |
viewport() | Creates a new |
draw() | Draws the full image to the current drawing target |
blit() | Draws a region of the image onto a drawing target, or another image onto this image |
recolor() | Changes all pixels in the image to the given color while respecting the alpha channel |
filter() | Applies an effect to the image by multiplying or adding values to individual channels |
rect() | Draws a rectangle on the image in the given color |
blur() | Blurs a region of the image |
flip_vertical() | Flips the image vertically in place |
rotate() | Rotates the image |
refresh_scale() | Widgets using |
The x offset within the underlying REAPER image as set by viewport()
(default 0).
The y offset within the underlying REAPER image as set by viewport()
(default 0).
The width in pixels of the image as set by create()
or load()
(default nil). Will
be nil until one of those methods is called.
The height in pixels of the image as set by create()
or load()
(default nil). Will
be nil until one of those methods is called.
The pixel density factor of the image, which controls how the image is drawn relative to
rtk.scale
. Specifically, rtk.scale.value
is divided by density
when drawn,
so a pixel density of 1.0
(default) is scaled directly by rtk.scale.value
, while
a density of 2.0
is drawn at half rtk.scale.value
.
This can be used to define high-DPI or "retina" images. Note that w
and h
are not
adjusted according to density and will reflect the image's true/intrinsic size. It is
most useful when combined with rtk.MultiImage
, which can represent many DPI variants of
the same image.
The image path that was passed to load()
or nil if load()
wasn't called (default nil).
The current rotation of the image in degrees as passed to rotate()
.
The numeric id that represents the image buffer within REAPER. This value is auto-generated
and is unique to the image buffer, although multiple rtk.Image
objects can share the same
id if viewport()
is used.
Constructor to create a new image resource.
If the dimensions are specified, the image will be reserved from REAPER and
sized accordingly, where all pixels will default to transparent. Otherwise,
the object will be inert until either create()
, load()
, or resize()
are
explicitly called.
-- Creates a new image and immediately loads from file
local img = rtk.Image():load('image.jpg')
-- Creates a new blank 24x24 image
local img2 = rtk.Image(24, 24)
-- This is equivalent
img = rtk.Image():create(24, 24)
w | (number or nil) | if specified, creates a new image with the given width |
h | (number or nil) | if specified, creates a new image with the given height |
density | (number or nil) | the image's pixel |
(rtk.Image) | the new instance |
Assigns a new image buffer with the specified dimensions.
After this method returneds, a new id
will be assigned to the image. The alpha
channel of image will be fully transparent by default.
w | (number) | the width of the image buffer in pixels |
h | (number) | the height of the image buffer in pixels |
density | (number or nil) | the image's pixel |
(rtk.Image) | Returns self for method chaining. A new rtk.Image object is not created here, rather the existing object is updated to use a new buffer. |
Loads an image from disk.
After this method returns, a new id
will be assigned to the image if necessary, and
path
, w
, and h
will be updated to reflect the newly loaded image. If the load
fails, those attributes will be set to nil.
If no file is found at the given path, it is treated as a path that's relative to the
current script path or any non-icon image paths previously registered with
rtk.add_image_search_path()
, and they will be searched in that order. Unlike
icon()
, the file extension isn't assumed to be .png -- so it's required -- and
the image will not be recolored if it's found in the icon path that doesn't correspond
to the active theme.
local img = rtk.Image():load('/path/to/image.jpg')
if not img then
log.error('image failed to load')
end
path | (string) | the path to the image file to load |
density | (number or nil) | the image's pixel |
(rtk.Image or nil) | returns self if the load was successful for method chaining, otherwise if the load failed then nil is returned. |
Pushes this image's buffer onto the stack for off-screen drawing.
All subsequent drawing operations will be directed to the image's buffer. The
image must have a valid id
, which means create()
or load()
must first
have been called.
You must call popdest()
after you're done drawing. Failure to do so will result
in either a blank window or, more likely, a runtime error.
Pops this image's buffer off the stack for off-screen drawing. It must be the current drawing target or a runtime error will occur.
After this method returns, the previous image buffer from before pushdest()
was called will be restored as the current drawing target.
Clones the current image contents into a new rtk.Image object with a new image buffer.
(rtk.Image) | a new rtk.Image object with a copy of the current image contents. |
Resizes the current image to new dimensions.
If necessary, create()
is implicitly called.
w | (number) | the desired width in pixels of the image |
h | (number) | the desired height in pixels of the image |
clear | (boolean or nil) | if true or not provided then |
(rtk.Image) | returns self for method chaining |
Returns a new image with the current image scaled to the given resolution.
local scaled = rtk.Image.icon('32-delete'):scale(18)
w | (number or nil) | the target width in pixels, or nil to use the h parameter and preserve aspect |
h | (number or nil) | the target height in pixels, or nil to use the w parameter and preserve aspect |
mode | (modeconst or nil) | the drawing mode used to blit the scaled image (default when nil is |
density | (number or nil) | the pixel density of the new scaled image, or nil to retain the source image's |
Clears the image either to the given color or to fully transparent.
If a color is provided, the image will be filled with that color, otherwise the alpha channel is fully set to 0.
color | (colortype or nil) | the color to clear the image to, or nil to clear the image to transparency (where all pixels have an alpha of 0) |
(rtk.Image) | returns self for method chaining |
Creates a new rtk.Image
that is a viewport into the current image.
This allows you take a slice of the current image to create a smaller view within it, without needing to create a new image buffer and copy the image over.
A typical use case is having a single image that contains multiple icons (i.e. a sprite) and you want to use a specific region of the sprite, for example as a button icon.
The returned new rtk.Image
will have the same id
as the current image
because they share the same underlying image buffer.
x | (number or nil) | the x offset within the source image (nil is 0) |
y | (number or nil) | the y offset within the source image (nil is 0) |
w | (number or nil) | the width of new image (nil extends to the right edge of the source) |
h | (number or nil) | the height of the new image (nil extends to the bottom edge of the source) |
density | (number or nil) | the pixel density the new image (defaults to current image's |
(rtk.Widget) | a new image object that represents the slice within the source image |
Draws the full image to the current drawing target.
This is a convenience method for blit()
that offers positional parameters for the
most common drawing operations.
dx | (number or nil) | the x offset within the current drawing target (defaults to 0) |
dy | (number or nil) | the y offset within the current drawing target (defaults to 0) |
a | (number or nil) | the opacity level to blend the image onto the current target from 0.0 to 1.0 (defaults to 1.0) |
scale | (number or nil) | the scale multiplier for the target image (defaults to 1.0) |
clipw | (number or nil) | the width beyond which the image will be clipped (default to no clipping) |
cliph | (number or nil) | the height beyond which the image will be clipped (defaults to no clipping) |
mode | (modeconst or nil) | a bitmap of drawing mode constants (defaults to |
(rtk.Image) | returns self for method chaining |
Draws a region of the image onto a drawing target, or another image onto this image.
Whereas draw()
satisfies the most common use cases, blit()
provides a more
comprehensive interface, abstracting REAPER's native gfx.blit()
function with
additional features and conveniences.
This method takes a table of attributes where every possible field has some sane default. In fact, calling this method without any arguments will default to drawing the image to the top left of the current drawing target.
The attrs
table can contain the following fields, all of which are optional:
src
(rtk.Image
or numeric image id): the source image that is to be drawn.
If not specified, the rtk.Image
that blit() is called upon is the image source,
but if src
is another image, then the current image is used as the drawing target.
In other words, if src
is defined, it draws onto us, otherwise we draw
onto the current drawing target.sx
: x offset within the source image (defaults to x
)sy
: y offset within the source image (defaults to y
)sw
: the width of the source image to draw (defaults to w
)sh
: the height of the source image to draw (defaults to h
)dx
: x offset within the drawing target where sx
begins (defaults to 0)dy
: y offset within the drawing target where sy
begins (defaults to 0)dw
: the target width for the destination. If this different than sw
then the
image width is scaled to fit dw
. (Defaults to sw * scale
.)dh
: the target height for the destination. If this different than sh
then the
image height is scaled to fit dh
. (Defaults to sh * scale
.)scale
: the scale of the destination image, which is only used if
dw
or dh
are not defined (defaults to 1.0)clipw
: clips the drawn image to this width (defaults to no clipping of width)cliph
: clips the drawn image to this height (defaults to no clipping of height)mode
: a bitmap of mode constants (defaults to DEFAULT
)-- Draws the image at 50,100 in the current drawing target at 50% opacity
-- and scaled 150%.
local img = rtk.Image():load('portrait.jpg')
img:blit{dx=50, dy=100, alpha=0.5, scale=1.5}
-- Draws whatever is on the current drawing target to the image. This
-- trick is used by widgets like rtk.Viewport to support translucent
-- overlays.
--
-- In this example, we're calling from within a hypothetical widget's
-- _draw() function where the calculated geometry attributes are available.
local img = rtk.Image:create(self.calc.w, self.calc.h)
img:blit{src=gfx.dest, sx=self.calc.x, sy=self.calc.y, mode=rtk.Image.FAST_BLIT}
attrs | (table or nil) | a table of fields as described above |
(rtk.Image) | returns self for method chaining |
Changes all pixels in the image to the given color while respecting the alpha channel.
The image is mutated in situ. If you don't want that you can clone()
it first. This
uses filter()
under the hood, by first multiplying all pixels (except alpha) with 0,
and then adding the supplied color.
color | (colortype) | the color to change all pixels to |
(rtk.Image) | returns self for method chaining |
Applies an effect to the image by multiplying or adding values to individual channels.
The image is mutated in situ. If you don't want that you can clone()
it first.
mr | (number) | the amount to multiply all pixels in the red channel |
mg | (number) | the amount to multiply all pixels in the green channel |
mb | (number) | the amount to multiply all pixels in the blue channel |
ma | (number) | the amount to multiply all pixels in the alpha channel |
ar | (number) | the value to add to all pixels in the red channel |
ag | (number) | the value to add to all pixels in the green channel |
ab | (number) | the value to add to all pixels in the blue channel |
aa | (number) | the value to add to all pixels in the alpha channel |
(rtk.Image) | returns self for method chaining |
Draws a rectangle on the image in the given color.
color | (colortype) | the color of the rectangle |
x | (number) | the x offset within the image for the left edge of the rectangle |
y | (number) | the y offset within the image for the top edge of the rectangle |
w | (number) | the width of the rectangle |
h | (number) | the height of the rectangle |
fill | (boolean or nil) | whether the rectangle should be filled (defaults to false) |
(rtk.Image) | returns self for method chaining |
Blurs a region of the image.
REAPER's blur capability is a bit crap, being both slow and ugly, but this can be useful in certain circumstances. Just don't expect the same quality you get from a Gaussian blur.
strength | (number or nil) | the number of passes, where large values increase the level of blur (default 20) |
x | (number or nil) | the x offset within the image to start blurring (default 0) |
y | (number or nil) | the y offset within the image to start blurring (default 0) |
w | (number or nil) | the width of the blur region (default full image width) |
h | (number or nil) | the height of the blur region (default full image height) |
(rtk.Image) | returns self for method chaining |
Flips the image vertically in place.
The image is mutated in situ. If you don't want that you can clone()
it first.
(rtk.Image) | returns self for method chaining |
Rotates the image.
The rotation is non-destructive: it only applies to how the image is blitted.
This is a work-in-progress and doesn't work properly in all cases. For example, it doesn't work with scaling or cloning. The usefulness is very limited at the moment. Expect weird behavior.
degrees | (number) | the rotation in degrees |
(rtk.Image) | returns self for method chaining |
Widgets using rtk.Image
objects invoke this whenever rtk.scale.value
has changed.
This is a no-op with rtk.Image
itself, but subclasses may use this to implement adaptive
behaviors. For example, rtk.MultiImage
implements this method to switch images based on
current DPI requirements.