diff --git a/uppsrc/CtrlCore/ImageWin32.cpp b/uppsrc/CtrlCore/ImageWin32.cpp index 847961347..a21a724c9 100644 --- a/uppsrc/CtrlCore/ImageWin32.cpp +++ b/uppsrc/CtrlCore/ImageWin32.cpp @@ -340,7 +340,7 @@ void SystemDraw::SysDrawImageOp(int x, int y, const Image& img, const Rect& src, static LRUCache cache; LLOG("SysImage cache pixels " << cache.GetSize() << ", count " << cache.GetCount()); Size sz = Ctrl::GetPrimaryScreenArea().GetSize(); - m.img = img; + m.img = IsPrinter() && GetDeviceCaps(GetHandle(), NUMCOLORS) == 2 ? Dither(img, 360) : img; // If printer does not support color, dither cache.Get(m).Paint(*this, x, y, src, color); cache.Shrink(4 * sz.cx * sz.cy, IsWinNT() ? 1000 : 100); } diff --git a/uppsrc/Draw/ImageOp.cpp b/uppsrc/Draw/ImageOp.cpp index 917e2b275..d1e44c5ce 100644 --- a/uppsrc/Draw/ImageOp.cpp +++ b/uppsrc/Draw/ImageOp.cpp @@ -790,4 +790,30 @@ Image Rotate(const Image& m, int angle) return ib; } +Image Dither(const Image& m, int dival) +{ + DTIMING("Dither"); + static byte dither[8][8]= { + 1, 49, 13, 61, 4, 52, 16, 64, + 33, 17, 45, 29, 36, 20, 48, 32, + 9, 57, 5, 53, 12, 60, 8, 56, + 41, 25, 37, 21, 44, 28, 40, 24, + 3, 51, 15, 63, 2, 50, 14, 62, + 35, 19, 47, 31, 34, 18, 46, 30, + 11, 59, 7, 55, 10, 58, 6, 54, + 43, 27, 39, 23, 42, 26, 38, 22 + }; + + Size isz = m.GetSize(); + ImageBuffer ib(m.GetSize()); + const RGBA *s = ~m; + RGBA *t = ~ib; + for(int y = 0; y < isz.cy; y++) + for(int x = 0; x < isz.cx; x++) { + int g = Grayscale(*s++) * 100 / dival; + *t++ = g > dither[y & 7][x & 7] ? White() : Black(); + } + return ib; +} + END_UPP_NAMESPACE diff --git a/uppsrc/Draw/ImageOp.h b/uppsrc/Draw/ImageOp.h index 0cd9e74fc..df3177da6 100644 --- a/uppsrc/Draw/ImageOp.h +++ b/uppsrc/Draw/ImageOp.h @@ -89,6 +89,7 @@ void Filter(RasterEncoder& target, Raster& src, ImageFilter9& filter); Image Etched(const Image& img); Image Sharpen(const Image& img, int amount = 100); +Image Dither(const Image& m, int dival = 394); Image RotateClockwise(const Image& img); Image RotateAntiClockwise(const Image& img); diff --git a/uppsrc/Draw/src.tpp/Image$en-us.tpp b/uppsrc/Draw/src.tpp/Image$en-us.tpp index 89323d7f7..f028242d5 100644 --- a/uppsrc/Draw/src.tpp/Image$en-us.tpp +++ b/uppsrc/Draw/src.tpp/Image$en-us.tpp @@ -390,12 +390,21 @@ based on [%-*@3 img].&] [s4; &] [s5;:Sharpen`(const Image`&`,int`): [_^Image^ Image]_[* Sharpen]([@(0.0.255) const]_[_^Image^ I mage][@(0.0.255) `&]_[*@3 img], [@(0.0.255) int]_[*@3 amount]_`=_[@3 100])&] -[s2;%% [%-*@3 img] [%-*@3 amount].&] +[s2;%% Sharpens image using primitive convolution filter.&] +[s3;%% &] +[s4; &] +[s5;:Dither`(const Image`&`,int`): [_^Image^ Image]_[* Dither]([@(0.0.255) const]_[_^Image^ I +mage][@(0.0.255) `&]_[*@3 m], [@(0.0.255) int]_[*@3 dival]_`=_[@3 394])&] +[s2;%% Provides primitive dithering with 8x8 matrix into black/white +picture. Dival is sort of gamma control of output, lowering it +from default value (to e.g. 350) can produce better results when +dithering is using for printing on purely monochromatic (without +half`-toning support) printers.&] [s3;%% &] [s4; &] [s5;:Etched`(const Image`&`): [_^Image^ Image]_[* Etched]([@(0.0.255) const]_[_^Image^ Image][@(0.0.255) `& ]_[*@3 img])&] -[s2;%% [%-*@3 img].&] +[s2;%% `"Etching`" effect.&] [s3;%% &] [s4; &] [s5;:SetColorKeepAlpha`(const Image`&`,Color`): [_^Image^ Image]_[* SetColorKeepAlpha]([@(0.0.255) c