* 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); | char *decode_test(struct image *img); | ||||
| /* image operations */ | /* image operations */ | ||||
| struct image *image_load(char *name); | |||||
| struct image *image_load(const char *name); | |||||
| struct image *image_new(int width, int height); | struct image *image_new(int width, int height); | ||||
| void image_free(struct image *img); | void image_free(struct image *img); | ||||
| void image_save(struct image *img, const char *name); | |||||
| void image_display(struct image *img); | void image_display(struct image *img); | ||||
| int getgray(struct image *img, int x, int y, int *g); | 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); | 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); | 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_fill_holes(struct image *img); | ||||
| struct image *filter_dup(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_detect_lines(struct image *img); | ||||
| struct image *filter_equalize(struct image *img, int threshold); | struct image *filter_equalize(struct image *img, int threshold); | ||||
| struct image *filter_trick(struct image *img); | struct image *filter_trick(struct image *img); | ||||
| struct image *filter_smooth(struct image *img); | struct image *filter_smooth(struct image *img); | ||||
| struct image *filter_median(struct image *img); | struct image *filter_median(struct image *img); | ||||
| struct image *filter_contrast(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); | int filter_count(struct image *img); | ||||
| @@ -120,6 +120,46 @@ struct image *filter_fill_holes(struct image *img) | |||||
| return dst; | 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 *filter_detect_lines(struct image *img) | ||||
| { | { | ||||
| struct image *dst; | struct image *dst; | ||||
| @@ -165,15 +205,25 @@ struct image *filter_equalize(struct image *img, int threshold) | |||||
| struct image *dst; | struct image *dst; | ||||
| int x, y; | int x, y; | ||||
| int r, g, b; | int r, g, b; | ||||
| int min = 0, max = 255; | |||||
| dst = image_new(img->width, img->height); | dst = image_new(img->width, img->height); | ||||
| if(threshold < 0) | |||||
| { | |||||
| min = 255; | |||||
| max = 0; | |||||
| threshold = -threshold; | |||||
| } | |||||
| for(y = 0; y < img->height; y++) | for(y = 0; y < img->height; y++) | ||||
| for(x = 0; x < img->width; x++) | for(x = 0; x < img->width; x++) | ||||
| { | { | ||||
| getpixel(img, x, y, &r, &g, &b); | 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; | return dst; | ||||
| @@ -329,6 +379,37 @@ struct image *filter_contrast(struct image *img) | |||||
| return dst; | 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 filter_count(struct image *img) | ||||
| { | { | ||||
| int histo[256]; | int histo[256]; | ||||
| @@ -26,7 +26,7 @@ | |||||
| # error "No imaging library" | # error "No imaging library" | ||||
| #endif | #endif | ||||
| struct image *image_load(char *name) | |||||
| struct image *image_load(const char *name) | |||||
| { | { | ||||
| struct image *img; | struct image *img; | ||||
| #if defined(HAVE_SDL_IMAGE_H) | #if defined(HAVE_SDL_IMAGE_H) | ||||
| @@ -76,12 +76,12 @@ struct image *image_new(int width, int height) | |||||
| rmask = 0xff000000; | rmask = 0xff000000; | ||||
| gmask = 0x00ff0000; | gmask = 0x00ff0000; | ||||
| bmask = 0x0000ff00; | bmask = 0x0000ff00; | ||||
| amask = 0x000000ff; | |||||
| amask = 0x00000000; | |||||
| # else | # else | ||||
| rmask = 0x000000ff; | rmask = 0x000000ff; | ||||
| gmask = 0x0000ff00; | gmask = 0x0000ff00; | ||||
| bmask = 0x00ff0000; | bmask = 0x00ff0000; | ||||
| amask = 0xff000000; | |||||
| amask = 0x00000000; | |||||
| # endif | # endif | ||||
| priv = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, 32, | priv = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, 32, | ||||
| rmask, gmask, bmask, amask); | rmask, gmask, bmask, amask); | ||||
| @@ -136,6 +136,18 @@ void image_free(struct image *img) | |||||
| free(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) | int getgray(struct image *img, int x, int y, int *g) | ||||
| { | { | ||||
| if(x < 0 || y < 0 || x >= img->width || y >= img->height) | if(x < 0 || y < 0 || x >= img->width || y >= img->height) | ||||