* implemented filter_black_stuff to remove black dots. * allow threshold to be negative in filter_equalize; in this case, invert colours. * implemented filter_crop. git-svn-id: file:///srv/caca.zoy.org/var/lib/svn/pwntcha/trunk@413 92316355-f0b4-4df1-b90c-862c8a59935fmaster
@@ -27,9 +27,10 @@ char *decode_slashdot(struct image *img); | |||
char *decode_test(struct image *img); | |||
/* image operations */ | |||
struct image *image_load(char *name); | |||
struct image *image_load(const char *name); | |||
struct image *image_new(int width, int height); | |||
void image_free(struct image *img); | |||
void image_save(struct image *img, const char *name); | |||
void image_display(struct image *img); | |||
int getgray(struct image *img, int x, int y, int *g); | |||
int getpixel(struct image *img, int x, int y, int *r, int *g, int *b); | |||
@@ -39,11 +40,14 @@ int setpixel(struct image *img, int x, int y, int r, int g, int b); | |||
void filter_flood_fill(struct image *img, int x, int y, int r, int g, int b); | |||
struct image *filter_fill_holes(struct image *img); | |||
struct image *filter_dup(struct image *img); | |||
struct image *filter_black_stuff(struct image *img); | |||
struct image *filter_detect_lines(struct image *img); | |||
struct image *filter_equalize(struct image *img, int threshold); | |||
struct image *filter_trick(struct image *img); | |||
struct image *filter_smooth(struct image *img); | |||
struct image *filter_median(struct image *img); | |||
struct image *filter_contrast(struct image *img); | |||
struct image *filter_crop(struct image *img, | |||
int xmin, int ymin, int xmax, int ymax); | |||
int filter_count(struct image *img); | |||
@@ -120,6 +120,46 @@ struct image *filter_fill_holes(struct image *img) | |||
return dst; | |||
} | |||
struct image *filter_black_stuff(struct image *img) | |||
{ | |||
struct image *dst; | |||
int x, y; | |||
int r, ra, rb, g, b; | |||
dst = image_new(img->width, img->height); | |||
/* Remove vertical stuff */ | |||
for(y = 0; y < img->height; y++) | |||
for(x = 0; x < img->width; x++) | |||
{ | |||
getpixel(img, x, y, &r, &g, &b); | |||
setpixel(dst, x, y, r, g, b); | |||
if(y > 0 && y < img->height - 1) | |||
{ | |||
getpixel(img, x, y - 1, &ra, &g, &b); | |||
getpixel(img, x, y + 1, &rb, &g, &b); | |||
if(r < ra && (r - ra) * (r - rb) > 5000) | |||
setpixel(dst, x, y, ra, ra, ra); | |||
} | |||
} | |||
/* Remove horizontal stuff */ | |||
for(y = 0; y < img->height; y++) | |||
for(x = 0; x < img->width; x++) | |||
{ | |||
getpixel(img, x, y, &r, &g, &b); | |||
if(x > 0 && x < img->width - 1) | |||
{ | |||
getpixel(dst, x - 1, y, &ra, &g, &b); | |||
getpixel(dst, x + 1, y, &rb, &g, &b); | |||
if(r < ra && (r - ra) * (r - rb) > 5000) | |||
setpixel(dst, x, y, ra, ra, ra); | |||
} | |||
} | |||
return dst; | |||
} | |||
struct image *filter_detect_lines(struct image *img) | |||
{ | |||
struct image *dst; | |||
@@ -165,15 +205,25 @@ struct image *filter_equalize(struct image *img, int threshold) | |||
struct image *dst; | |||
int x, y; | |||
int r, g, b; | |||
int min = 0, max = 255; | |||
dst = image_new(img->width, img->height); | |||
if(threshold < 0) | |||
{ | |||
min = 255; | |||
max = 0; | |||
threshold = -threshold; | |||
} | |||
for(y = 0; y < img->height; y++) | |||
for(x = 0; x < img->width; x++) | |||
{ | |||
getpixel(img, x, y, &r, &g, &b); | |||
if(r < threshold) r = 0; else r = 255; | |||
setpixel(dst, x, y, r, r, r); | |||
if(r < threshold) | |||
setpixel(dst, x, y, min, min, min); | |||
else | |||
setpixel(dst, x, y, max, max, max); | |||
} | |||
return dst; | |||
@@ -329,6 +379,37 @@ struct image *filter_contrast(struct image *img) | |||
return dst; | |||
} | |||
struct image *filter_crop(struct image *img, | |||
int xmin, int ymin, int xmax, int ymax) | |||
{ | |||
struct image *dst; | |||
int x, y; | |||
int r, g, b; | |||
if(xmin < 0) | |||
xmin = 0; | |||
if(ymin < 0) | |||
ymin = 0; | |||
if(xmax >= img->width) | |||
xmax = img->width - 1; | |||
if(ymax >= img->height) | |||
ymax = img->height - 1; | |||
if(xmin >= xmax || ymin >= ymax) | |||
return NULL; | |||
dst = image_new(xmax - xmin, ymax - ymin); | |||
for(y = 0; y < dst->height; y++) | |||
for(x = 0; x < dst->width; x++) | |||
{ | |||
getpixel(img, xmin + x, ymin + y, &r, &g, &b); | |||
setpixel(dst, x, y, r, g, b); | |||
} | |||
return dst; | |||
} | |||
int filter_count(struct image *img) | |||
{ | |||
int histo[256]; | |||
@@ -26,7 +26,7 @@ | |||
# error "No imaging library" | |||
#endif | |||
struct image *image_load(char *name) | |||
struct image *image_load(const char *name) | |||
{ | |||
struct image *img; | |||
#if defined(HAVE_SDL_IMAGE_H) | |||
@@ -76,12 +76,12 @@ struct image *image_new(int width, int height) | |||
rmask = 0xff000000; | |||
gmask = 0x00ff0000; | |||
bmask = 0x0000ff00; | |||
amask = 0x000000ff; | |||
amask = 0x00000000; | |||
# else | |||
rmask = 0x000000ff; | |||
gmask = 0x0000ff00; | |||
bmask = 0x00ff0000; | |||
amask = 0xff000000; | |||
amask = 0x00000000; | |||
# endif | |||
priv = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, 32, | |||
rmask, gmask, bmask, amask); | |||
@@ -136,6 +136,18 @@ void image_free(struct image *img) | |||
free(img); | |||
} | |||
void image_save(struct image *img, const char *name) | |||
{ | |||
#if defined(HAVE_SDL_IMAGE_H) | |||
SDL_SaveBMP(img->priv, name); | |||
#elif defined(HAVE_IMLIB2_H) | |||
imlib_context_set_image(img->priv); | |||
imlib_save_image(name); | |||
#elif defined(HAVE_CV_H) | |||
cvSaveImage(name, img->priv); | |||
#endif | |||
} | |||
int getgray(struct image *img, int x, int y, int *g) | |||
{ | |||
if(x < 0 || y < 0 || x >= img->width || y >= img->height) | |||