Ephoto: Add Sobel Edge Detection Filter.

This commit is contained in:
Stephen Houston 2016-06-13 21:20:14 -05:00
parent 4350566a38
commit 6ce5ec3277
3 changed files with 99 additions and 3 deletions

View File

@ -149,6 +149,7 @@ void ephoto_filter_cartoon(Evas_Object *main, Evas_Object *image);
void ephoto_filter_posterize(Evas_Object *main, Evas_Object *image); void ephoto_filter_posterize(Evas_Object *main, Evas_Object *image);
void ephoto_filter_sketch(Evas_Object *main, Evas_Object *image); void ephoto_filter_sketch(Evas_Object *main, Evas_Object *image);
void ephoto_filter_invert(Evas_Object *main, Evas_Object *image); void ephoto_filter_invert(Evas_Object *main, Evas_Object *image);
void ephoto_filter_edge(Evas_Object *main, Evas_Object *image);
void ephoto_filter_histogram_eq(Evas_Object *main, Evas_Object *image); void ephoto_filter_histogram_eq(Evas_Object *main, Evas_Object *image);
/*file functions*/ /*file functions*/

View File

@ -13,7 +13,8 @@ enum _Ephoto_Image_Filter
EPHOTO_IMAGE_FILTER_POSTERIZE, EPHOTO_IMAGE_FILTER_POSTERIZE,
EPHOTO_IMAGE_FILTER_SEPIA, EPHOTO_IMAGE_FILTER_SEPIA,
EPHOTO_IMAGE_FILTER_SHARPEN, EPHOTO_IMAGE_FILTER_SHARPEN,
EPHOTO_IMAGE_FILTER_SKETCH EPHOTO_IMAGE_FILTER_SKETCH,
EPHOTO_IMAGE_FILTER_SOBEL
}; };
struct _Ephoto_Filter struct _Ephoto_Filter
@ -45,6 +46,7 @@ static Eina_Bool _sepia(void *data);
static Eina_Bool _negative(void *data); static Eina_Bool _negative(void *data);
static Eina_Bool _posterize(void *data); static Eina_Bool _posterize(void *data);
static Eina_Bool _dodge(void *data); static Eina_Bool _dodge(void *data);
static Eina_Bool _sobel(void *data);
static Eina_Bool _histogram_eq(void *data); static Eina_Bool _histogram_eq(void *data);
static Ephoto_Filter * static Ephoto_Filter *
@ -511,7 +513,6 @@ _posterize(void *data)
return EINA_TRUE; return EINA_TRUE;
} }
} }
_idler_finishing_cb(ef, EINA_FALSE); _idler_finishing_cb(ef, EINA_FALSE);
return EINA_FALSE; return EINA_FALSE;
@ -609,6 +610,69 @@ _dodge(void *data)
return EINA_FALSE; return EINA_FALSE;
} }
static Eina_Bool
_sobel(void *data)
{
Ephoto_Filter *ef = data;
Evas_Coord x, y, w, h;
int i, j, passes = 0;
unsigned int *p;
float sobx[3][3] = {{-1, 0, 1},
{-2, 0, 2},
{-1, 0, 1}};
float soby[3][3] = {{-1, -2, -1},
{0, 0, 0},
{1, 2, 1}};
w = ef->w;
h = ef->h;
for (y = ef->pos; y < h; y++)
{
p = ef->im_data_new + (y * w);
for (x = 0; x < w; x++)
{
int pval = 0, a, r, g, b;
double hpval = 0.0, vpval = 0.0;
if (y > 0 && x > 0 && y < (h - 2) && x < (w - 2))
{
for (i = -1; i <= 1; i++)
{
for (j = -1; j <= 1; j++)
{
int index, pix;
index = (y + i) * w + x + j;
pix = ef->im_data[index];
hpval += pix * sobx[i+1][j+1];
vpval += pix * soby[i+1][j+1];
}
}
}
pval = abs(hpval) + abs(vpval);
*p = pval;
b = (int) ((*p) & 0xff);
g = (int) ((*p >> 8) & 0xff);
r = (int) ((*p >> 16) & 0xff);
a = (int) ((*p >> 24) & 0xff);
b = _normalize_color(b);
g = _normalize_color(g);
r = _normalize_color(r);
a = _normalize_color(a);
*p = (a << 24) | (r << 16) | (g << 8) | b;
p++;
}
passes++;
if (passes == 500)
{
ef->pos = y++;
return EINA_TRUE;
}
}
_idler_finishing_cb(ef, EINA_FALSE);
return EINA_FALSE;
}
static Eina_Bool static Eina_Bool
_histogram_eq(void *data) _histogram_eq(void *data)
{ {
@ -760,7 +824,7 @@ ephoto_filter_cartoon(Evas_Object *main, Evas_Object *image)
Ephoto_Filter *ef = _initialize_filter(EPHOTO_IMAGE_FILTER_CARTOON, Ephoto_Filter *ef = _initialize_filter(EPHOTO_IMAGE_FILTER_CARTOON,
main, image); main, image);
ef->rad = 5; ef->rad = 9;
ef->drad = 5.0; ef->drad = 5.0;
ef->qpos = 0; ef->qpos = 0;
ef->qcount = 1; ef->qcount = 1;
@ -793,6 +857,20 @@ void ephoto_filter_sketch(Evas_Object *main, Evas_Object *image)
ef->idler = ecore_idler_add(_grayscale, ef); ef->idler = ecore_idler_add(_grayscale, ef);
} }
void ephoto_filter_edge(Evas_Object *main, Evas_Object *image)
{
Ephoto_Filter *ef = _initialize_filter(EPHOTO_IMAGE_FILTER_SOBEL,
main, image);
ef->rad = 3;
ef->qpos = 0;
ef->qcount = 2;
ef->queue = eina_list_append(ef->queue, _grayscale);
ef->queue = eina_list_append(ef->queue, _sobel);
ef->popup = _processing(main);
ef->idler = ecore_idler_add(_blur, ef);
}
void void
ephoto_filter_histogram_eq(Evas_Object *main, Evas_Object *image) ephoto_filter_histogram_eq(Evas_Object *main, Evas_Object *image)
{ {

View File

@ -1226,6 +1226,21 @@ _go_sketch(void *data, Evas_Object *obj EINA_UNUSED,
} }
} }
static void
_go_edge(void *data, Evas_Object *obj EINA_UNUSED,
void *event_info EINA_UNUSED)
{
Ephoto_Single_Browser *sb = data;
if (sb->viewer)
{
sb->editing = EINA_TRUE;
Ephoto_Viewer *v = evas_object_data_get(sb->viewer, "viewer");
ephoto_filter_edge(sb->main, v->image);
}
}
static void static void
_image_changed(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, _image_changed(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
void *event_info EINA_UNUSED) void *event_info EINA_UNUSED)
@ -1471,6 +1486,8 @@ _add_edit_menu_items(Ephoto_Single_Browser *sb, Evas_Object *menu)
elm_menu_item_add(menu, menu_itt, "insert-image", _("Blur"), _go_blur, sb); elm_menu_item_add(menu, menu_itt, "insert-image", _("Blur"), _go_blur, sb);
elm_menu_item_add(menu, menu_itt, "insert-image", _("Cartoon"), elm_menu_item_add(menu, menu_itt, "insert-image", _("Cartoon"),
_go_cartoon, sb); _go_cartoon, sb);
elm_menu_item_add(menu, menu_itt, "insert-image", _("Edge Detect"),
_go_edge, sb);
elm_menu_item_add(menu, menu_itt, "insert-image", _("Invert Colors"), elm_menu_item_add(menu, menu_itt, "insert-image", _("Invert Colors"),
_go_invert, sb); _go_invert, sb);
elm_menu_item_add(menu, menu_itt, "insert-image", _("Old Photo"), elm_menu_item_add(menu, menu_itt, "insert-image", _("Old Photo"),