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: P100056.IIQ

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.