Introduction

Welcome to FLIR ONE iPhone app development. This document will introduce you to developing apps with the FLIR ONE external iPhone accessory (aka the FLIR ONE device). Note that this is not to be confused with the FLIR ONE iPhone app (aka the FLIR ONE app).
This document is intended to serve as a quick start guide. It will introduce the developer to all of the important terms and methodologies related to the SDK. This document will help give an overall understanding of how the SDK works. Answers to commonly asked questions are also included.
This Documentation was written for the FLIR ONE SDK – BETA release. Updates to the SDK and documentation will be rolled out soon. For any support questions, contact FLIROneSDK@FLIR.com.

1. Initial Project Setup

System Requirements:

In order to develop using the FLIR One SDK for iOS, you’ll need a Mac with Xcode installed. For testing on physical devices, you’ll need an iPhone 5 or later, running iOS 7.0 or later.

Required external files:

FLIROneSDK.framework
FLIROneSDK.bundle

The required files must be downloaded from FLIR. The steps required to install these files along with any other project dependencies are included below.
These required external files are likely to be provided at the same place as this document. For any support questions, contact FLIROneSDK@FLIR.com.

Optional

sampleframes_hq.bundle

This bundle may be added to the project in order to add a new set of sample frames to the simulator, featuring a higher resolution stream captured by the newer FLIR One device.

Linking Binary with Libraries Requirements

FLIROneSDK.framework
libstdc++.dylib
Accelerate.framework

The above libraries must be added to your project under Build Phases in the section Link Binary with Libraries. FLIROneSDK.framework must be downloaded from FLIR, and libstdc++.dylib is included with Xcode.

There are many ways to add files into your Xcode project. One approach to add the FLIROneSDK.framework file to your project is to open your project in Xcode from the project navigator perspective then drag and drop the required file into your project. It’s advised that you either create a “Frameworks” folder in which to add the framework file, or add the file to the “Supporting Files” subfolder. When prompted be sure to select the option to copy the file into the project so that the required files will be included in the project rather than being linked from some other on-disk location. Ensure that the file was correctly added to the Build Phases section “Link Binary with Libraries”. It should have been added automatically when you dropped it into your project.

The remaining library, libstdc++.dylib is included with Xcode. You can simply add it to your project by pressing the plus sign and typing the name into the search bar then selecting the desired library from the list of results.

Copy Bundle Resources Requirements

FLIROneSDK.bundle

In order to add the FLIROneSDK.bundle to your project, follow the same procedure as noted in the FLIROneSDK.framework requirement above. This file along with any other required files must be downloaded from FLIR. They will likely be provided at the same place as this document. For any support questions, contact FLIROneSDK@FLIR.com

Modifying the Info.plist file:

The following required external accessory protocols must be added to the project info.plist file. To do so, open the Info.plist in Xcode. It can be found in the Supporting Files project folder by default. Add a new information property list to the plist and name it: “Supported external accessory protocols”. In the newly created information property list item, add the three following components:

com.FLIR.rosebud.fileio
com.FLIR.rosebud.config
com.FLIR.rosebud.frame

Setting -ObjC linker flag

Under Build Settings section of the project settings. Search for the settings Other Linker Flags. Modify this option for both debug and release modes to include the flag -ObjC.

2. Getting Up and Running: Streaming Frames

Adding a Delegate

The first step to receiving frames from the FLIR ONE is to register a class as “delegate” to the FLIROneSDKStreamManager. The easiest way to do this is to make sure your main view controller conforms to FLIROneSDKImageReceiverDelegate and FLIROneSDKStreamManagerDelegate protocols.

Once this is done, you can add the view controller to the stream manager’s delegates with:

[[FLIROneSDKStreamManager sharedInstance] addDelegate:self];

Implementing Callbacks and Rendering

In order to receive frames, you’ll have to specify which types of frames you’re interested in receiving. The following formats can be retrieved synchronously at the native framerate of 9 Hz. They are all delivered in row major format, and all can be rendered easily using the [FLIROneSDKUIImage imageWithFormat:andData:andSize:] method.

Blended MSX RGBA 8888
Thermal RGBA 8888
14-Bit Linear Flux
Radiometric Kelvin x 100
Visual JPEG
Visual YCbCr

Blended MSX RGBA 8888

This format is a combination of visual and thermal components, delivered as a 480×640 portrait image, row major, of 4 byte RGBA pixels. It cannot be used in tandem with Thermal RGBA 8888

Thermal RGBA 8888

This format is purely the thermal component of the MSX format, and is delivered in much the same way. It cannot be used in tandem with Blended MSX RGBA 8888

14-Bit Linear Flux

This format is composed of 14 bit pixels, row major and little endian, each representing a value read from the thermal sensor. The data is portrait orientation.

Radiometric Kelvin x 100

This format is much like the 14-Bit Linear Flux format, except that the values are in units of degrees Kelvin, multiplied by 100. In order to extract a temperature value from a scene, you must use this format, and divide the pixel’s temperature value by 100 to get units in Kelvin.

Visual YCbCr

This format is the visual data from the camera, adjusted to better align with the thermal stream, and is in portrait orientation. The data is row major, with each pixel composed of Y, Cb, and Cr bytes.

Visual JPEG

This format is raw jpeg data, landscape orientation, and has not been adjusted to align with the thermal camera in any way.

Specifying Image Options

In order to receive frames in the formats you desire, you must first set the image options property of the Stream Manager:

[FLIROneSDKStreamManager sharedInstance].imageOptions = FLIROneSDKImageOptionsBlendedMSXRGBA8888Image;

You may also use the | character to combine multiple formats, with the exception of Blended MSX RGBA and Thermal RGBA.

Next, implement the FLIROneSDKDelegateManager:didReceiveBlendedMSXRGBA8888Image:imageSize: delegate method. This method is called at 9hz when the [FLIROneSDKStreamManager sharedInstance].imageOptions flag includes FLIROneSDKImageOptionsBlendedMSXRGBA8888Image.

Here’s an example implementation of the FLIROneSDKDelegateManager:didReceiveBlendedMSXRGBA8888Image:imageSize: delegate method. It uses the [FLIROneSDKUIImage imageWithFormat:andData:andSize:] convenience method to render delivered frame data data into a usable UIImage subclass.

- (void)FLIROneSDKDelegateManager:(FLIROneSDKDelegateManager *)delegateManager didReceiveBlendedMSXRGBA8888Image:(NSData *)msxImage imageSize:(CGSize)size {

    //render the image    
    UIImage *image = [FLIROneSDKUIImage imageWithFormat:FLIROneSDKImageOptionsBlendedMSXRGBA8888Image andData:msxImage andSize:size];

    //perform ui update on main thread
    dispatch_async(dispatch_get_main_queue(), ^{
        self.imageView.image = image;
    });
}

Selecting a Palette

When streaming, you can specify a palette to use by setting the FLIROneSDKStreamManager’s palette property to any valid FLIROneSDKPalette object. A dictionary of available palette objects can be accessed with [FLIROneSDKPalette palettes].

3. Using the FLIROneSDK, delegation and using delegates

Each iPhone app must register one or more delegates of the FLIROneSDKStreamManager to receive events from the FLIR ONE device. Any number of objects that comply with the FLIROneSDKStreamManagerDelegate and FLIROneSDKImageReceiverDelegateprotocols may register to receive events from the FLIROneSDK. The following FLIROneSDKStreamManager method is used to add a delegate.

[[FLIROneSDKStreamManager sharedInstance] addDelegate:self]; //the FLIROneSDKStreamManager is accessed as a shared instance because it is a thread-safe singleton object.

Note: The FLIROneSDK keeps track of registered delegates in a set. For this reason an object is added more that once as a delegate, subsequent attempts will have no effect.

The set of SDK delegates will handle all of the interaction between the FLIR ONE device and the iPhone app. There are no required methods, but there are a number of recommended methods to implement. Without the following methods, the application will not be able to receive frames from the FLIR ONE device. The specific list of responsibilities can be found in the SDK documentation included with the FLIR ONE framework in Xcode.
Recommended delegate methods briefly discussed:

Connecting and Disconnecting the FLIR ONE device

- (void)FLIROneSDKDidConnect
- (void)FLIROneSDKDidDisconnect

The above SDK delegate methods should be implemented to control the application as desired when the FLIR ONE device is connected and disconnected. When the FLIR ONE device is connected an application should set a flag that it is in the connected state such as the following:
self.connected = YES;
Similarly the flag should be turned off when the FLIR ONE device is disconnected. Note that all UI updates should be done on the main thread to insure good application performance.

Streaming Frames

- (void)FLIROneSDKDelegateManager:(FLIROneSDKDelegateManager *)delegateManager didReceiveFrameWithOptions:(FLIROneSDKImageOptions)options metadata:(FLIROneSDKImageMetadata)metadata

For streaming frames to the iPhone you should implement the above FLIROneSDKDelegateManager:didReceiveFrameWithOptions:metadata: method. This method will get called every time a frame is sent from the FLIR ONE device to the iPhone. See the section below on streaming frames to the application. Note that the callbacks will not be performed on the UI thread, and as such, you will need to perform UI updated on the main thread instead of on the callback thread.

4. Tuning the FLIR ONE device (Original FLIR One Only)

What is Tuning?

Tuning is a quick recalibration process of the IR camera in the FLIR ONE device that requires user interaction. Tuning is required by the IR camera on a regular basis because the properties of the IR camera change in time based upon its internal temperature and other factors. For this reason tuning, and therefore user interaction, is required whenever the FLIR ONE device determines that the IR properties have drifted by too much from the previous tuning. The user will tune the FLIR ONE device by pulling down on the shutter on the back of the FLIR ONE device. This will pull down a shutter over the IR and visible cameras and allow the FLIR ONE device to re-tune itself. The tuning process should only require between 1 and 5 seconds. During the tuning process, the FLIR ONE device will perform a calibration called a flat field calibration (FFC).

How to present tuning in the application

Tuning requires the user to take action and pull down on the FLIR ONE device shutter. For this reason, the user must be presented with a cue to begin the tuning process. The tuning process begins when the delegate method FLIROneSDKTuningStateDidChange is called with the tuning state FLIROneSDKTuningStateTuningRequired. The tuning process is finished when the delegate method is called with a state of FLIROneSDKTuningStateTunedWithClosedShutter. At this point the calibration is complete and the user should be asked to release the shutter. Finally, when the user releases the shutter and the required user interaction has ended, the delegate method will be called with the state FLIROneSDKTuningStateTunedWithOpenedShutter. At this point, the tuning view can be dismissed and the application can resume normal usage.

In addition to required tuning, there is an optional tuning request. This occurs when the following delegate method is called with a tuning state of FLIROneSDKTuningStateTuningSuggested.

- (void)FLIROneSDKTuningStateDidChange:(FLIROneSDKTuningState)newTuningState

This optional tuning request means that the FLIR ONE device has determined its calibration state is no longer optimal. Valid frames are still being returned, however the temperature reading should no longer be considered trustworthy. It is recommended to pass the information along to the user via UI cues suggesting that they re-tune their FLIR ONE device. This is optional depending on the use case of the application it may be completely ignored. If high quality IR data is required, it is recommended to require tuning in this state.

Note: All updates to the UI must be done on the main thread of the application for best results.

Using the tuning view included in the SDK

The SDK includes a convenient tuning view FLIROneSDKTuning, which handles all of the required tuning states. In order to use this tuning view it is necessary to have a top view controller that implements the FLIROneSDKDelegate protocol. This FLIROneSDKDelegate must implement the FLIROneSDKTuningStateDidChange method as shown below. In this implementation some logic must be included for how to handle the various values of newTuningState. See the example project included with the SDK for an example implementation of this logic. Note that all UI updates must be made on the main thread.

The TuningStateDidChange method is called every time the tuning state of the FLIR ONE device changes. This includes any time the user changes the state of the shutter, or anytime the quality of the IR data from the FLIR ONE device starts to become in adequate. Within this method it is necessary to implement special cases for most of the states of FLIROneSDKTuningState that will be responsible for updating the user interface with the required queues for the user to tune their FLIR ONE device.
Note: All updates to the UI must be done on the main thread of the application for best results. If using the built in tuning view included in the SDK, all interaction with this class must be done on the main thread.

The possible tuning states are as follows:

  • FLIROneSDKTuningStateTuningRequired – The camera must be tuned right now for it to resume streaming frames from the FLIR ONE device. This state requires the user to tune the device by pulling down on the shutter.
  • FLIROneSDKTuningStateInProgress – The camera is in the process of being tuned but has not yet finished. This state indicates that the user has pulled down on the shutter and the camera has begun the tuning process. The user should be informed via the UI that the tuning process has started and that they should not yet let go of the shutter.
  • FLIROneSDKTuningStateTunedWithClosedShutter – The camera has been tuned and the user should release the shutter handle. This state indicates that the tuning process is finished. The user should be informed via the user interface that they should release the handle. It is also a good idea to implement an iPhone vibrate to help inform the user that the tuning is complete.
  • FLIROneSDKTuningStateApproximatelyTunedWithOpenedShutter – The user has release the shutter handle, and the tuning interface should be dismissed. However, the IR camera is still warming up. This state should only occur in the first 1-2 minutes after starting up the FLIR ONE Camera. When the camera is warmed up and retuned, the tuning state returned will be FLIROneSDKTuningStateTunedWithOpenedShutter. Users should be informed that temperature readings from the camera should not yet be trusted as accurate.
  • FLIROneSDKTuningStateTunedWithOpenedShutter – The user has released the shutter handle, and the tuning interface should be dismissed. Temperature readings can now be trusted as accurate until tuning is requested again.
  • FLIROneSDKTuningStateTuningSuggested – The camera is requesting, but not demanding, that the user pull down the handle to retune. At this time it is optional for the user to retune the camera. If the application requires the highest quality IR data, it is a good idea to require tuning at this state.
    Editing images after collection:
    There are several delegate methods for use with loading, editing and saving images after collection using the FLIROneSDKImageEditor shared instance. Refer to the FLIROneSDK documentation in Xcode for details.

NOTE: The tuning view will handle tuning events, but will not handle Connection and Disconnection events of the device. You must implement your own logic and UI to ask the user to connect the FLIR ONE device.

The built in tuning view controller is called like so:

//id <FLIROneSDKStreamManagerDelegate> is an object that conforms to the FLIROneSDKStreamManagerDelegate protocol 
[id <FLIROneSDKStreamManagerDelegate> presentWithViewController:(UIViewController *)viewController withTuningState:(FLIROneSDKTuningState)tuningState]

In the method call shown above id <FLIROneSDKStreamManagerDelegate> would be replaced with an object that complies with the FLIROneSDKStreamManagerDelegate protocol (likely the top view controller). Also, the first argument, viewController should be the top view controller of the application. In the case where this viewController is also the SDK delegate then the value of (UIViewController *) viewController would simply be self.

A working implementation of the FLIROneSDKTuningStateDidChange method should keep track of if the tuning view has already been presented. If the tuning view has not yet been presented and one of the following events is received, the tuning view should be presented: TuningSuggested (optional), TuningRequired, InProgress, and TunedWithShutterClosed. The tuning view will automatically dismiss itself when tuning is completed. Your application logic can assume that the tuning view will be dismissed when the FLIR ONE device disconnects, or if the tuning state changes to TunedWithOpenedShutter.
Warning: You must not present the FLIROneSDKTuningViewController if it is already presented or the application may crash.

Warning: If using the built in tuning view included in the SDK, all interaction with this class must be done on the main thread.

Note: Because this method will present a tuning view controller modally, all function of the application will be blocked while the tuning process is happening. This will block the user from using other functionality of the application if the FLIR ONE device is disconnected or out of power. For this reason, if your app has any functionality that does not require the use of the FLIR ONE device, such as viewing or editing collected photos, it is recommended to make your own less intrusive view controller.

5. Saving Images and Video to Disk

Image and video collection is handled by the class FLIROneSDKStreamManager. A photo is captures simply by calling the following method:

[FLIROneSDKStreamManager capturePhotoWithFilepath:];

This will capture the current frame from the FLIR ONE device and save it disk as a jpeg. The FLIROneSDKStreamManager’s delegates will receive a callback when the photo is captured, indicating the success or failure of this operation.

6. Managing and editing media collected by the application

It is important to allow the user a way to view, edit, and delete all media collected by the FLIR ONE device. The ideal way to do this is with a media library.

What is the media library?

The media library is a way for the application to present a collection of images and videos the application has collected. From the library a user should be able to see a preview of all of the images or videos they have collected. At a minimum the user should be able to view images or videos collected and should be able to delete files from the library. It would also be great to allow your user a way to edit images. All of these features can be implemented with the help of two SDK classes, FLIROneSDKLibraryManager and FLIROneSDKImageEditor.

The LibraryManager contains all of the functionality needed to get the filepaths of media collected by your application and saved to disk.

The ImageEditor implements all of the functionality needed to access a single image by filepath, edit it, copy it, and save changes. Editing supported by the ImageEditor includes changing the current color palette of an image and editing emissivity. The Image Editor can also re-render the saved image with updated palette, as well as providing data in any of the supported media formats, including radiometric temperature array.

How to implement a media library

The easiest way to implement a media library is to get the entire list of file paths associated with the application and add a UICollectionViewCell or UITableViewCell for each to a collection view or table view. Each cell of this collection view should show a preview image of the media collected (image or video) and the cell should also keep track of the file path associated with that cell.

The SDK contains UI elements which allow developers to quickly set up a library interface. In order to add images to this premade library, developers should use the following two methods:

[[FLIROneSDKLibraryManager sharedInstance] mediaPath]
[[FLIROneSDKLibraryManager sharedInstance] libraryFilepathForCurrentTimestampWithExtension:]

mediaPath returns a NSURL pointing to the folder where media should be added to the library.

libraryFilepathForCurrentTimestampWithExtension: returns a filepath with the supplied extension (“png” or “mov”, usually) within the media folder.

This filepath should be used with the following methods for capturing media:

[[FLIROneSDKStreamManager sharedInstance] capturePhotoWithFilepath:]
[[FLIROneSDKStreamManager sharedInstance] startRecordingVideoWithFilepath:withVideoRendererDelegate:]

If an image is captured to a location other than the media folder, and you wish to add the image to the library later, you may use the following method:

[[FLIROneSDKLibraryManager sharedInstance] copyImageToLibraryWithFilepath:withThumbnailFilepath:]

A list of file paths can be accessed from the LibraryManger via its property:

@property (readonly, nonatomic, strong) NSArray *filepaths;

A preview image can be accessed like so:

UIImage *previewImage = [[FLIROneSDKLibraryManger sharedInstance]  thumbnailForFilepath: mediaFilepath];

When you want to edit a file, you can use the image editor to load the file’s data into memory, allowing it to be edited and re-rendered in any data format desired (visual JPEG, YCbCr, thermal, etc).

//load an image into the editor
[FLIROneSDKImageEditor sharedInstance]loadImageWithFilepath:];

When the user makes and edit such as changing the color palette, this change would be confirmed using the following FLIROneSDKImageEditor method:

[FLIROneSDKImageEditor sharedInstance] setPalette: [[FLIROneSDKPalette palettes] objectForKey: "Iron"]]; //iron is the name of a palette

This method will asynchronously render a new image with the desired palette and return that result in the FLIROneSDKDelegate method, FLIROneSDKEditorImageDidChange:.
See the SDK documentation on FLIROneSDKImageEditor and FLIROneSDKLibraryManager for a complete list of methods they implement.
How to use the SDK’s built in media library
The SDK comes with a convenient pre-packaged Library View. This view will show a preview image of all images and videos sorted by date taken in a UICollectionView. Images and videos can be shared, deleted, or viewed individually. Images may be edited including rotation, changing of color palettes, and cropping.

To include this library view in your project simply call the following FLIRRosebudSDKLibraryViewController method passing in the current view controller when you want to present the library view.

+ (void) presentLibraryFromViewController:(UIViewController *)viewController;

7. Accessing images from disk

Images should be accessed from disk using the FLIROneSDKImageEditor. The image editor takes in a filepath of an image saved by the FLIROneSDKStreamManager and renders an image using the color palette and emissivity that were set when the image was saved. The filepaths of all images saved by the SDK can be accessed using the FLIROneSDKLibraryManager. Additional details can be found in the section on how to implement a media library.

In order to receive image data for an image stored on disk, first set the imageOptions property of the FLIROneSDKImageEditor sharedInstance appropriately.
For instance, if you wish to receive an image’s visual and MSX-blended components, use:

[FLIROneSDKImageEditor sharedInstance].imageOptions = FLIROneSDKImageOptionsBlendedMSXRGBA8888Image | FLIROneSDKImageOptionsVisualJPEGImage;

This means that when a new image is loaded, the delegates will receive two callbacks each, in addition to the standard “ImageRecieved” callback.

Additionally, make sure you have a delegate ready to receive the image data. This can be accomplished with:

[[FLIROneSDKImageEditor sharedInstance] addDelegate:someDelegate];

The image editor is capable of changing the color palette and emissivity. When the image changes are ready to be saved, the FLIROneSDKImageEditor method below should be used.

- (void)finishEditingAndSaveCurrentImageToFilepath:(BOOL)filepath withPreviewImage:(UIImage *)previewImage;

The above method takes a NSURL filepath specifying the location where the image should be saved. Supply the same filepath as was used to load the image if an in-place save is desired. The method also takes an argument for a preview image, which will be saved as the “visible” portion of the jpeg, as well as for generating the thumbnail file for the image. If nil is supplied, it will use the MSX image as a preview image.

8. Sharing and uploading data

The SDK allows developers to quickly share thermal images and video to the camera roll or online using the SDK’s included share activity UI. Simply call the following method with the file path of the desired items to share:

[FLIROneSDKShareActivity presentActivityViewControllerWithFilepaths:(NSArray *)filepaths withViewController:(UIViewController *)viewController];

9. Common pitfalls and questions

How are images saved?

Radiometric images are images saved as “fat jpegs” on disk. These images are saved with all of the meta-data required to reconstruct the radiometric data. This radiometric data includes the ability to read the temperature of a pixel at a given point and the ability to change the color palette and set the rotation. Keeping this data intact is desired for use with FLIR Tools: For iPhone, For OS X. The FLIR Tools application allows users extract advanced temperature readings from radiometric jpegs. Currently radiometric jpegs can be imported to the FLIR Tools application from the iPhone or shared from within an SDK using application via email. See documentation on sharing and uploading data.

How to edit an image?

Images can always be edited and saved via standard IOS methods for interacting with a UIImage. A UIImage is easily accessible from an incoming frame via the uiImage property of every frame.

In order to take advantage of radiometric data, it is recommended to capture images using the FLIROneSDKStreamManager. These images can be loaded, edited, and saved using the FLIROneSDKImageEditor class included in the SDK. This class allows editing and saving of images in a way that preserves the radiometric data. Preserving the radiometric data is ideal for use with the FLIR Tools application.

In order to load an image using the FLIROneSDKImageEditor, the image must have been saved using the FLIROneSDKStreamManager capturePhotoWithFilepath: method.

Current functionality of the FLIROneSDKImageEditor class includes the following.
The image editor can:
* Change the color palette of an image
* Change the emissivity of an image

Why am I not getting live streamed images

  • Are the project dependencies installed correctly?
  • Did you add the required Supported external accessory protocols to Info.plist?
  • Have you added a delegate via: [[FLIROneSDKStreamManager sharedInstance] addDelegate:someDelegate];?
  • Are the appropriate delegate methods implemented?
    a. See the above section on delegates and delegation for information about important delegate methods to implement.
    b. If tuning is required, frames will not be streamed to the iPhone until tuning takes place. It is important to implement the basic delegate methods for tuning.
  • Have you set the appropriate image options? The default value is [FLIROneSDKStreamManager sharedInstance].imageOptions = FLIROneSDKImageOptionsBlendedMSXRGBA8888Image
    For further questions contact FLIROneSDK@FLIR.com for support.

Why am I getting crashes or inconsistent behavior using the FLIROneSDKTuningViewController?

The FLIR ONE SDK takes advantage of multi threaded programming practices. For this reason, it is important to perform all UI updates on the main queue of the application. This includes presenting of the FLIROneSDKTuningViewController.

Additionally your application must keep track of if the tuning view controller has already been presented. While it is presented, the app should not attempt to present it again or it may lead to a crash.

The FLIROneSDKTuningViewController is not intended to prompt the user to connect their FLIR ONE device, and the tuning view controller will immediately disconnect itself if the device is disconnected from the device. For this reason, your application must first prompt the user to connect and ensure that connection has taken place before presenting the tuning view controller.

How do I get the temperature out of the pixels?

In order to get the temperature of a pixel, you’ll need to add FLIROneSDKImageOptionsThermalRadiometricKelvinImage to the image options. Once you receive an array in this format, you can use the width and height supplied to find the value of a particular pixel in this array. The values represent degrees Kelvin * 100. For example, the value 273.15ºK is represented by 27,315.

How do I change the color palette of an image?

The color palette of an image is a standard property of every frame. This value can be set during streaming via the FLIROneSDKStreamManager. This property can also be edited post collection via FLIROneSDKImageEditor.

How do I get information about the FLIR ONE device battery level?

Although it is completely optional it is a good idea to inform your user of the power level of the FLIR ONE device. Changes in the battery level will be passed to all FLIROneSDKDelegate objects implementing the optional protocol method:

- (void) FLIROneSDKBatteryPercentageDidChange:(NSNumber *)percentage;

When the status of the charging state changes the new state of the FLIR ONE device (plugged in or not) will be passed to all FLIROneSDKDelegate objects implementing the optional protocol method:

- (void) FLIROneSDKBatteryChargingStateDidChange:(FLIROneSDKBatteryChargingState)status;

What is FLIR Tools?

FLIR Tools is an application developed by FLIR for use with Mac OS X or iPhone. The FLIR Tools application allows users extract advanced temperature readings from radiometric jpegs. Currently radiometric jpegs can be imported to the FLIR Tools application from the iPhone or shared from within an SDK using application via email. See documentation on sharing and uploading data.