* 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) | |||