Image Browsing
Image Browsing is a set features introduced in CameraSDK 3.0. These lets you access all images stored on the camera. You can get previews (thumbnails) of images, scaled and cropped Jpegs, view meta-data, change or apply rating and delete images.
Caution
These features requires your cameras to run a newer firmware, since many of the features introduced in these APIs, involve processing to be done on the camera.
iXM: Firmware 4.23 or later
IQ4: Firmware 6.03 or later
Common traits
All APIs for Image browsing are method present on the Camera
class. Most of the method exists in two variants: sync and async.
The sync variant straight forward, it blocks and returns the requested data, e.g. a preview. The async variant does not block, and returns void
. The requested data is delivered via a notification.
Internally, the sync methods are simply calling the corresponding async API, and then blocks until a notification with the data arrives.
Optional Timeouts
All synchronous APIs include an optional timeout argument. By default this argument is set to 0
(zero), which means there is no timeout. Consequently the synchronous call will block forever, if they never receive their expected response.
Listing images
To get a list of all images on the camera, call this method on the Camera
object:
std::vector<std::shared_ptr<IImageListItem const>>
imageList = camera.GetAllImages();
IEnumerable<IImageListItem> imageList = camera.GetAllImages();
Each image is represented as a lightweight IImageListItem object, that include only 4 properties: Id, Date, filename & device.
Property |
Description |
---|---|
Id |
You use the Id to reference the image in all subsequent calls the image browsing APIs |
Date |
The Date is a Unix style (Epoch) timestamp of the image’s capture date and time |
Filename |
The image’s IIQ file name, like: |
Device |
The Device property is a bit-field that tells on which storage media the image is present. It also tells if there are any Jpeg versions of the image |
The returned list is a snapshot copy of the images present on the camera. Any changes to the set of images on the camera, will require you to obtain a new list, by calling GetAllImages
again.
Alternatively, you can receive notifications signalling images are added or removed.
Get basic Meta-Data
You can request a set of common meta-data about any image. Use this method on the Camera
class:
std::shared_ptr<IImageFileBasicInfo const> metaData =
camera.GetBasicImageInfo(imageId);
IImageFileBasicInfo metaData = camera.GetBasicImageInfo(imageId);
The returned IImageFileBasicInfo
derived object defines the commonly used meta-data related to image files. The set contains the following information:
Aperture |
Shutter Speed |
Lens Focal Length |
White Balance |
IIQ file comprs. |
Orientation |
Dimensions |
ISO |
Star Rating |
Unix Time stamp |
Image file size |
Filename |
Focus point |
Similar to GetBasicImageInfo
, there is the async variant called RequestBasicImageInfoAsync
. This async variant returns the meta data object through a CameraImageBasicImageInfo
notification.
Request an IIQ file
You can download any image’s IIQ file, from the camera. You request the IIQ using the image’s Id, and then receive the IIQ file just you would when transferring captures.
This means you first must first enable Receive Captured Images, since requested IIQ’s are delivered using that same mechanism.
This has the implication that a trigger could happen, while you wait to receive an image you requested. Therefore, you should check the filename of the received image, if it matches the image you requested earlier.
To request and receive an IIQ file, begins with a three-step process on the camera
object:
// Enable image receiving
camera.EnableImageReceiving(true);
// Request the image with the 'Id' received from 'GetAllImages'
camera.RequestImage(imageItem.GetId());
// wait for image to arrive
IIQImageFile iiqFile = camera.WaitForImage();
// Enable image receiving
camera.EnableImageReceiving(true);
// Request the image with the 'Id' received from 'GetAllImages'
camera.RequestImage(imageItem.Id);
// wait for image to arrive
IIQImageFile iiqFile = camera.WaitForImage();
After receiving the image object (IIQImageFile
), compare its filename with the one you got from the IImageListItem
, like this:
if (iiqFile.filename != imageItem.GetFilename())
{
// we got another image than the one we expected
}
if (iiqFile.FileName != imageItem.Filename)
{
// we got another image than the one we expected
}
This comparison will handle the case where the camera is triggered and the transfer of the new capture, coincide with a call to RequestImage
.
Note
In contrast to many other image browsing APIs, there is no synchronous method for getting an IIQ file.
Getting a Preview
Previews are taken from the preview (or thumbnail) present inside the IIQ file. Some Phase One cameras can be configured to not generate previews in IIQ files, in order to increase capture rate - or save power. In such cases, the camera will generate the preview when requested to.
The Preview is always the entire image, there is no cropping and it is set to a fixed pre-determined size, that can not be changed, after it is generated.
Previews can be delivered either as plain RGB bitmaps or as a Jpeg files. Previews stored in IIQ files are always RGB. If you request a Jpeg formatted preview, the camera will always need to encode the Jpeg from the RGB bitmap, before the preview can be sent to you. There is no caching of Jpeg previews.
Use the image id to get a preview from the Camera
class, like this:
std::shared_ptr<IImageBuffer> preview =
camera.GetPreview(imageItem.GetId(),
IImageBuffer::FileType::RGB24);
IImageBuffer preview = camera.GetImagePreview(imageItem.Id,
ImageBufferFileType.RGB24);
The preview is returned as a (shared) pointer to a IImageBuffer
object. This buffer class specifies the image pixel format (RGB24, Jpeg, etc), as well as the image dimensions: width & height.
As you will see in the next section, the IImageBuffer
class is also used to deliver image tiles. Therefore is has a lot properties that is not used when receiving previews.
Getting a Tile
The tiles API allow you to receive cut-outs of an image. Imagine that you are using CameraSDK to write an app that can do zoom and pan on images. Tiles allows you to realize this by letting you request a cropped section of an image, with a scaling factor applied.
In such scenario you would divide the entire image into a grid of sections - called tiles. You then request only the visible tiles, that are in your user’s viewport.
On the other end, you could also use this method to simply get previews of different sizes.
std::shared_ptr<IImageBuffer const> tile = camera.GetTile(
imageItem.GetId(), // the id of the image
xOffset, // the left offset into the image
yOffset, // the top to down offset into the image
tileWidth, // the input width of the tile
tileHeight, // the input height of the tile
.25, // image is scaled to 25%
IImageBuffer::FileType::JPEG // return image format is Jpeg
);
IImageBuffer tile = camera.GetTile(
imageItem.Id, // the id of the image
xOffset, // the left offset into the image
yOffset, // the top to down offset into the image
tileWidth, // the input width of the tile
tileHeight, // the input height of the tile
.25f, // image is scaled to 25%
ImageBufferFileType.JPEG // return image format is Jpeg
);
You use the x
, y
, width
and height
arguments to control any cropping, you would like to apply. All these coordinates are relative to the full image dimensions, before any scaling is applied.
If you apply a scaling factor different form 1.0
, the returned tile will be smaller than the supplied input width and height. E.g. if input width is 1024px, and a scaling of 0.5 is used, the resulting tile will be approximately 512px.
Warning
The image conversion pipeline inside the camera will likely not provide you with the exact crop and dimensions requested. For performance optimizations, it might choose an offset or size, that are a few pixels off the requested.
Do not assume that your image tile has been cropped from the exact location you defined.
To allow you to handle this inaccuracy, the returned IImageBuffer
has properties that specify what exact offset and dimension the image was cropped at.
Rate an image
Images in the camera can be rated from 0 to 5 stars. (0 stars means not-rated.) This allows photographers to mark interesting or high quality captures. Though this feature is most valuable on IQ4 cameras, iXM’s still have the feature.
You can see an image current rating by getting the IImageFileBasicInfo
object for the image. (See Get basic Meta-Data.)
A simple method on the Camera
class allows you to change, set or remove a star-rating:
camera.RateImage(imageItem.GetId(), IImageFileBasicInfo::StarRating::TwoStars);
camera.RateImage(imageItem.Id, StarRating.TwoStars);
The method is asynchronous and will return immediately, meaning before the rating is actually applied in the camera.
To be notified when the new rating is in-effect, listen for the CameraImageEdited
event.
Delete an image
Images present on the cameras storage can be deleted. The deletion is permanent, there is no trash bin-like scheme.
When you delete an image, the IIQ file itself and all other files representing that image is removed from all storage media. This means any associated Jpeg files and any extra copies on SD cards.
To delete an image, call this method on an instance of the Camera
class:
camera.DeleteImage(imageItem.GetId());
camera.DeleteImage(imageItem.Id);
The method is asynchronous and returns immediately. When the deletion is done, a CameraImageRemoved
event is sent.