Image Util: Encoding, Decoding, and Transforming Images
This tutorial demonstrates how you can convert, resize, rotate, and crop an image, and decode and encode a JPEG image.
Warm-up
Become familiar with the Image Util API basics by learning about:
-
Initializing Image Utilities
Initialize the image utilities for use.
- Image manipulation
-
Converting the Color Space
Convert an image from one color space to another.
-
Resizing an Image
Resize an image.
-
Rotating an Image
Rotate an image.
-
Cropping an Image
Crop an image.
-
Converting the Color Space
-
Decoding from a File or Memory
Decode a JPEG image from a file or memory.
-
Encoding to a File or Memory
Encode raw image data to a JPEG file or to memory in JPEG format.
Initializing the Image Utilities
To initialize image utilities:
-
To use the functions and data types of the Image Util API (in mobile and wearable applications), include the <image_util.h> header file in your application:
#include <image_util.h>
-
Declare the required variables:
#define SAMPLE_FILENAME "sample_image.jpg" #define OUTPUT_ROTATED_JPEG "rotated_image.jpg" const image_util_colorspace_e colorspace = IMAGE_UTIL_COLORSPACE_RGB888; unsigned char *img_rotate_target = NULL; unsigned char *img_source = NULL; int ret = 0; int width = 0, height = 0; unsigned int size_decode = 0;
-
To ensure that a function has been properly executed, always check its return value. If the return value is different from IMAGE_UTIL_ERROR_NONE, an error has occurred.
The Image Util API supports the following color spaces defined in the image_util_colorspace_e enumerator:
IMAGE_UTIL_COLORSPACE_YV12, // YV12 - YCrCb planar format IMAGE_UTIL_COLORSPACE_YUV422, // YUV422 - planar IMAGE_UTIL_COLORSPACE_I420, // YUV420 - planar IMAGE_UTIL_COLORSPACE_NV12, // NV12- planar IMAGE_UTIL_COLORSPACE_UYVY, // UYVY - packed IMAGE_UTIL_COLORSPACE_YUYV, // YUYV - packed IMAGE_UTIL_COLORSPACE_RGB565, // RGB565, high-byte is Blue IMAGE_UTIL_COLORSPACE_RGB888, // RGB888, high-byte is Blue IMAGE_UTIL_COLORSPACE_ARGB8888, // ARGB8888, high-byte is Blue IMAGE_UTIL_COLORSPACE_BGRA8888, // BGRA8888, high-byte is Alpha IMAGE_UTIL_COLORSPACE_RGBA8888, // RGBA8888, high-byte is Alpha IMAGE_UTIL_COLORSPACE_BGRX8888, // BGRX8888, high-byte is X IMAGE_UTIL_COLORSPACE_NV21, // NV12 - planar IMAGE_UTIL_COLORSPACE_NV16, // NV16 - planar IMAGE_UTIL_COLORSPACE_NV61, // NV61 - planar
To find out which color spaces are encoded, use the image_util_foreach_supported_jpeg_colorspace() function:
int image_util_foreach_supported_jpeg_colorspace(image_util_supported_jpeg_colorspace_cb callback, void * user_data);
For more information about the YUV color space, see http://www.fourcc.org/yuv.php.
-
The image_util_transform_run() function used for all image transformations needs the media_packet_h parameter. Create it by setting the source image:
ret = image_util_decode_jpeg(SAMPLE_FILENAME, colorspace, &img_source, &width, &height, &size_decode); ret = media_format_create(&fmt); ret = media_format_set_video_mime(fmt, colorspace); ret = media_format_set_video_width(fmt, width); ret = media_format_set_video_height(fmt, height); ret = media_packet_create_alloc(fmt, NULL, NULL, &src); ret = media_packet_get_buffer_size(src, &size); src = malloc(size); ret = media_packet_get_buffer_data_ptr(src, &src_ptr); ret = memcpy(src_ptr, img_source, size);
Converting the Color Space
To convert an image from one color space to another:
- Create a transform handle to support the conversion.
The transform is related and limited to image processing, such as converting, resizing, rotating, and cropping.
transformation_h handle; ret = image_util_transform_create(&handle);
-
To use hardware acceleration, enable it using the image_util_transform_set_hardware_acceleration() function:
ret = image_util_transform_set_hardware_acceleration(handle, true);
Even though you use hardware acceleration, you can set the output format with the image_util_transform_set_colorspace() function:
ret = image_util_transform_set_colorspace(handle, colorspace);
-
After creating the transform_h handle and setting the output property, execute the transform using the image_util_transform_run() function.
You can use the image_util_transform_completed_cb callback for handling the function results.
ret = image_util_transform_run(handle, src, (image_util_transform_completed_cb)completed_callback, user_data);
Note - The function only converts the color space. It does not change the image width or height.
- Because of the restrictions of the image processing library, not all color space combinations are supported for conversion. For example, the NV12 format is commonly used in hardware chips, but it is not supported by the library.
- If the hardware acceleration is enabled, you can execute 2 more image processings using just the created handle.
-
When the callback confirms that the transform is completed, call the image_util_transform_destroy() function:
ret = image_util_transform_destroy(handle);
Resizing an Image
To resize an image:
-
Create a transform handle to support resizing.
The transform is related and limited to image processing, such as converting, resizing, rotating, and cropping.
transformation_h handle; ret = image_util_transform_create(&handle);
-
To use hardware acceleration, enable it using the image_util_transform_set_hardware_acceleration() function:
ret = image_util_transform_set_hardware_acceleration(handle, true);
Even though you use hardware acceleration, you can set the output resolution with the image_util_transform_set_resolution() function.
ret = image_util_transform_set_resolution(handle, width, height);
-
After creating the transform_h handle and setting the output property, execute the transform using the image_util_transform_run() function.
You can use the image_util_transform_completed_cb callback for handling the function results.
ret = image_util_transform_run(handle, src, (image_util_transform_completed_cb)completed_callback, user_data);
Note - Since the source format is the same as the target format, you can ignore the format.
- If the color space is YUV, the target image width and height must be multiples of 8. This restriction does not apply to the RGB images.
- If the hardware acceleration is enabled, you can execute 2 more image processings using just the created handle.
-
When the callback confirms that the transform is completed, call the image_util_transform_destroy() function:
ret = image_util_transform_destroy(handle);
Rotating an Image
To rotate an image:
-
Create a transform handle to support rotating.
The transform is related and limited to image processing, such as converting, resizing, rotating, and cropping.
transformation_h handle; ret = image_util_transform_create(&handle);
-
To use hardware acceleration, enable it using the image_util_transform_set_hardware_acceleration() function:
ret = image_util_transform_set_hardware_acceleration(handle, true);
Even though you use hardware acceleration, you can set the rotation property with the image_util_transform_set_rotation() function:
ret = image_util_transform_set_rotation(handle, rotation);
The possible values for the rotation parameter are:
- IMAGE_UTIL_ROTATION_NONE
- IMAGE_UTIL_ROTATION_90
- IMAGE_UTIL_ROTATION_180
- IMAGE_UTIL_ROTATION_270
- IMAGE_UTIL_ROTATION_FLIP_HORZ
- IMAGE_UTIL_ROTATION_FLIP_VERT
-
After creating the transform_h handle and setting the output property, execute the transform using the image_util_transform_run() function.
You can use the image_util_transform_completed_cb callback for handling the function results.
ret = image_util_transform_run(handle, src, (image_util_transform_completed_cb)completed_callback, user_data);
Note - Since the source format is the same as the target format, you can ignore the src_format.
- If the color space is YUV, the target image width and height must be multiples of 8. This restriction does not apply to the RGB images.
- If the hardware acceleration is enabled, you can execute 2 more image processings using just the created handle.
-
When the callback confirms that the transform is completed, call the image_util_transform_destroy() function:
ret = image_util_transform_destroy(handle);
Cropping an Image
To crop an image:
-
Create a transform handle to support cropping.
The transform is related and limited to image processing, such as converting, resizing, rotating, and cropping.
transformation_h handle; ret = image_util_transform_create(&handle);
-
To use hardware acceleration, enable it using the image_util_transform_set_hardware_acceleration() function:
ret = image_util_transform_set_hardware_acceleration(handle, true);
Even though you use hardware acceleration, you can set the cropped property with the image_util_transform_set_crop_area() function:
ret = image_util_transform_set_crop_area(handle, start_x, start_y, end_x, end_y);
-
After creating the transform_h handle and setting the output property, execute the transform using the image_util_transform_run() function.
You can use the image_util_transform_completed_cb callback for handling the function results.
ret = image_util_transform_run(handle, src, (image_util_transform_completed_cb)completed_callback, user_data);
-
When the callback confirms that the transform is completed, call the image_util_transform_destroy() function:
ret = image_util_transform_destroy(handle);
Note - Because of a YUV restriction, and because the crop start position can otherwise be set arbitrarily, the cropped image width and height must be even.
- If the hardware acceleration is enabled, you can execute 2 more image processings using just the created handle.
Decoding from a File or Memory
To decode a JPEG image:
- To decode from a file, use the image_util_decode_jpeg() function.
Manually allocate the memory for the image buffer based on a calculated buffer size.
ret = image_util_decode_jpeg(SAMPLE_FILENAME, colorspace, &img_source, &width, &height, &size_decode);
-
To decode from memory, use the image_util_decode_jpeg_from_memory() function.
Manually allocate the memory for the image buffer based on a calculated buffer size.
ret = image_util_decode_jpeg_from_memory(jpeg_buffer, jpeg_size, colorspace, image_buffer, width, height, size);
Encoding to a File or Memory
To encode a rotated or flipped image:
- To encode to a JPEG file, use the image_util_encode_jpeg() function:
ret = image_util_encode_jpeg(img_flip_target, dest_width, dest_height, colorspace, 100, OUTPUT_ROTATED_JPEG);
- To encode to memory in JPEG format, use the image_util_encode_jpeg_to_memory() function:
ret = image_util_encode_jpeg_to_memory(img_flip_target, dest_width, dest_height, colorspace, 100, jpeg_buffer, jpeg_size);