Sat, 10 Jul 2021 16:12:35 +0300
* Convolution filter bug fixed
Source/Gorgon/ImageProcessing/Filters.h | file | annotate | diff | comparison | revisions | |
Testing/Source/Manual/Generic.cpp | file | annotate | diff | comparison | revisions |
--- a/Source/Gorgon/ImageProcessing/Filters.h Sat Jul 10 12:25:55 2021 +0300 +++ b/Source/Gorgon/ImageProcessing/Filters.h Sat Jul 10 16:12:35 2021 +0300 @@ -42,7 +42,8 @@ * you may use Convolution member function. It will call this function with the contained image. * outsidecolor could be converted from RGBA if an 8-bit image is used. outofrange is only used * when this function is applied to integral typed images including Image class. scale is used - * only if outofrange is set to Scale or ScaleThenClamp. + * only if outofrange is set to Scale or ScaleThenClamp. If noalpha is set, the operation will + * not be performed on alpha channel and the original alpha channel is copied to the output. */ template <class CT_ = Byte> Containers::basic_Image<CT_> Convolution( @@ -195,7 +196,7 @@ auto cy = y - j + h/2; if(cx < 0 || cx >= W || cy < 0 || cy >= H) { - oob(cx, cy, values); + oob(cx, cy, values, kernel(i, j)); } else { for(int c=0; c<C; c++) { @@ -296,9 +297,9 @@ switch(outofbounds) { default: case OutOfBoundsPolicy::FixedColor: - forpixels([&](auto , auto , auto &values) { + forpixels([&](auto , auto , auto &values, float kernel) { for(int c=0; c<C; c++) { - values[c] += outsidecolor[c]; + values[c] += outsidecolor[c] * kernel; } }); break; @@ -308,39 +309,47 @@ break; case OutOfBoundsPolicy::NearestNeighbor: - forpixels([&](auto x, auto y, auto &values) { + forpixels([&](auto x, auto y, auto &values, float kernel) { auto cx = Clamp(x, 0, W - 1); auto cy = Clamp(y, 0, H - 1); for(int c=0; c<C; c++) { - values[c] += input(cx, cy, c); + values[c] += input(cx, cy, c) * kernel; } }); break; case OutOfBoundsPolicy::Cyclic: - forpixels([&](auto x, auto y, auto &values) { + forpixels([&](auto x, auto y, auto &values, float kernel) { auto cx = PositiveMod(x, W - 1); auto cy = PositiveMod(y, H - 1); for(int c=0; c<C; c++) { - values[c] += input(cx, cy, c); + values[c] += input(cx, cy, c) * kernel; } }); break; case OutOfBoundsPolicy::Mirror: - forpixels([&](auto x, auto y, auto &values) { + forpixels([&](auto x, auto y, auto &values, float kernel) { auto cx = Mirror(x, W - 1); auto cy = Mirror(y, H - 1); for(int c=0; c<C; c++) { - values[c] += input(cx, cy, c); + values[c] += input(cx, cy, c) * kernel; } }); break; } - + + if(noalpha && A != -1) { + for(int y=0; y<H; y++) { + for(int x=0; x<W; x++) { + output(x, y, A) = input(x, y, A); + } + } + } + return output; }
--- a/Testing/Source/Manual/Generic.cpp Sat Jul 10 12:25:55 2021 +0300 +++ b/Testing/Source/Manual/Generic.cpp Sat Jul 10 16:12:35 2021 +0300 @@ -1,7 +1,10 @@ #include "GraphicsHelper.h" #include <Gorgon/Graphics/Bitmap.h> +#include <Gorgon/ImageProcessing/Kernel.h> +#include <Gorgon/ImageProcessing/Filters.h> +using namespace Gorgon::ImageProcessing; std::string helptext = "Key list:\n" "esc\tClose\n" @@ -12,15 +15,20 @@ int main() { Application app("generictest", "Test", helptext, 10); - app.wind.Resize(1000, 850); Graphics::Layer layer; app.wind.Add(layer); Bitmap bmp; - bmp.Import("../../Resources/Logo-large.png"); + bmp.Import("read.png"); + bmp.StripAlpha(); - bmp = bmp.FlipX(); + bmp.Assume( + Convolution( + Convolution(bmp.GetData(), Kernel::GaussianFilter(2,Gorgon::Axis::X, 2)), + Kernel::GaussianFilter(2,Gorgon::Axis::Y, 2) + ) + ); bmp.Prepare(); bmp.Draw(layer, 0,0);