I'm working now on an app that has TONS of features, and will be light-years beyond even the FLIR One SDK sample app. It's about 95% done now. It is called "FOne Ultimate". I would have called it "FLIR One Ultimate", except that would probably get me sued by FLIR for violating their trademark.
It outputs 16bit grayscale TIF files for Raw14bit thermal, and radiometric centikelvin-scale thermal images
It outputs 32bit RGB BMP files for thermal IR (aligned and cropped) image, MSX (aligned and cropped) image, and visible light (aligned and cropped) image.
The only format that it saves as a compressed JPG file is the full size (not cropped) visible light JPEG image.
It correctly rotates all of the image formats (except the JPEG format) to be aligned with the orientation you are holding your phone (portrait, reverse portrait, landscape, or reverse landscape). I have yet to figure out how to properly have the FLIR One SDK's FrameProcessor object correctly rotate any of the FLIR One image formats (raw or JPEG) at all, but have my own function for rotating the images when they provide you with the raw bytes of image data (anything that I can save as TIF or BMP), which is available for all formats except the visible light JPEG image, hence the reason I cannot correctly rotate that image. You will need to provide your own image editing software to correctly rotate that image, unless I find another way to do it.
The 16bit grayscale TIF and 32bit BGRX BMP saving functions are my own, as neither FLIR One SDK, nor Android SDK have functions that allow me to save BMP or TIF files. I also had to create my own byte-swapping functions, as the BMP specification calls for little endian-byte order for all multi-byte values, and of course the Android system uses big-endian multi-byte values. Also I had to write my own red-blue channel swapper for this, as BMP files are stored with the blue channel first, rather than the red channel.
I also used the endian byte swapping functions to create little-endian TIF files (even though the TIFF specification also allows for big-endian), as the app is intended to be a thermal data-gathering platform for Android, but with the idea that the captured files will be used on a desktop or laptop PC (which of course are little-endian systems). Any TIF writer software I write for the PC is going to be written with the intent of using it with these thermal image files, and don't plan to create the extra overhead of making my PC TIF reading software capable of handling both big and little endian TIF files (though the official TIFF specs say readers need to be able to do both). In light of this fact that I won't be doing any byte-swapping at the TIF file reader end of things, I need to perform byte-swapping at the TIF file writer end of things.
And then there's one more feature that my app provides that NO OTHER app for the FLIR One yet provides. This is the ability to record a video that can handle even 16bits per pixel frames. The official FLIR One app can save MP4 video, but (at least on my phone) it lags SO BAD after a couple seconds that the video I'm seeing 1 minute after the recording started represents events that happened about 10 seconds after the recording started, and to see events that happened about 20 seconds after the recording started, I have to wait about 2 minutes for the preview screen to catch up. Yep, it's THAT MUCH of a lag. I think the problem is the time it takes to compress a frame means the CPU can't display anything while it's running the MPEG4 compressor (maybe they didn't implement multithreading correctly or something). Maybe my phone is just slow, but even then, MPEG4 has a big problem. It DOES NOT SUPPORT 16bits per pixel frames.
My app does not have either problem. It doesn't use another thread for frame writing, but it still has NO LAG, and this is because it doesn't waste time performing MPEG4 compression on the frames. Instead it writes all of its frames by saving the raw pixel data directly to the file. And this also means that unlike with MPEG4 it CAN handle 16bits per pixel images that are needed to hold the raw thermal data for the raw14bit images and the centikelvin thermal images. How does it do this? Well it's pretty simple actually. I invented my own video file format. I call it Ben's Video Format, and files saved in this format have a .bvf file extension. Unlike AVI files, which have quite a complicated structure, BVF video files have a MINIMAL HEADER. The structure of the header is simple (note that all multi-byte values are, once again, in little-endian byte order,) and is as follows:
ascii string FileID (this should always be "BVF ", and that's a space at the end, not a null character, as it's a 4byte fixed-length string)
int FrameWidth
int FrameHeight
short ChannelsPerPixel (valid values are 1, 3, or 4)
short BytePerChannel (valid values are 1 or 2)
int FrameCount
short FrameRateNumerator (this should always be 88 (58 hex) for FLIR One video
short FrameRateDenominator (this should always be 10 (0A hex) for FLIR One video)
int Reserved (this may be used in future versions of this file format for extending the header)
After this comes all the raw uncompressed bytes of the frames sequentially stored in the file. Unlike AVI there is no index to look up frame position. As it's all stored as uncompressed pixel data, you can easilly calculate the location in the file for any given frame by simply knowing the frame number you want, and the width, height, bytes per channel, and channels per pixel. All this information can be gotten in the header, and can be used during playback to easily calculate the size and offset of an uncompressed frame during playback. No need to waste space in the file generating an index. And as it doesn't need to waste time saving an index, that made it a LOT easier to program, as I don't need to figure out how to write the necessary code to store an index separately as the frames are being written, and then concatenate the index to the end of the file as is done with AVI files. Not only is it simpler in concept, and able to handle many 16bit's per pixel grayscale frames (which even AVI can't handle, despite its complexity) it's also MUCH easier for a developer to write software for than it is with AVI files. And if you want to have an index, a playback application can easily use the format information stored in the header to generate an in-memory index when the file is loaded, and then use this index during playback and/or seeking. As for supported pixel formats, they are as follows:
8bits per pixel grayscale (1chan-per-pix and 1byte-per-chan)
16bits per pixel grayscale (1chan-per-pix and 2-bytes-per-chan)
24bits per pixel RGB(3chans-per-pix and 1byte-per-chan)
48bits per pixel RGB(3chans-per-pix and 2bytes-per-chan)
32bits per pixel RGBX(4chans-per-pix and 1byte-per-chan)
64bits per pixel RGBX(4chans-per-pix and 2bytes-per-chan)
Note that with 4 channels the 4th channel is not actually alpha channel, and is simply ignored, which is why it's designated as X (unused), not A (alpha).
Note that of these 6 pixel formats that my BVF format supports, only 2 of them are used by my FLIR One app. These are 16bits per pixel grayscale, and 32bits per pixel color.
Currently in conjunction with this thermal app, I've also created my own PC application, using VB6, that can play these BVF video files. I'll describe the features of this player when I release it, which will be at the same time as I release my app.
And then there's a neat remote control feature in this app. I just finished working on that feature a couple days ago (been working on the app for about a month). This feature allows you to use your laptop or desktop PC to control the thermal imager app. It works by sending 5-character ascii commands over UDP protocol over a LAN to your smartphone. A Windows application that will actually issue these commands is something that I'm currently working on in VB6.
Then there's one more feature I'd like to add to my app, and I will start working on that next. That is streaming frames from the app over a TCP connection back to a desktop or laptop PC, so that when it is all done, my fully featured app will allow complete remote operation of the FLIR One device. In effect, this will turn any Android phone with the FLIR One device into a PC operated thermal imager, just like some of the very high end FLIR thermal images that cost thousands of $$$$. In security operations, it could be used as a LWIR nightvision security camera to see intruders in complete darkness, where it could be monitored and recorded by a DVR or security guard, just like a regular security camera. In industry, it could be used to remotely monitor the temperature of processes occurring in a machine in a factory.
Once I've finished and released this Android app, expect it to be followed by PC applications that take advantage of its remote control and frame streaming features.