Display LIF Images in 4V

Convert LIF Image format to a Quad and render it on a QuadView.

As discussed in previous sections, a QuadView requires a Quad Bitmap to render an image in 4V. The Android Media SDK provides support for different image types. In order to render a Leia Image Format or other supported formats like SBS, you need to first decode them and generate viewpoints.

The Leia Android Media SDK provides flexible APIs to convert the different supported image formats. This section provides a step-by-step guide on rendering a Leia Image Format or LIF image using a QuadView.

For this tutorial, you will load a LIF image from your Android project's resource directory, decode it and generate views to obtain a Quad bitmap. You can then display the Quad using the QuadView.

Setup Resources

We will be working with a LIF image in this project. Copy over the following image to your Android project's raw resource directory.

Optionally, you can work with your own LIF image.

Setup Environment

Setup the project by adding the dependency for the Leia Android Media SDK to your project.

Retrieve LIF file

In order to convert a LIF image, we need to retrieve the file from the resource directory as byte[]

Kotlin
Java
Kotlin
val fileInputStream = resources.openRawResource(R.raw.farm_lif)
fileInputStream.use {
val imageBytes = IOUtils.toByteArray(it)
}
Java
try (InputStream fileInputStream = getResources().openRawResource(R.raw.farm_lif)) {
byte[] imageBytes = IOUtls.toByteArray(fileInputStream);
}
  • We open the raw resource as an InputStream using Resources#openRawResource(int res)

  • Convert the input stream to a byte representation using IOUtils

Decode LIF image

After you retrieve the file, you can decode the LIF using the MultiviewImageDecoder to obtain a MultiviewImage instance. A MultiviewImage is a decoded representation of image formats supported by a Leia Light-field device. You can learn about the Multiview Image here.

Kotlin
Java
Kotlin
val fileInputStream = context.resources.openRawResource(R.raw.farm_lif)
fileInputStream.use {
val imageBytes = IOUtils.toByteArray(it)
// Decode LIF image bytes to obtain multiview image
val multiviewImage = MultiviewImageDecoder.getDefault().decode(imageBytes, 1280 * 720)
}
Java
InputStream fileInputStream = getResources().openRawResource(R.raw.farm_lif);
byte[] imageBytes = IOUtls.toByteArray(fileInputStream);
// Decode LIF image bytes to obtain multiview image
MultiviewImage multiviewImage = MultiviewImageDecoder.getDefault().decode(imageBytes, 1280 * 720);
  • The decode() function takes in the byte[] and the number of output resolution pixels as parameters.

  • We will set the output pixels to 1280 x 720 for this tutorial. This ensures that all the decoded view points have the same resolution specified here.

  • The decoder returns null if the file passed in is not an image format supported by the SDK.

Note: The code in this step should be called on a worker thread.

Populate Disparity Maps

The MultiviewImage obtained in the previous step can now be used to generate view points and convert the image to a Quad.

In order to do so, we can use the MultiviewSynthesizer2 to synthesize the MultiviewImage and generate the disparity maps, if required.

Kotlin
Java
Kotlin
// Obtain MultiviewSynthesizer instance
val synthesizer = MultiviewSynthesizer2.createMultiviewSynthesizer(context)
// Populate Disparity maps
synthesizer.populateDisparityMaps(multiviewImage)
Java
// Obtain MultiviewSynthesizer instance
MultiviewSynthesizer2 synthesizer = MultiviewSynthesizer2.createMultiviewSynthesizer(context);
// Populate Disparity maps
synthesizer.populateDisparityMaps(multiviewImage);
  • Obtain the MultiviewSynthesizer2 instance using the MultiviewSynthesizer2.createMultiviewSynthesizer(Context context) function.

  • Generate the disparity maps for the MultiviewImage using MultiviewSynthesizer2#populateDisparityMaps(MultiviewImage).

  • Disparity maps are essential for generating the different view points in a Quad image. Disparity maps will only be populated by this function, if not already present in the MultiviewImage

Note: All steps in this section should be called on a worker thread.

View Synthesis to Quad

Finally, obtain a Quad Bitmap by converting the MultiviewImage to a Quad using the MultiviewSynthesizer2#toQuadBitmap(MultiviewImage) function. This synthesizes the Multiview Image to generate 4 viewpoints and return a Bitmap representing a Quad image.

Kotlin
Java
Kotlin
val quadBitmap = synthesizer2.toQuadBitmap(multiviewImage)
Java
Bitmap quadBitmap = synthesizer2.toQuadBitmap(multiviewImage);

Set Quad in QuadView

You now have the Quad Bitmap which can be used to display the image in 4V using the QuadView.

Kotlin
Java
Kotlin
quadView.setQuadBitmap(quadBitmap)
Java
quadView.setQuadBitmap(quadBitmap);

Build your app

If you followed the steps correctly, you should be able to view the LIF image in 4V in your Android project.

Feel free to refer to the sample project on Github, which performs decoding and view synthesis on a worker thread, while following Android best practices.

Decode using File or Content Uris

In the tutorial above, you learnt how to decode an image using the image bytes[]. However, the MultiviewImageDecodercan also decode files using the File Uri or ContentUris.

You can use this to load LIF images stored on the device's internal storage and decode them directly using their Uri. You can learn more about the different decoding options here.

Kotlin
Java
Kotlin
val contentUri: Uri;
// ..
// Obtain uri of file on device storage
// Decode image using Uri to obtain Multiview Image
val multiviewImage = MultiviewImageDecoder.getDefault().decode(context, contentUri, 1280 * 720)
Java
Uri contentUri;
// ..
// Obtain uri of file on device storage
// Decode image using Uri to obtain Multiview Image
MultiviewImage multiviewImage = MultiviewImageDecoder.getDefault().decode(context, contentUri, 1280 * 720);

In the next tutorial, you will learn how to decode and display a SBS (2x1) image using the QuadView.