~~Title: Image Objects~~
{{page>index}}
-----
===== Image Objects =====
Using Evas, you can create and manipulate image objects. Evas supports image
loaders of various formats as plug-in modules.
The image formats that Evas supports include ''bmp'', ''edj'', ''gif'',
''ico'', ''jpeg'', ''pmaps'', ''png'', ''psd'', ''svg'', ''tga'', ''tiff'',
''wbmp'', ''webp'', and ''xpm''.
{{ :evas_image_loader.png }}
=== Table of Contents ===
* [[#Evas_Object_Image_Functions|Evas Object Image Functions]]
* [[#Creating_an_Image_Object_and_Setting_the_Image_Data_Source|Creating an Image Object and Setting the Image Data Source]]
* [[#Image_Scaling|Image Scaling]]
* [[#Setting_Raw_Data_to_Image_Object|Setting Raw Data to Image Object]]
=== Related Info ===
* [[https://build.enlightenment.org/job/nightly_efl_gcc_x86_64/lastSuccessfulBuild/artifact/doc/html/group__Evas__Object__Image.html|Image Object Functions API]]
==== Evas Object Image Functions ====
Evas has over 70 image object functions. The following functions are discussed
in this document:
Evas_Object *evas_object_image_add(Evas *e);
void evas_object_image_file_set(Evas_Object *obj, const char *file, const char *key);
void evas_object_image_fill_set(Evas_Object *obj, int x, int y, int w, int h);
void evas_object_image_filled_set(Evas *e, Eina_Bool setting);
Evas_Object *evas_object_image_filled_add(Evas *e);
void evas_object_image_smooth_scale_set(Evas_Object *obj, Eina_Bool smoothscale);
void evas_object_image_load_size_set(Evas_Object *obj, int w, int h);
void evas_object_image_data_set(Evas_Object *obj, void *data);
void *evas_object_image_data_get(const Evas_Object *obj, Eina_Bool for_writing);
void evas_object_image_size_set(Evas_Object *obj, int w, int h);
void evas_object_image_data_update_add(Evas_Object *obj, int x, int y, int w, int h);
Eina_Bool evas_object_image_save(const Evas_Object *obj, const char *file, const char *key, const char *flags);
==== Creating an Image Object and Setting the Image Data Source ====
A common use case of an image object is to set a file as the image data
source. The process has 3 steps and each one involves the following API calls:
* The ''evas_object_image_add()'' function creates an image object and returns the pointer.
Evas_Object *evas_object_image_add(Evas *e);
* The ''evas_object_image_file_set()'' function sets a source file on the image object. The object fetches the image pixel data from the source file.
void evas_object_image_file_set(Evas_Object *obj, const char *file, const char *key);
* The ''evas_object_image_fill_set()'' sets how to fill the image object's area with the given pixel data.
void evas_object_image_fill_set(Evas_Object *obj, int x, int y, int w, int h);
In the following code example, the ''main()'' function creates an image object
and displays it on a window. The image object size is 300x300 and the source
image resolution is 100x127. The image is scaled into 300 by 300 to fill the
image object area using the ''evas_object_image_fill_set()'' function.
#include
int main(int argc, char **argv)
{
elm_init(argc, argv);
// Create a window object
Evas_Object *win = elm_win_add(NULL, "main", ELM_WIN_BASIC);
evas_object_resize(win, 400, 400);
evas_object_show(win);
// Return Evas handle from window
Evas *e = evas_object_evas_get(win);
// Create an image object
Evas_Object *img = evas_object_image_add(e);
// Set a source file to fetch pixel data
evas_object_image_file_set(img, "./logo.png", NULL);
// Set the size and position of the image on the image object area
evas_object_image_fill_set(img, 0, 0, 300, 300);
evas_object_move(img, 50, 50);
evas_object_resize(img, 300, 300);
evas_object_show(img);
elm_run();
elm_shutdown();
return 0;
}
{{ :evas_object_display.png }}
==== Image Scaling ====
Users can decide how to fill the image object area with the given image pixel
data by setting the position, width, and height of the image using the
''evas_object_image_fill_set()'' function. Without setting this information,
the image is not displayed. If the size of the image is bigger than the image
object area, only a sub-region of the original image is displayed. If the
image is smaller than the area, images are tiled repeatedly to fill the object
area.
{{ :evas_image_scaling.png }}
{{ :evas_scaling.png }}
the ''evas_object_image_filled_set()'' function scales the image to fit the
object area. Resizing the image object automatically triggers an internal call
to the ''evas_object_image_fill_set()'' function.
void evas_object_image_filled_set(Evas * e,
Eina_Bool setting
)
The ''evas_object_image_filled_add()'' function creates a new image object
that automatically scales its bound image to the object area. This is a helper
function around the ''evas_object_image_add()'' and
''evas_object_image_filled_set()'' functions.
Scaled images' quality can differ according to scaling algorithms. Smooth
scaling improves the image quality in the process of size reducing or
enlarging. Evas runs its own smooth scaling algorithm by default and provides
an API so users can disable the function.
Evas_Object *evas_object_image_filled_add(Evas *e);
void evas_object_image_smooth_scale_set(Evas_Object * obj,
Eina_Bool smoothscale
)
The algorithm is implemented using the SIMD (Single Instruction Multiple Data)
vectorization in case of software rendering. It is optimized on Intel and ARM
CPU through MMX and NEON command respectively.
There is a trade-off between image smoothness and rendering performance. The
load gets bigger as the image gets bigger. Users can avoid such scaling
overload by using the same size of the image object and the source image.
In the following code, 2 image objects are created to show the effects of
smooth scaling. The one with smooth scaling applied appears softer on the
screen.
#include
int main(int argc, char **argv)
{
elm_init(argc, argv);
// Create a window object
Evas_Object *win = elm_win_add(NULL, "main", ELM_WIN_BASIC);
evas_object_resize(win, 400, 200);
evas_object_show(win);
// Return Evas handle from window
Evas *e = evas_object_evas_get(win);
// Create an image object
Evas_Object *img = evas_object_image_filled_add(e);
evas_object_image_file_set(img, "./logo.png", NULL);
evas_object_move(img, 0, 0);
evas_object_resize(img, 200, 200);
evas_object_show(img);
// Create another image object
Evas_Object *img2 = evas_object_image_filled_add(e);
evas_object_image_file_set(img2, "./logo.png", NULL);
// Disable smooth scaling
evas_object_image_smooth_scale_set(img2, EINA_FALSE);
evas_object_move(img2, 200, 0);
evas_object_resize(img2, 200, 200);
evas_object_show(img2);
elm_run();
elm_shutdown();
return 0;
}
Smooth scaling disabled:
{{ :evas_smooth_disabled.png }}
Smooth scaling enabled:
{{ :evas_smooth_enabled.png }}
Evas caches scaled image data and reuses them. Users can save the memory by
loading the image in the scaled size to the memory at the beginning. This
option is available only for ''jpeg'' format at the moment.
void evas_object_image_load_size_set(Evas_Object * obj,
int w,
int h
)
An example code is as follows.
#include
int main(int argc, char **argv)
{
elm_init(argc, argv);
// Create a window object
Evas_Object *win = elm_win_add(NULL, "main", ELM_WIN_BASIC);
evas_object_resize(win, 400, 200);
evas_object_show(win);
// Return Evas handle from window
Evas *e = evas_object_evas_get(win);
// Create an image object
Evas_Object *img = evas_object_image_filled_add(e);
// Load the image scaled into the object size
// before evas_object_image_file_set() is called
evas_object_image_load_size_set(img, 300, 300);
evas_object_image_file_set(img, "./logo.png", NULL);
evas_object_move(img, 50, 50);
evas_object_resize(img, 300, 300);
evas_object_show(img);
elm_run();
elm_shutdown();
return 0;
}
==== Setting Raw Data to Image Object ====
Users can set raw data to the image object manually using the
''evas_object_image_data_set()'' function instead of setting an image file as
the data source. The image data should be in raw data form. In case of an
200x200 sized image with alpha channel enabled (32 bits per pixel), the size
of the image data is 160000 (=200*200*4) bytes.
void evas_object_image_data_set(Evas_Object * obj,
void * data
)
Image objects fetch metadata such as width or height from the header of the
image files. Since the raw data does not have the metadata, users must set the
size of the image using the ''evas_object_image_size_set()'' function.
void evas_object_image_size_set(Evas_Object * obj,
int w,
int h
)
The ''evas_object_image_data_get()'' function returns the data pointer of an
image object and requires a parameter to determine whether the data is
modified or not. If users pass ''EINA_TRUE'' for ''for_writing'', Evas updates
the image pixels in the next rendering cycle.
void* evas_object_image_data_get(const Evas_Object * obj,
Eina_Bool for_writing
)
The ''evas_object_image_data_update_add()'' helps to mark the updated area for
rendering efficiency.
void evas_object_image_data_update_add(Evas_Object * obj,
int x,
int y,
int w,
int h
)
The following example code and figure show how to specify the area to update.
evas_object_image_data_update_add(image, 100, 100, 50, 50);
evas_object_image_data_update_add(image, 180, 100, 50, 50);
evas_object_image_data_update_add(image, 85, 200, 160, 80);
{{ :evas_partial_update.png }}
The following code creates an image object and sets a source file on it. Then
it implements the blur effect to the pixel data and saves them using the
''evas_object_image_save()'' function.
Eina_Bool evas_object_image_save(const Evas_Object * obj,
const char * file,
const char * key,
const char * flags
)
#include
void image_blur(Evas_Object *img)
{
unsigned char *img_src = evas_object_image_data_get(img, EINA_TRUE);
int w, h;
evas_object_image_size_get(img, &w, &h);
int blur_size = 4;
int x, y, xx, yy;
for (y = 0; y < h; y++)
{
for (x = 0; x < w; x++)
{
int avg_color[3] = {0, 0, 0};
int blur_pixel_cnt = 0;
for (xx = x; (xx < x + blur_size) && (xx < w); xx++)
{
for (yy = y; (yy < y + blur_size) && (yy < h); yy++)
{
int idx = (yy * w * 4) + (xx * 4);
avg_color[0] += img_src[idx + 0];
avg_color[1] += img_src[idx + 1];
avg_color[2] += img_src[idx + 2];
++blur_pixel_cnt;
}
}
avg_color[0] /= blur_pixel_cnt;
avg_color[1] /= blur_pixel_cnt;
avg_color[2] /= blur_pixel_cnt;
int idx = (y * w * 4) + (x * 4);
img_src[idx + 0] = avg_color[0];
img_src[idx + 1] = avg_color[1];
img_src[idx + 2] = avg_color[2];
}
}
evas_object_image_data_update_add(img, 0, 0, w, h);
}
int main(int argc, char **argv)
{
elm_init(argc, argv);
Evas_Object *win = elm_win_add(NULL, "main", ELM_WIN_BASIC);
evas_object_resize(win, 200, 200);
evas_object_show(win);
Evas *e = evas_object_evas_get(win);
Evas_Object *img = evas_object_image_filled_add(e);
evas_object_image_file_set(img, "./logo.png", NULL);
evas_object_resize(img, 200, 200);
evas_object_show(img);
image_blur(img);
evas_object_image_save(img, "logo2.png", NULL, "quality=100 compress=8");
elm_run();
elm_shutdown();
return 0;
}
Before: {{ :evas_blur1.png }}
After: {{ :evas_blur2.png }}
\\
-----
{{page>index}}