From 30b38d6fab0ffd3a90a71b70907dc0026809d4f0 Mon Sep 17 00:00:00 2001 From: twanvl Date: Thu, 29 Mar 2007 14:45:59 +0000 Subject: [PATCH] Implemented sharpening for image slicer git-svn-id: svn://svn.code.sf.net/p/magicseteditor/code/trunk@241 0fc631ac-6414-0410-93d0-97cfa31319b6 --- src/gfx/gfx.hpp | 7 ++++ src/gfx/resample_image.cpp | 59 ++++++++++++++++++++++++++++++++++ src/gui/image_slice_window.cpp | 8 ++--- 3 files changed, 70 insertions(+), 4 deletions(-) diff --git a/src/gfx/gfx.hpp b/src/gfx/gfx.hpp index b0971cca..33be8e06 100644 --- a/src/gfx/gfx.hpp +++ b/src/gfx/gfx.hpp @@ -36,6 +36,13 @@ enum PreserveAspect /// Resample an image, but preserve the aspect ratio by adding a transparent border around the output if needed. void resample_preserve_aspect(const Image& img_in, Image& img_out); +/// Resample an image to create a sharp result by applying a sharpening filter +/** Amount must be between 0 and 100 */ +void sharp_resample(const Image& img_in, Image& img_out, int amount); + +/// Sharpening version of of resample_and_clip +void sharp_resample_and_clip(const Image& img_in, Image& img_out, wxRect rect, int amount); + /// Draw text by first drawing it using a larger font and then downsampling it /** optionally rotated by an angle. * rect = rectangle to draw in diff --git a/src/gfx/resample_image.cpp b/src/gfx/resample_image.cpp index d8d23450..014dc527 100644 --- a/src/gfx/resample_image.cpp +++ b/src/gfx/resample_image.cpp @@ -165,3 +165,62 @@ void resample_preserve_aspect(const Image& img_in, Image& img_out) { resample_pass(img_in, img_temp, 0, 0, img_in.GetWidth(), 1, rwidth, 1, img_in.GetHeight(), img_in.GetWidth(), img_temp.GetWidth()); resample_pass(img_temp, img_out, 0, offset_out, img_in.GetHeight(), img_temp.GetWidth(), rheight, img_out.GetWidth(), rwidth, 1, 1); } + +// ----------------------------------------------------------------------------- : Sharpening + +void sharp_downsample(const Image& img_in, Image& img_out, int amount); + +void sharp_resample(const Image& img_in, Image& img_out, int amount) { + sharp_resample_and_clip(img_in, img_out, wxRect(0, 0, img_in.GetWidth(), img_in.GetHeight()), amount); +} + +void sharp_resample_and_clip(const Image& img_in, Image& img_out, wxRect rect, int amount) { + Image img_larger(img_out.GetWidth() * 2, img_out.GetHeight() * 2, false); + resample_and_clip(img_in, img_larger, rect); + sharp_downsample(img_larger, img_out, amount); +} + +// Downsample an image to create a sharp result by applying a sharpening filter +// img_in must be twice as large as img_out +void sharp_downsample(const Image& img_in, Image& img_out, int amount) { + assert(img_in.GetWidth() == img_out.GetWidth() * 2); + assert(img_in.GetHeight() == img_out.GetHeight() * 2); + + int width = img_out.GetWidth(), height = img_out.GetHeight(); + int line = width * 6; + int center_weight = 201; + int border_weight = amount; + assert(4 * center_weight - 8 * border_weight > 0); + + Byte *in = img_in.GetData(), *out = img_out.GetData(); + + for (int y = 0 ; y < height ; ++y) { + for (int x = 0 ; x < width ; ++x) { + for (int c = 0 ; c < 3 ; ++c) { // for each component + // Filter using a kernel of the form + /* -1 -1 + * -1 c c -1 + * -1 c c -1 + * -1 -1 + * But when we are near the edge replicate the edge pixel + */ + int tot = + center_weight * (in[0] + in[3] + in[line] + in[line+3]) - // center + border_weight * ( + (x == 0 ? in[0] + in[line] : in[-3] + in[line-3]) + // left + (x+1 == width ? in[3] + in[line+3] : in[6] + in[line+6]) + // right + (y == 0 ? in[0] + in[3] : in[-line] + in[3-line]) + // top + (y+1 == height ? in[line] + in[line+3] : in[line*2] + in[line*2+3]) );// bottom + // And then avarage the result into a single pixel (downsample by factor 2) + out[0] = col( tot / (4 * center_weight - 8 * border_weight) ); + // next pixel + ++in; + ++out; + } + // skip a pixel + in += 3; + } + // skip a line + in += line; + } +} diff --git a/src/gui/image_slice_window.cpp b/src/gui/image_slice_window.cpp index ee27ab22..c4541196 100644 --- a/src/gui/image_slice_window.cpp +++ b/src/gui/image_slice_window.cpp @@ -54,11 +54,11 @@ Image ImageSlice::getSlice() const { return source; } Image target(target_size.GetWidth(), target_size.GetHeight(), false); -// if (sharpen && sharpen_amount > 0) { -// sharp_resample_and_clip(source, target, selection, sharpen_amount); -// } else { + if (sharpen && sharpen_amount > 0 && sharpen_amount <= 100) { + sharp_resample_and_clip(source, target, selection, sharpen_amount); + } else { resample_and_clip(source, target, selection); -// } + } return target; }