Image (lx-image.hpp)
Contents
- 1 Images
- 1.1 Pixel Formats
- 1.1.1 (1) SDK: LXiIMD_BYTE, etc. defines
- 1.1.2 (2) SDK: LXiIMV_GREY, etc. defines
- 1.1.3 (3) SDK: LXiIMT_INDEX, etc. defines
- 1.1.4 (4) SDK: LXiIMP_GREY8, etc. defines
- 1.1.5 (5) SDK: LXiPROCESS_FAST, etc. defines
- 1.1.6 (6) SDK: LXtPixelFormat, etc. typedefs (types)
- 1.1.7 (7) SDK: LXiIMC_RED, etc. defines
- 1.2 Image Interfaces
- 1.2.1 (8) SDK Common: Image methods
- 1.2.2 (9) SDK Common User: Size methods
- 1.2.3 (10) SDK Common User: Format methods
- 1.2.4 (11) PY Common: Image methods
- 1.2.5 Adding Image Attributes
- 1.2.6 Standard Image Attributes
- 1.2.7 HDR Image Attributes
- 1.2.8 Color Image
- 1.2.8.1 (15) SDK: Image::GetPixel, etc.
- 1.2.8.2 (16) SDK: LXu_IMAGE, etc. defines
- 1.2.8.3 (17) User Class: Image method
- 1.2.8.4 (18) PY: Image method
- 1.2.8.5 (19) SDK: ImageSegment::GetSegment, etc.
- 1.2.8.6 (20) PY: empty ImageSegment user class
- 1.2.8.7 (21) SDK: LXu_IMAGESEGMENT, etc. defines
- 1.2.8.8 (22) SDK: ImageWrite::SetPixel, etc.
- 1.2.8.9 (23) SDK: LXu_IMAGEWRITE, etc. defines
- 1.2.8.10 (24) SDK: CLxUser_ImageWrite::AddAttribute method
- 1.2.8.11 (25) PY: ImageWrite method
- 1.2.9 Index Image
- 1.2.9.1 (26) SDK: IndexImage::MapSize, etc.
- 1.2.9.2 (27) SDK: LXu_INDEXIMAGE define
- 1.2.9.3 (28) User Class: IndexImage method
- 1.2.9.4 (29) PY: IndexImage method
- 1.2.9.5 (30) SDK: IndexImageWrite::SetIndex, etc.
- 1.2.9.6 (31) SDK: LXu_INDEXIMAGEWRITE define
- 1.2.9.7 (32) SDK: CLxUser_IndexImageWrite::AddAttribute method
- 1.2.9.8 (33) PY: IndexImageWrite method
- 1.2.10 Layered Images
- 1.2.10.1 (34) SDK: LayeredImage::Size
- 1.2.10.2 (35) SDK: LayeredImage::Count, etc.
- 1.2.10.3 (36) SDK: LayeredImage::Offset, etc.
- 1.2.10.4 (37) SDK: LayeredImage::ChannelName
- 1.2.10.5 (38) SDK: LayeredImage::Parent, etc.
- 1.2.10.6 (39) SDK: LXu_LAYEREDIMAGE, etc. defines
- 1.2.10.7 (40) SDK: CLxUser_LayeredImage::GetImage method
- 1.2.10.8 (41) PY: empty LayeredImage user class
- 1.2.11 Writing Layered Images
- 1.2.12 Tile Image Interface
- 1.2.12.1 (46) SDK: TileImage::LevelCount
- 1.2.12.2 (47) SDK: TileImage::GetTile
- 1.2.12.3 (48) SDK: TileImage::GetTileSize
- 1.2.12.4 (49) SDK: TileImage::GetLevelSize
- 1.2.12.5 (50) SDK: TileImage::DetermineTile
- 1.2.12.6 (51) SDK: TileImage::DeterminePixel
- 1.2.12.7 (52) SDK: LXu_TILEIMAGE, etc. defines
- 1.2.12.8 (53) SDK: empty TileImage User Class
- 1.2.12.9 (54) PY: empty TileImage user class
- 1.2.13 Image I/O
- 1.2.13.1 (55) SDK: ImageLoaderTarget1::SetSize, etc.
- 1.2.13.2 (56) SDK: LXu_IMAGELOADERTARGET1 define
- 1.2.13.3 (57) SDK: empty ImageLoaderTarget1 User Class
- 1.2.13.4 (58) SDK: LXtImageTarget1 struct
- 1.2.13.5 (59) SDK: ImageLoaderTarget::SetSize, etc.
- 1.2.13.6 (60) SDK: LXu_IMAGELOADERTARGET define
- 1.2.13.7 (61) SDK: empty ImageLoaderTarget User Class
- 1.2.13.8 (62) PY: empty ImageLoaderTarget user class
- 1.2.14 Image Level Access
- 1.2.14.1 (63) SDK: ImageLevelSample::Count
- 1.2.14.2 (64) SDK: ImageLevelSample::GetLevelSize
- 1.2.14.3 (65) SDK: LXtImageSample struct
- 1.2.14.4 (66) SDK: ImageLevelSample::SampleLevel
- 1.2.14.5 (67) SDK: ImageLevelSample::GetPixel
- 1.2.14.6 (68) SDK: ImageLevelSample::GetLine
- 1.2.14.7 (69) PY: empty ImageLevelSample user class
- 1.2.14.8 (70) SDK: LXu_IMAGELEVELSAMPLE, etc. defines
- 1.3 Global Service
- 1.4 Nexus 801
- 1.5 Image Compression
- 1.6 Animation Creation
- 1.1 Pixel Formats
Images
This module defines COM interfaces for dealing with pixel-map images. Greyscale, color and alpha mapped images can be read, written, loaded and saved using these interfaces. All images present consistent features regardless of their internal representation.
Pixel Formats
Images are defined by their pixel format which consists of a datatype and vector size. There are two data types. The BYTE type is an 8 bit integer in the range is 0 to 255. The FLOAT type is a 32-bit floating point number in the nominal range of 0.0 to 1.0. Operations on integer pixel values are clamped so the results are always in the valid range. Floating point colors are not clamped, so the images can represent superbright and superdark pixels.
(1) SDK: LXiIMD_BYTE, etc. defines
#define LXiIMD_BYTE 0x00 #define LXiIMD_FLOAT 0x08 #define LXfIMD_MASK 0x08 #define LXxIMD_TYPE(t) (t & LXfIMD_MASK)
The vector sizes are GREY which is one monochrome component; RGB which is a vector of three color components; or RGBA which is a vector of three color components and alpha. The alpha channel is represented by 0 for transparent, 255 for opaque if in byte format, and 1.0 for opaque if floating point format.
(2) SDK: LXiIMV_GREY, etc. defines
#define LXiIMV_GREY 0x01 #define LXiIMV_RGB 0x03 #define LXiIMV_RGBA 0x04 #define LXfIMV_MASK 0x07 #define LXxIMV_TYPE(v) (v & LXfIMV_MASK)
Index images use the index flag.
(3) SDK: LXiIMT_INDEX, etc. defines
#define LXiIMT_INDEX 0x100 #define LXiIMT_MASK 0x100
Image pixel types are just the mask values combined together. Here are all six of the possible combinations in more convenient form. The color bits of an index mask can be acquired separately as well.
(4) SDK: LXiIMP_GREY8, etc. defines
#define LXiIMP_GREY8 (LXiIMD_BYTE | LXiIMV_GREY) #define LXiIMP_GREYFP (LXiIMD_FLOAT | LXiIMV_GREY) #define LXiIMP_RGB24 (LXiIMD_BYTE | LXiIMV_RGB) #define LXiIMP_RGBFP (LXiIMD_FLOAT | LXiIMV_RGB) #define LXiIMP_RGBA32 (LXiIMD_BYTE | LXiIMV_RGBA) #define LXiIMP_RGBAFP (LXiIMD_FLOAT | LXiIMV_RGBA) #define LXiIMP_IGREY8 (LXiIMD_BYTE | LXiIMV_GREY | LXiIMT_INDEX) #define LXiIMP_IRGB24 (LXiIMD_BYTE | LXiIMV_RGB | LXiIMT_INDEX) #define LXiIMP_IRGBA32 (LXiIMD_BYTE | LXiIMV_RGBA | LXiIMT_INDEX) // macro to check for greyscale pixel types explicitly, as LXiIMV_RGB masks LXiIMV_GREY #define LXi_IMP_ISGREY(x) ((x == LXiIMP_GREY8) || (x == LXiIMP_GREYFP) || (x == LXiIMP_IGREY8))
(5) SDK: LXiPROCESS_FAST, etc. defines
#define LXiPROCESS_FAST 0 #define LXiPROCESS_MEDIUM 1 #define LXiPROCESS_ACCURATE 2
(6) SDK: LXtPixelFormat, etc. typedefs (types)
typedef unsigned int LXtPixelFormat; typedef unsigned int LXtProcessHint; typedef unsigned char LXtImageByte; typedef float LXtImageFloat; typedef unsigned int LXtImageIndex; typedef LXtImageFloat LXtColorRGBA[4];
Color components in stored in vector type pixels are always in RGBA order. Use these indices to access components in a more abstract way.
(7) SDK: LXiIMC_RED, etc. defines
#define LXiIMC_RED 0 #define LXiIMC_GREEN 1 #define LXiIMC_BLUE 2 #define LXiIMC_ALPHA 3
Image Interfaces
There are several image interfaces, but they all start with the following two methods. The first gets the width and height of the image in pixels. The second returns the pixel format closest to the native storage format for the image data. Both must always return reasonable values, so there are no error conditions.
(8) SDK Common: Image methods
LXxMETHOD( void, Size) ( LXtObjectID self, unsigned int *w, unsigned int *h); LXxMETHOD( LXtPixelFormat, Format) ( LXtObjectID self);
There are also common user class extensions to allow reading the width and height independently, and to query attributes of the format.
(9) SDK Common User: Size methods
unsigned Width () const { unsigned w, h; Size (&w, &h); return w; } unsigned Height () const { unsigned w, h; Size (&w, &h); return h; }
(10) SDK Common User: Format methods
bool IsFloat () const { return LXxIMD_TYPE (Format ()) == LXiIMD_FLOAT; } unsigned Components () const { return LXxIMV_TYPE (Format ()); }
(11) PY Common: Image methods
def IsFloat(self): return (self.Format() & lx.symbol.fIMD_MASK) == lx.symbol.iIMD_FLOAT def Components(self): return self.Format() & lx.symbol.fIMV_MASK
Adding Image Attributes
Arbitrary attributes may be added to writeable image objects. These can be read and set using the image ILxAttributes interface.
This function allows a client to add an attribute to an ILxImageWrite object by providing an attribute name and an exotype name. If the attribute has been added successfully, its index will be returned.
(12) SDK Common: Image Write methods
LXxMETHOD( LxResult, AddAttribute) ( LXtObjectID self, const char *name, const char *type, unsigned *index);
Standard Image Attributes
Some name and types are defined for common attributes that are read or set by the application.
DPI | Dots per Inch, which is the number of pixels in the image that will fit vertically in each inch of the printed image. To know the horizontal DPI you have to take pixel aspect into account. |
PIXASPECT | This is the aspect ratio of a single pixel in the image, computed as width/height. If the pixel height is one, then the pixel width is the same as the pixel aspect. |
REGX0, REGX1, REGY0, REGY1 | Pixel coordinates of the borders of the rendered region of the image. X and Y start at zero at the left and top of the image. |
GAMMA | Gamma is an exponent applied to unity-normalized color values in the image before saving. To get the "real" values for pixels in the image, the inverse gamma needs to be applied. |
COMMENT | Everyone's got something to say, right? |
(13) SDK: LXsIATTRNAME_CAM_TRANS, etc. defines
#define LXsIATTRNAME_CAM_TRANS "cameraTransform" #define LXsIATTRTYPE_CAM_TRANS LXsTYPE_STRING #define LXsIATTRNAME_WORLD_TO_CAM "worldToCamera" #define LXsIATTRTYPE_WORLD_TO_CAM LXsTYPE_STRING #define LXsIATTRNAME_ISO "ISO" #define LXsIATTRTYPE_ISO LXsTYPE_FLOAT #define LXsIATTRNAME_EXPTIME "exposureTime" #define LXsIATTRTYPE_EXPTIME LXsTYPE_FLOAT #define LXsIATTRNAME_DPI "DPI" #define LXsIATTRTYPE_DPI LXsTYPE_FLOAT #define LXsIATTRNAME_APERATUREX "aperatureX" #define LXsIATTRTYPE_APERATUREX LXsTYPE_FLOAT #define LXsIATTRNAME_APERATUREY "aperatureY" #define LXsIATTRTYPE_APERATUREY LXsTYPE_FLOAT #define LXsIATTRNAME_CLIP_DIST "clipDist" #define LXsIATTRTYPE_CLIP_DIST LXsTYPE_FLOAT #define LXsIATTRNAME_FOC_LENGTH "focalLength" #define LXsIATTRTYPE_FOC_LENGTH LXsTYPE_FLOAT #define LXsIATTRNAME_PIXASPECT "pixelAspect" #define LXsIATTRTYPE_PIXASPECT LXsTYPE_FLOAT #define LXsIATTRNAME_REGX0 "regionX0" #define LXsIATTRTYPE_REGX0 LXsTYPE_INTEGER #define LXsIATTRNAME_REGX1 "regionX1" #define LXsIATTRTYPE_REGX1 LXsTYPE_INTEGER #define LXsIATTRNAME_REGY0 "regionY0" #define LXsIATTRTYPE_REGY0 LXsTYPE_INTEGER #define LXsIATTRNAME_REGY1 "regionY1" #define LXsIATTRTYPE_REGY1 LXsTYPE_INTEGER #define LXsIATTRNAME_GAMMA "gamma" #define LXsIATTRTYPE_GAMMA LXsTYPE_FLOAT #define LXsIATTRNAME_COMMENT "comment" #define LXsIATTRTYPE_COMMENT LXsTYPE_STRING #define LXsIATTRNAME_APPLY_DISPLAY_LUT "applyDisplayLUT" #define LXsIATTRTYPE_APPLY_DISPLAY_LUT LXsTYPE_INTEGER #define LXsSAV_OUTPUT_PIXEL_FORMAT "outputPixelFormat" #define LXsSAV_OUTPUT_KNOWN_COLOR_SPACE "knownColorSpace" // Certain image formats have a particular color space which // can't be inferred from their pixel format (e.g. .hdr is 8-bit but linear) // Image IO Plugins can set the 'colorspace' field of the LXtImageTarget1 // structure to LXsKNOWN_COLORSPACE_LINEAR in order to specify // that the colorspace of this image is linear. #define LXsKNOWN_COLORSPACE_LINEAR "linear" #define LXsDEFAULT_COLORSPACE_8BIT "8bit" #define LXsDEFAULT_COLORSPACE_16BIT "16bit" #define LXsDEFAULT_COLORSPACE_FLOAT "float" #define LXsDEFAULT_COLORSPACE_GREY "grey" // Image IO Plugins can set the 'depth' field of the LXtImageTarget1 // structure to any of the below values. // Modo will choose a default colorspace for the image based on this setting. // If 'None' is specified, no default colorspace conversion will occur. // // But users can override this choice on a per-clip basis, by setting the // clip's colorspace channel. // #define LXiDEFAULT_COLORSPACE_NONE 0 #define LXiDEFAULT_COLORSPACE_8BIT 1 #define LXiDEFAULT_COLORSPACE_16BIT 2 #define LXiDEFAULT_COLORSPACE_FLOAT 3 #define LXiDEFAULT_COLORSPACE_GREY 4
HDR Image Attributes
The OpenEXR file specification suggests some common metadata appropriate for HDR or physically accurate images.
LUMA | The luminance of a white pixel with r=g=b=1.0. The units, candela/m^2, match the 'whiteLuminance' OpenEXR standard attribute. |
FOCDIST | The focus distance for the camera. |
APERTURE | the aperture is given in f-stops, (focal length of the lens divided by the diameter of the iris opening). |
(14) SDK: LXsIATTRNAME_LUMA, etc. defines
#define LXsIATTRNAME_LUMA "luminance" #define LXsIATTRTYPE_LUMA LXsTYPE_FLOAT #define LXsIATTRNAME_FOCDIST "focusDist" #define LXsIATTRTYPE_FOCDIST LXsTYPE_FLOAT #define LXsIATTRNAME_APERTURE "aperture" #define LXsIATTRTYPE_APERTURE LXsTYPE_FLOAT
Color Image
The basic image interface allows clients to read colored pixels or entire lines. When reading pixels the client should always ask for an RGBA format, but for lines the full range of format conversions is possible.
(15) SDK: Image::GetPixel, etc.
''[[#C8|SDK Common: Image methods]]'' LXxMETHOD( LxResult, GetPixel) ( LXtObjectID self, unsigned int x, unsigned int y, LXtPixelFormat type, void *pixel); LXxMETHOD( const void *, GetLine) ( LXtObjectID self, unsigned int y, LXtPixelFormat type, void *buf);
This is the primary interface for image objects, and so this the GUID specified when attempting to load or save images.
(16) SDK: LXu_IMAGE, etc. defines
#define LXu_IMAGE "469AFBB8-E6A2-4d88-9C39-5430CA72E404" #define LXa_IMAGE "image" #define LXa_IMAGE_FLOAT "image_float" #define LXsSAV_IMAGE_FLOAT "saver.imageFloat"
(17) User Class: Image method
''[[#C9|SDK Common User: Size methods]]'' ''[[#C10|SDK Common User: Format methods]]''
(18) PY: Image method
''[[#C11|PY Common: Image methods]]''
An image segment is a sub-range of pixels within a scanline, which is always read in FP RGBA format, and written in any given format.
(19) SDK: ImageSegment::GetSegment, etc.
LXxMETHOD( LxResult, GetSegment) ( LXtObjectID self, unsigned int y, unsigned int left, unsigned int right, LXtImageFloat *rgba); LXxMETHOD( LxResult, SetSegment) ( LXtObjectID self, unsigned int y, unsigned int left, unsigned int right, LXtPixelFormat type, const void *line);
Empty ImageSegment Python user class.
(20) PY: empty ImageSegment user class
pass
(21) SDK: LXu_IMAGESEGMENT, etc. defines
#define LXu_IMAGESEGMENT "370ABB2F-119E-4EEC-98F8-03388ABE7D2C" #define LXa_IMAGESEGMENT "imagesegment"
Writing to an image requires a different interface. This provides methods for assigning color values to pixels or lines. Not all images will be writable.
(22) SDK: ImageWrite::SetPixel, etc.
''[[#C8|SDK Common: Image methods]]'' ''[[#C12|SDK Common: Image Write methods]]'' LXxMETHOD( LxResult, SetPixel) ( LXtObjectID self, unsigned int x, unsigned int y, LXtPixelFormat type, const void *pixel); LXxMETHOD( LxResult, SetLine) ( LXtObjectID self, unsigned int y, LXtPixelFormat type, const void *line);
(23) SDK: LXu_IMAGEWRITE, etc. defines
#define LXu_IMAGEWRITE "8F9CF293-B6F9-498e-A124-6704E2C24662" #define LXa_IMAGEWRITE "imagewrite"
(24) SDK: CLxUser_ImageWrite::AddAttribute method
LxResult AddAttribute ( const std::string &name, const std::string &type, unsigned &index) { return CLxLoc_ImageWrite::AddAttribute (name.c_str (), type.c_str (), &index); } ''[[#C9|SDK Common User: Size methods]]'' ''[[#C10|SDK Common User: Format methods]]''
(25) PY: ImageWrite method
''[[#C11|PY Common: Image methods]]''
Index Image
An index image is one that stores index values at the pixel locations and uses a lookup table to get the color. While the ILxImage interface gets the color values at each pixel, this interface allows access to the underlying index and color map.
(26) SDK: IndexImage::MapSize, etc.
''[[#C8|SDK Common: Image methods]]'' LXxMETHOD( LxResult, MapSize) ( LXtObjectID self, unsigned *numColors); LXxMETHOD( LxResult, GetIndex) ( LXtObjectID self, unsigned int x, unsigned int y, LXtImageIndex *index); LXxMETHOD( LxResult, GetMap) ( LXtObjectID self, LXtImageIndex index, LXtPixelFormat type, void *pixel);
(27) SDK: LXu_INDEXIMAGE define
#define LXu_INDEXIMAGE "08CAE3BC-ED69-4EC4-9D7D-BBDBE4E35343"
(28) User Class: IndexImage method
''[[#C9|SDK Common User: Size methods]]'' ''[[#C10|SDK Common User: Format methods]]''
(29) PY: IndexImage method
''[[#C11|PY Common: Image methods]]''
Writing to an index image can only be done with one of these interfaces.
(30) SDK: IndexImageWrite::SetIndex, etc.
''[[#C8|SDK Common: Image methods]]'' ''[[#C12|SDK Common: Image Write methods]]'' LXxMETHOD( LxResult, SetIndex) ( LXtObjectID self, unsigned int x, unsigned int y, LXtImageIndex index); LXxMETHOD( LxResult, SetMap) ( LXtObjectID self, LXtImageIndex index, LXtPixelFormat type, const void *pixel);
(31) SDK: LXu_INDEXIMAGEWRITE define
#define LXu_INDEXIMAGEWRITE "D59C5E09-779E-445b-B317-282630CB6BD5"
(32) SDK: CLxUser_IndexImageWrite::AddAttribute method
LxResult AddAttribute ( const std::string &name, const std::string &type, unsigned &index) { return CLxLoc_IndexImageWrite::AddAttribute (name.c_str (), type.c_str (), &index); } ''[[#C9|SDK Common User: Size methods]]'' ''[[#C10|SDK Common User: Format methods]]''
(33) PY: IndexImageWrite method
''[[#C11|PY Common: Image methods]]''
Layered Images
In many cases it is useful to add channels to images beyond the basic R, G, B, and A. In other cases, it is useful to preserve multiple sub-images in a composition. These requirements can be met with a layered image object, consisting of a list of named, independent sub-images, each with their own dimensions, offset, and pixel type. Interlayer blending information is also associated with each layer, Photoshop style.
Size | This returns the bounds of the image composition. While the combination of layer sizes and offsets makes it possible that some layers' pixels will not all be in bounds, the entire composition will be cropped at (0,0) to (w,h). |
(34) SDK: LayeredImage::Size
LXxMETHOD( LxResult, Size) ( LXtObjectID self, unsigned int *w, unsigned int *h);
Adding a standard format() method here would allow this object to masquerade as an ILxImage object... probably more confusing than useful.
Count | return number of layers. |
Image | return ILxImage for layer at 'index'. |
Name | return name for layer at 'index'. |
Type | return type string and flags for layer at 'index'. |
(35) SDK: LayeredImage::Count, etc.
LXxMETHOD( unsigned int, Count) ( LXtObjectID self); LXxMETHOD( LxResult, Image) ( LXtObjectID self, unsigned int index, void **ppvObj); LXxMETHOD( LxResult, Name) ( LXtObjectID self, unsigned int index, const char **name); LXxMETHOD( LxResult, Type) ( LXtObjectID self, unsigned int index, unsigned int *flags, const char **type);
Offset | return pixel offset for layer at 'index' relative to complete layered image composition.. |
Blend | returns the opacity and the image blend mode for layer at 'index'. The image blend mode is one of the LXi_IBM_ modes. |
(36) SDK: LayeredImage::Offset, etc.
LXxMETHOD( LxResult, Offset) ( LXtObjectID self, unsigned int index, int *x, int *y); LXxMETHOD( LxResult, Blend) ( LXtObjectID self, unsigned int index, float *opacity, unsigned int *mode);
ChannelName | Pass back the name of the channel at the given layer and channel index, which may be overridden by the user by inserting semicolon delimiters in between each channel name in the Shader Tree. |
(37) SDK: LayeredImage::ChannelName
LXxMETHOD( LxResult, ChannelName) ( LXtObjectID self, unsigned layerIndex, unsigned channelIndex, const char **name);
Parent | Returns the parent layer index, or -1 if there is no parent |
IsGroup | Returns true if the layer is a group layer |
(38) SDK: LayeredImage::Parent, etc.
LXxMETHOD( LxResult, Parent) ( LXtObjectID self, unsigned layerIndex, int *parentIndex); LXxMETHOD( LxResult, IsGroup) ( LXtObjectID self, unsigned layerIndex, unsigned int *isGroup);
(39) SDK: LXu_LAYEREDIMAGE, etc. defines
#define LXu_LAYEREDIMAGE "8523ECC4-B8B3-4C6E-8F14-A1D2D01E8038" #define LXa_LAYEREDIMAGE "layeredimage"
(40) SDK: CLxUser_LayeredImage::GetImage method
''[[#C9|SDK Common User: Size methods]]'' bool GetImage ( unsigned int index, CLxLoc_Image &img) { LXtObjectID obj; if (LXx_FAIL (Image (index, &obj))) return false; return img.take (obj); }
Empty LayeredImage Python user class.
(41) PY: empty LayeredImage user class
pass
Writing Layered Images
Layered image objects will provide an ILxLayeredImageWrite interface for writing.
AddLayer | This is the way a layered image is actually created, adding layers by passing in ILxImage objects. The image object will be locked and released by the layered image, so clients may release the image after setting the layer. |
SetType | Layer type and flags can be set using this function. |
SetOffset | Pixel offsets for a layer are set with this function. |
SetBlending | The blending parameter (or opacity) and the blending mode are set with this function. A list of modes should appear here shortly... |
(42) SDK: LayeredImageWrite::AddLayer, etc.
LXxMETHOD( LxResult, AddLayer) ( LXtObjectID self, LXtObjectID image, const char *name, const char **channelNames); LXxMETHOD( LxResult, SetType) ( LXtObjectID self, unsigned int index, int flags, const char *type); LXxMETHOD( LxResult, SetOffset) ( LXtObjectID self, unsigned int index, int x, int y); LXxMETHOD( LxResult, SetBlending) ( LXtObjectID self, unsigned int index, float blend, const char *mode); LXxMETHOD( LxResult, AddAttribute) ( LXtObjectID self, const char *name, const char *type, int *index);
(43) SDK: LXu_LAYEREDIMAGEWRITE define
#define LXu_LAYEREDIMAGEWRITE "79D28886-9652-4A76-9AA7-1B1E4D553DCD"
(44) SDK: empty LayeredImageWrite User Class
Empty LayeredImageWrite Python user class.
(45) PY: empty LayeredImageWrite user class
pass
Tile Image Interface
The tiled image interface provides a way for clients to implement images using tile trees. Tiles will themselves simply be images, so we can manage a global cache of them internally rather than depending on each implementation to manage an internal cache.
A tile tree is a collection of "levels", which are intended to be images of decreasing size. Each image level is broken into tiles, which allows us to only work on small portions of the image instead of loading an entire image. Typically, the image levels decrease in size by power of two.
For example, one dimension of a normal tile tree of an image with size 1024x1024, and tiles of size 256x256, would look like this:
Level 2 _ Level 1 _ _ Level 0 _ _ _ _
Where each _ represents a tile.
One thing to note is that the meaning of "level" is reverse from ImageLevelSample; level 0 is the base of the tile tree, where each tile is the original size, and the highest value of level will have a single tile.
Implementations of the TileImage interface are only required to be able to get the tiles at level 0; they may require the clients to generate tiles above level 0 by resizing the tiles below them.
LevelCount | LevelCount returns the number of levels in the tile tree. |
(46) SDK: TileImage::LevelCount
LXxMETHOD( unsigned, LevelCount) ( LXtObjectID self);
GetTile | GetTile is the direct way of getting a tile from the tile image. In general, this will be loaded directly from the file off disk. Tiles will simply be an ILxImageID. These should be created by the implementation, and the client will release them. |
It should return LXe_OK if it's okay, but LXe_OUTOFBOUNDS if the tile isn't in the image.
(47) SDK: TileImage::GetTile
LXxMETHOD( LxResult, GetTile) ( LXtObjectID self, unsigned int level, unsigned int tileX, unsigned int tileY, void **ppvObj);
GetTileSize | GetTileSize will determine the width and height of a given tile, and place it in *width and *height. For a given TileImage, these will usually be constant and equal except for boundary tiles. |
It should return LXe_OK if it's okay, but LXe_OUTOFBOUNDS if the tile isn't in the image.
(48) SDK: TileImage::GetTileSize
LXxMETHOD( LxResult, GetTileSize) ( LXtObjectID self, unsigned int level, unsigned int tileX, unsigned int tileY, unsigned int *width, unsigned int *height);
GetLevelSize | GetLevelSize will determine the size of an entire level both in pixel counts and tile counts. It will place the former in *width and *height, and the latter in *tilesWidth and *tilesHeight. |
Any of the pointers should be able to be NULL, if the caller only wants to get the tile dimensions, for instance. It should return LXe_OUTOFBOUNDS if the level isn't in the image.
(49) SDK: TileImage::GetLevelSize
LXxMETHOD( LxResult, GetLevelSize) ( LXtObjectID self, unsigned int level, unsigned int *width, unsigned int *height, unsigned int *tilesWidth, unsigned int *tilesHeight);
DetermineTile | DetermineTile will determine which tile contains a given pixel at a given level, and place it in *tileX and *tileY. |
It should return LXe_OK normally, but LXe_OUTOFBOUNDS if the pixel isn't on that level.
(50) SDK: TileImage::DetermineTile
LXxMETHOD( LxResult, DetermineTile) ( LXtObjectID self, unsigned int level, unsigned int x, unsigned int y, unsigned int *tileX, unsigned int *tileY);
DeterminePixel | DeterminePixel will take in a pixel position X and Y for a given level, and put in *adjX and *adjY the position of the pixel within the tile that contains it. |
It should return LXe_OK normally, but LXe_OUTOFBOUNDS if the pixel isn't on that level.
(51) SDK: TileImage::DeterminePixel
LXxMETHOD( LxResult, DeterminePixel) ( LXtObjectID self, unsigned int level, unsigned int x, unsigned int y, unsigned int *adjX, unsigned int *adjY);
(52) SDK: LXu_TILEIMAGE, etc. defines
#define LXu_TILEIMAGE "BD12D6C3-C08F-4AD1-A080-399F958D28C0" #define LXa_TILEIMAGE "tileImage"
(53) SDK: empty TileImage User Class
Empty TileImage Python user class.
(54) PY: empty TileImage user class
pass
Image I/O
Images can be loaded and saved with appropriate servers of the loader and saver class. Loading can be opaque for disk-based access, although most loaders are currently direct, so a format, type, size and number of colors must be specified by the recognition method to allow the host to create a suitable image object to receive the data. This is done using a target interface.
(55) SDK: ImageLoaderTarget1::SetSize, etc.
LXxMETHOD( LxResult, SetSize) ( LXtObjectID self, LXtPixelFormat type, unsigned width, unsigned height); LXxMETHOD( LxResult, SetMap) ( LXtObjectID self, unsigned ncolor);
(56) SDK: LXu_IMAGELOADERTARGET1 define
#define LXu_IMAGELOADERTARGET1 "9F124A7B-DFC7-42E6-977B-71AE2E33B017"
(57) SDK: empty ImageLoaderTarget1 User Class
Legacy struct, still provided for older image loaders.
(58) SDK: LXtImageTarget1 struct
LXtPixelFormat type; unsigned int w, h, ncolor;
The latest image loader target interface. This has two additional methods. * SetColorspaceDepth * SetColorspace
These can be used to specify more accurately which colorspaces to use for the given type.
(59) SDK: ImageLoaderTarget::SetSize, etc.
LXxMETHOD( LxResult, SetSize) ( LXtObjectID self, LXtPixelFormat type, unsigned width, unsigned height); LXxMETHOD( LxResult, SetMap) ( LXtObjectID self, unsigned ncolor); LXxMETHOD( LxResult, SetColorspaceDepth) ( LXtObjectID self, unsigned depth); LXxMETHOD( LxResult, SetColorspace) ( LXtObjectID self, const char *colorspace);
(60) SDK: LXu_IMAGELOADERTARGET define
#define LXu_IMAGELOADERTARGET "1034861C-78C4-4BEC-9588-F1D3C0B0401A"
(61) SDK: empty ImageLoaderTarget User Class
Empty ImageLoaderTarget Python user class.
(62) PY: empty ImageLoaderTarget user class
pass
Image Level Access
Images can present an alternate interface that allows them to be accessed as a set of levels. The levels are filtered versions of the image at different scales, and typically are arranged in power-law series. The underlying implementation may be tiled, enabling access to images that are larger than the available memory, since the image server only needs sufficient memory for a single tile. Levels can be used directly when rendering so that the only levels used are those approximating the visual scale of the image in the rendered scene.
The count returns the number of different levels in the image.
(63) SDK: ImageLevelSample::Count
LXxMETHOD( unsigned, Count) ( LXtObjectID self);
Each resolution level should be twice the size of the previous level, starting at 1x1 pixels for level zero, although the tiled image load can pass back slightly different dimensions for each resolution level, according to the needs of the tiled format. The image may or may not provide the full image as a level, although the full image must be accessible through the required ILxImage interface.
(64) SDK: ImageLevelSample::GetLevelSize
LXxMETHOD( LxResult, GetLevelSize) ( LXtObjectID self, unsigned level, unsigned *width, unsigned *height);
Sampling of a level is done using an array of structures, each with a pixel position in the level and a location to receive the RGBA data in floating point format.
(65) SDK: LXtImageSample struct
unsigned x; unsigned y; LXtImageFloat *rgba;
Level images provide image data at a given resolution level, for an array of image samples.
(66) SDK: ImageLevelSample::SampleLevel
LXxMETHOD( LxResult, SampleLevel) ( LXtObjectID self, unsigned level, LXtImageSample *pixel, unsigned num);
Pixels can be directly accessed from a given level, in either integer or floating-point RGBA format, using an x- and y-coordinate in the local coordinate system of the specified level.
(67) SDK: ImageLevelSample::GetPixel
LXxMETHOD( LxResult, GetPixel) ( LXtObjectID self, unsigned level, unsigned int x, unsigned int y, LXtPixelFormat type, void *pixel);
Levels also support line-by-line access through a modified version of the GetLine() method, which uses a y-coordinate in the local coordinate system of the specified level. The data returned is always RGBA in floating point.
(68) SDK: ImageLevelSample::GetLine
LXxMETHOD( const LXtImageFloat *, GetLine) ( LXtObjectID self, unsigned level, unsigned y, LXtImageFloat *buf);
Empty ImageLevelSample Python user class.
(69) PY: empty ImageLevelSample user class
pass
(70) SDK: LXu_IMAGELEVELSAMPLE, etc. defines
#define LXu_IMAGELEVELSAMPLE "79A6EA0E-9589-4D03-880C-C06A6EC6CF7D" #define LXa_IMAGELEVELSAMPLE "imageLevelSample"
Global Service
Image facilities can be accessed through the SDK using a global service interface.
(71) SDK: ImageService::ScriptQuery, etc.
LXxMETHOD( LxResult, ScriptQuery) ( LXtObjectID self, void **ppvObj); LXxMETHOD( LxResult, Create) ( LXtObjectID self, unsigned int width, unsigned int height, LXtPixelFormat type, unsigned int maxIndex, void **ppvObj); LXxMETHOD( LxResult, Duplicate) ( LXtObjectID self, LXtObjectID source, LXtPixelFormat type, void **ppvObj); LXxMETHOD( LxResult, Load) ( LXtObjectID self, const char *filePath, void **ppvObj); LXxMETHOD( LxResult, Save) ( LXtObjectID self, LXtObjectID image, const char *filePath, const char *format, LXtObjectID monitor); LXxMETHOD( LxResult, Resample) ( LXtObjectID self, LXtObjectID dest, LXtObjectID source, LXtProcessHint hint); LXxMETHOD( LxResult, Composite) ( LXtObjectID self, LXtObjectID dest, LXtObjectID source, const LXtFVector2 pos); LXxMETHOD( LxResult, DrawLine) ( LXtObjectID self, LXtObjectID image, const LXtFVector2 p0, const LXtFVector2 p1, const LXtFVector color); LXxMETHOD( LxResult, Kelvin2RGB) ( LXtObjectID self, float kelvin, LXtFVector rgbColor); LXxMETHOD( LxResult, RGB2Kelvin) ( LXtObjectID self, const LXtFVector rgbColor, float *kelvin); LXxMETHOD( LxResult, CreateCrop) ( LXtObjectID self, LXtObjectID sourceImage, double x, double y, double w, double h, void **ppvObj);
This reads the entire image into a single buffer given the pixel format. This is just like Image::GetLine() except that it does all the lines at once.
(72) SDK: ImageService::ImageGetBuffer
LXxMETHOD( LxResult, ImageGetBuffer) ( LXtObjectID self, LXtObjectID sourceImage, LXtPixelFormat type, void *buf);
Nexus 801
LaodNoCache() is the same as Load(), but the image is not added to the intenral cache. This is useful when the image is only needed once (say, because it is being loaded and resized).
(73) SDK: ImageService::LoadNoCache
LXxMETHOD( LxResult, LoadNoCache) ( LXtObjectID self, const char *filePath, void **ppvObj);
(74) SDK: LXu_IMAGESERVICE define
#define LXu_IMAGESERVICE "03A7D258-397C-4D92-B3AF-695AD676FCF9"
Create a new image and fill in the user's user object.
(75) SDK: CLxUser_ImageService::New method
bool New ( CLxUser_Image &image, unsigned int w, unsigned int h, LXtPixelFormat type, unsigned int maxIndex = 0) { LXtObjectID obj; bool created = false; image.clear (); if (LXx_OK (Create (w, h, type, maxIndex, &obj))) { image.take (obj); created = true; } return created; } bool NewCrop ( CLxUser_Image &image, CLxUser_Image &sourceImage, double x, double y, double w, double h) { LXtObjectID obj; bool created = false; image.clear (); if (LXx_OK (CLxLoc_ImageService::CreateCrop (sourceImage, x, y, w, h, &obj))) { image.take (obj); created = true; } return created; } bool Load ( CLxUser_Image &image, const std::string &filePath) { LXtObjectID obj; bool found = false; image.clear (); if (LXx_OK (CLxLoc_ImageService::Load (filePath.c_str (), &obj))) { image.take (obj); found = true; } return found; } bool LoadNoCache ( CLxUser_Image &image, const std::string &filePath) { LXtObjectID obj; bool found = false; image.clear (); if (LXx_OK (CLxLoc_ImageService::LoadNoCache (filePath.c_str (), &obj))) { image.take (obj); found = true; } return found; } LxResult Save ( CLxUser_Image &image, const std::string &filePath, const std::string &format, ILxUnknownID monitor = 0) { return CLxLoc_ImageService::Save (image, filePath.c_str (), format.c_str (), monitor); } LxResult Resample ( CLxUser_Image &destImage, CLxUser_Image &sourceImage, LXtProcessHint hint) { return CLxLoc_ImageService::Resample (destImage, sourceImage, hint); } LxResult Composite ( CLxUser_Image &destImage, CLxUser_Image &sourceImage, const LXtFVector2 pos) { return CLxLoc_ImageService::Composite (destImage, sourceImage, pos); } LxResult DrawLine ( CLxUser_Image &image, const LXtFVector2 p0, const LXtFVector2 p1, LXtFVector color) { return CLxLoc_ImageService::DrawLine (image, p0, p1, color); }
Empty Image service Python user class.
(76) PY: empty Service.Image user class
pass
Image Compression
Image block codec interfaces allow an image to be compressed into a block of data which can then be included in other files, such as for thumbnails. Compress() allocates and returns a block encoding the image. Free() frees the block when the client is done. Decompress() creates an image from a block.
(77) SDK: ImageBlockCodec::Compress, etc.
LXxMETHOD( LxResult, Compress) ( LXtObjectID self, LXtObjectID image, unsigned char **buf, int *size); LXxMETHOD( void, Free) ( LXtObjectID self, unsigned char *buf, int size); LXxMETHOD( LxResult, Decompress) ( LXtObjectID self, unsigned char *buf, int size, void **ppvObj);
(78) SDK: LXu_IMAGEBLOCKCODEC, etc. defines
#define LXu_IMAGEBLOCKCODEC "7960B5BA-70D3-4FAD-8CA1-BD30A7938554" #define LXa_IMAGEBLOCKCODEC "imageBlockCodec"
Animation Creation
Since there's really no better place for this we'll put the simple animation interface here. This is a very simple API for creating animations.
The LXsMOVIE_OPTIONSCOMMAND tag identifies a command that should be executed to set options for the movie saver. It is commonly called when the user has chosen the movie saver from a file dialog, and in any other situation where the user needs to be presented with saver options before actually saving the movie.
(79) SDK: LXu_MOVIE, etc. defines
#define LXu_MOVIE "B7BD9F49-9400-45F1-ADEE-BFE82A1C4A65" #define LXa_MOVIE "movie" #define LXsMOVIE_SAVESTEREO "movie.stereoscopic" #define LXsMOVIE_OPTIONSCOMMAND "optionsCommand"
Movie creation API is pretty simple - you begin a movie, add a bunch of images in sequence, and then end it. The movie itself lives on disk at the path specified. There are currently no flags defined, but there may be in the future. Default format is MP4 and default framerate is 15 fps.
(80) SDK: Movie::BeginMovie
LXxMETHOD( LxResult, BeginMovie) ( LXtObjectID self, const char *fname, int w, int h, int flags);
Before adding any frames, you can change the framerate from the default of 15 with following method.
(81) SDK: Movie::SetFramerate
LXxMETHOD( LxResult, SetFramerate) ( LXtObjectID self, int frate);
Adding an image is straightforward. Do this in sequence.
(82) SDK: Movie::AddImage
LXxMETHOD( LxResult, AddImage) ( LXtObjectID self, LXtObjectID image);
When done adding images, call this to finalize the movie and write it to disk.
(83) SDK: Movie::EndMovie
LXxMETHOD( LxResult, EndMovie) ( LXtObjectID self);
Adding an audio track. This must be called after adding all images before EndMove.
(84) SDK: Movie::AddAudio
LXxMETHOD( LxResult, AddAudio) ( LXtObjectID self, LXtObjectID audio);