From 3af62446fc817c3a5555761897be38ddde056161 Mon Sep 17 00:00:00 2001 From: David Carley Date: Tue, 17 Nov 2015 12:15:34 -0600 Subject: [PATCH] Implements greyscale thresholding --- .editorconfig | 12 ++ docs/api.md | 6 + index.js | 31 +++++- package.json | 3 +- src/operations.cc | 17 +++ src/operations.h | 5 + src/pipeline.cc | 14 +++ test/fixtures/expected/threshold-1.jpg | Bin 0 -> 882 bytes .../fixtures/expected/threshold-128-alpha.png | Bin 0 -> 2126 bytes .../expected/threshold-128-transparency.png | Bin 0 -> 1083 bytes .../expected/threshold-128-transparency.webp | Bin 0 -> 12188 bytes test/fixtures/expected/threshold-128.jpg | Bin 0 -> 14814 bytes test/fixtures/expected/threshold-40.jpg | Bin 0 -> 16299 bytes test/unit/threshold.js | 105 ++++++++++++++++++ 14 files changed, 189 insertions(+), 4 deletions(-) create mode 100644 .editorconfig create mode 100644 test/fixtures/expected/threshold-1.jpg create mode 100644 test/fixtures/expected/threshold-128-alpha.png create mode 100644 test/fixtures/expected/threshold-128-transparency.png create mode 100644 test/fixtures/expected/threshold-128-transparency.webp create mode 100644 test/fixtures/expected/threshold-128.jpg create mode 100644 test/fixtures/expected/threshold-40.jpg create mode 100644 test/unit/threshold.js diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..5760be58 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,12 @@ +# http://editorconfig.org +root = true + +[*] +indent_style = space +indent_size = 2 +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.md] +trim_trailing_whitespace = false diff --git a/docs/api.md b/docs/api.md index 52c6c456..74339d03 100644 --- a/docs/api.md +++ b/docs/api.md @@ -328,6 +328,12 @@ When a `radius` is provided, performs a slower, more accurate sharpen of the L c * `flat`, if present, is a Number representing the level of sharpening to apply to "flat" areas, defaulting to a value of 1.0. * `jagged`, if present, is a Number representing the level of sharpening to apply to "jagged" areas, defaulting to a value of 2.0. +#### threshold([threshold]) + +Converts all pixels in the image to greyscale white or black. Any pixel greather-than-or-equal-to the threshold (0..255) will be white. All others will be black. + +* `threshold`, if present, is a Number, representing the level above which pixels will be forced to white. + #### gamma([gamma]) Apply a gamma correction by reducing the encoding (darken) pre-resize at a factor of `1/gamma` then increasing the encoding (brighten) post-resize at a factor of `gamma`. diff --git a/index.js b/index.js index c2585f3b..e13244aa 100644 --- a/index.js +++ b/index.js @@ -62,6 +62,7 @@ var Sharp = function(input) { sharpenRadius: 0, sharpenFlat: 1, sharpenJagged: 2, + threshold: 0, gamma: 0, greyscale: false, normalize: 0, @@ -142,7 +143,18 @@ Sharp.prototype._write = function(chunk, encoding, callback) { }; // Crop this part of the resized image (Center/Centre, North, East, South, West) -module.exports.gravity = {'center': 0, 'centre': 0, 'north': 1, 'east': 2, 'south': 3, 'west': 4, 'northeast': 5, 'southeast': 6, 'southwest': 7, 'northwest': 8}; +module.exports.gravity = { + 'center': 0, + 'centre': 0, + 'north': 1, + 'east': 2, + 'south': 3, + 'west': 4, + 'northeast': 5, + 'southeast': 6, + 'southwest': 7, + 'northwest': 8 +}; Sharp.prototype.crop = function(gravity) { this.options.canvas = 'crop'; @@ -328,6 +340,19 @@ Sharp.prototype.sharpen = function(radius, flat, jagged) { return this; }; +Sharp.prototype.threshold = function(threshold) { + if (typeof threshold === 'undefined') { + this.options.threshold = 128; + } else if (typeof threshold === 'boolean') { + this.options.threshold = threshold ? 128 : 0; + } else if (typeof threshold === 'number' && !Number.isNaN(threshold) && (threshold % 1 === 0) && threshold >= 0 && threshold <= 255) { + this.options.threshold = threshold; + } else { + throw new Error('Invalid threshold (0 to 255) ' + threshold); + } + return this; +}; + /* Set the interpolator to use for the affine transformation */ @@ -478,7 +503,7 @@ Sharp.prototype.withMetadata = function(withMetadata) { typeof withMetadata.orientation === 'number' && !Number.isNaN(withMetadata.orientation) && withMetadata.orientation % 1 === 0 && - withMetadata.orientation >=0 && + withMetadata.orientation >= 0 && withMetadata.orientation <= 7 ) { this.options.withMetadataOrientation = withMetadata.orientation; @@ -504,7 +529,7 @@ Sharp.prototype.tile = function(size, overlap) { } // Overlap of tiles, in pixels if (typeof overlap !== 'undefined' && overlap !== null) { - if (!Number.isNaN(overlap) && overlap % 1 === 0 && overlap >=0 && overlap <= 8192) { + if (!Number.isNaN(overlap) && overlap % 1 === 0 && overlap >= 0 && overlap <= 8192) { if (overlap > this.options.tileSize) { throw new Error('Tile overlap ' + overlap + ' cannot be larger than tile size ' + this.options.tileSize); } diff --git a/package.json b/package.json index 1c3e33fa..b49d47f4 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,8 @@ "Victor Mateevitsi ", "Alaric Holloway ", "Bernhard K. Weisshuhn ", - "Chris Riley " + "Chris Riley ", + "David Carley " ], "description": "High performance Node.js module to resize JPEG, PNG, WebP and TIFF images using the libvips library", "scripts": { diff --git a/src/operations.cc b/src/operations.cc index f2e42549..b00c1463 100644 --- a/src/operations.cc +++ b/src/operations.cc @@ -262,4 +262,21 @@ namespace sharp { *out = sharpened; return 0; } + + int Threshold(VipsObject *context, VipsImage *image, VipsImage **out, int threshold) { + VipsImage *greyscale; + if (vips_colourspace(image, &greyscale, VIPS_INTERPRETATION_B_W, nullptr)) { + return -1; + } + vips_object_local(context, greyscale); + image = greyscale; + + VipsImage *thresholded; + if (vips_moreeq_const1(image, &thresholded, threshold, nullptr)) { + return -1; + } + vips_object_local(context, thresholded); + *out = thresholded; + return 0; + } } // namespace sharp diff --git a/src/operations.h b/src/operations.h index ca70346c..cabe4a2e 100755 --- a/src/operations.h +++ b/src/operations.h @@ -24,6 +24,11 @@ namespace sharp { */ int Sharpen(VipsObject *context, VipsImage *image, VipsImage **out, int radius, double flat, double jagged); + /* + * Perform thresholding on an image. If the image is not greyscale, will convert before thresholding. + * Pixels with a greyscale value greater-than-or-equal-to `threshold` will be pure white. All others will be pure black. + */ + int Threshold(VipsObject *context, VipsImage *image, VipsImage **out, int threshold); } // namespace sharp #endif // SRC_OPERATIONS_H_ diff --git a/src/pipeline.cc b/src/pipeline.cc index d9629c32..df3a98ff 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -40,6 +40,7 @@ using sharp::Composite; using sharp::Normalize; using sharp::Blur; using sharp::Sharpen; +using sharp::Threshold; using sharp::ImageType; using sharp::DetermineImageType; @@ -104,6 +105,7 @@ struct PipelineBaton { int sharpenRadius; double sharpenFlat; double sharpenJagged; + int threshold; std::string overlayPath; double gamma; bool greyscale; @@ -142,6 +144,7 @@ struct PipelineBaton { sharpenRadius(0), sharpenFlat(1.0), sharpenJagged(2.0), + threshold(0), gamma(0.0), greyscale(false), normalize(false), @@ -502,6 +505,7 @@ class PipelineWorker : public AsyncWorker { bool shouldAffineTransform = xresidual != 0.0 || yresidual != 0.0; bool shouldBlur = baton->blurSigma != 0.0; bool shouldSharpen = baton->sharpenRadius != 0; + bool shouldThreshold = baton->threshold != 0; bool hasOverlay = !baton->overlayPath.empty(); bool shouldPremultiplyAlpha = HasAlpha(image) && (shouldAffineTransform || shouldBlur || shouldSharpen || hasOverlay); @@ -686,6 +690,15 @@ class PipelineWorker : public AsyncWorker { image = extractedPost; } + // Threshold - must happen before blurring, due to the utility of blurring after thresholding + if (shouldThreshold) { + VipsImage *thresholded; + if (Threshold(hook, image, &thresholded, baton->threshold)) { + return Error(); + } + image = thresholded; + } + // Blur if (shouldBlur) { VipsImage *blurred; @@ -1216,6 +1229,7 @@ NAN_METHOD(pipeline) { baton->sharpenRadius = To(Get(options, New("sharpenRadius").ToLocalChecked()).ToLocalChecked()).FromJust(); baton->sharpenFlat = To(Get(options, New("sharpenFlat").ToLocalChecked()).ToLocalChecked()).FromJust(); baton->sharpenJagged = To(Get(options, New("sharpenJagged").ToLocalChecked()).ToLocalChecked()).FromJust(); + baton->threshold = To(Get(options, New("threshold").ToLocalChecked()).ToLocalChecked()).FromJust(); baton->gamma = To(Get(options, New("gamma").ToLocalChecked()).ToLocalChecked()).FromJust(); baton->greyscale = To(Get(options, New("greyscale").ToLocalChecked()).ToLocalChecked()).FromJust(); baton->normalize = To(Get(options, New("normalize").ToLocalChecked()).ToLocalChecked()).FromJust(); diff --git a/test/fixtures/expected/threshold-1.jpg b/test/fixtures/expected/threshold-1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2e6ad457ebc91037452b102c85fe97cd52293a2b GIT binary patch literal 882 zcmex=^lOiET&UP@Y7ModgWM?qOlT~kX_QeM|USHnP6LsJ7}2qQZ?I~NC+Fc+7w zhLo6;2Fc+60R}-1h7XJm%#2D5OoEKef{g!@5{jIH^=Er>&6c$!=pq2xt zp1%C&*!r--+kechH~WeG+??{%;_Pm}s%NtwZ*To@?_>7kxApwTqr>Jdexz+^ShWDJ zy^`fd`N3uqm#<$t-BrJI)0=47)$cvNb}ZeqS6$`LnVM@`|3>A;QqAdjoicEe{QqwP E08O!U;{X5v literal 0 HcmV?d00001 diff --git a/test/fixtures/expected/threshold-128-alpha.png b/test/fixtures/expected/threshold-128-alpha.png new file mode 100644 index 0000000000000000000000000000000000000000..5e900feae40f543e57dab4ec49d446deee5277cb GIT binary patch literal 2126 zcmah~c{J2}AO8M+^PBvJ7^7vxWGu;f5o4(=(Wps9){C1%p{&U^Zk8JQNgdZtwp^1G zN^YUtJ6Xn}#pXWT!pHHf@<57886S4?+X>^DX0Q~g5wMuw>b8vKLt#|Nd>yg zxoWAj$eb7z%ew8Kc3?jUZCS3+EmxHBG7ZoXd^h{Qy|L`s9V?(#MPXlgwg~D+zZ}DsMuMP!x-c>5M zH+y1$EI4R$MErX)Vi$7t)L&l`V)sj~fKoT+B?ZQ2zvbc8$C5^AUm`?u^C{D^sp(dm zx}fk#d?~+CUJI-BEF)Xj^j#kc8qb{HL7p~*SZ(ml`iWD|&(#JU(QA#*+=a>L4}RU= z7&!L(SlvX)P%tcUSjI(lPBqJxH&-oQ+roF!rC#;0mYR0IlX{gmmw&`>Z^=r?=lMR8RT1$CNXH z{pL9Q!&?Lo&;DUuZ_#5&pC+jMt!ZpqAya#}HntlCQa@JDpN@?#+5PE)A(?J(I+QsZ z5uWFNy7(N_YuQb&VbGS8Y;%@7Zo7fJep>ab_O2!tR9SMk65Lfi?H^&!F{TeCJ@jfm%x6P=QZv3F=vhvM<6Kk`7HwKNv z(zCPo#UP1yXB;1>;5*k%r})M02?OP=CN^7hzcVON3!}?vMBwT-(WYqFBiBu|MH7NA zJ0C(i(k{Nz!04VZnqOdq8Ht~3@FJUwj4*HyRd@Di0=Da>vUk!OF3rGbWFde92_+FT0lGbD>h+_jQmG-z)@&W{_3`wW7hKBmNAbIkXsuF1UUKw!FP5=pFIN zk03lLqEF-JLCZob3^-L1g<5M?7W%sF=PHTngANk75G`w_2kZ6N6`<<;Tw|zrF$s#N&D;jTHl8k`sg;m2iU**}_N^YHtty;Mq}f^gbE@wDA2FHC^Y z*0J|@U(2~#V_x%?tcC||r%@qwRYzWI-%5rhx7(U`vfTry$U?2kmXv6_xnz(y;ivw3 z1P3Ai{7{u3;1Gnwg0XcW{r-|6Cd0@{(=ELOvF->x%j&8{r@*aW<29?Qr{c+cay3uS z)&4`Y0aokI(m$j@6*bRkkon^UR+N0_HI|%^5RU8aYTV9$#olHdRVr2FFLC{@r?ztm z!e)v}+mhoyMS$1+UcN`k8N( z;0Pj=Y&@nL$3x+F82XqNw1kJwGjN`n`=`eVzLx!}J(0=-BtC~?arYH(38^y@b9<)_ zXRn~XGMZhRCswSXIR;Y9FTRuqVk(j{CgfLCpt+vL3d@u^3uta&wL&#zRt=)Gn^&3# zeYA!sN0E>Y9bOnJJgM0gHZhb1vUIL^?@kOO2q~If?h1~FVY6&>al6c2D~R1wJiS$> zk_fQ}hNrbWc!Fy`H3F>{`zlX2W5{3F&YntUso@-*}sX}CeoDHTwAkg%Q!+HbCxCU6`a!iwNm=IAxA%B{rhI4w`XEP8XL*{3gbNyn%-! ze6plA#VIm#QHicE*oQ}3NR4@|fw5fH1^#x@_i{?~to&I_ zl(3heK9E0?BucnIP_M0!UVOL28$oh>0y2Hy9wdth>i7K9k8lnWhrXG7#Vd9mHT{w> z9@LuOb3i<45{q&5=KAs^pKk)@kp^_FE?Eoia`)3zp1x+x2F%Wv(!gQ;?SX znVW5bp|ZtQ3%+!gtw=3nttD^&dl zw)`(*ak&oU|I2tH^VyR1#Vzze%Z!cK40Y^*&>l(Xmir%#P5MSf|B(rq?67hCt~!3i Lkx_HV_sYKkCO4zY literal 0 HcmV?d00001 diff --git a/test/fixtures/expected/threshold-128-transparency.png b/test/fixtures/expected/threshold-128-transparency.png new file mode 100644 index 0000000000000000000000000000000000000000..a21e9173f26a75cb5b76befd4d185d9482d6ca20 GIT binary patch literal 1083 zcmeAS@N?(olHy`uVBq!ia0y~yU~~YoKX9-C$wJ+|*+7c3z$3Dlfq`2Hgc&d0t^32k z!2H(J#WAE}&f7b8H_cWMVGFqQ^7sCts^D}Zp3W6HbtP+O&oj0)6!;)4Fd3+A@Bo&| zem#bQGxIO90^P)BJoUMuPvh-f$rX1t`b`KDYBF{9VzdpSKynBPa)?aMRc;Q!? zn0LF#yW8%2?n}3NzHPr|MXvm_`g*77p5W*E(ztleB%E*!V_-6_T-ukY!H_(|=-b8G zQ!Xp^e%)D~b>|t=gwR^O8QcfA{>|Ed{(tq-W9Ei;So6+v-t4!o`W|jIf7aIB3@NUO z>MVz!vgN7~BmQNZ5#?G?a4xBh# zDf<4+^Q))+pZ=gA-tc+G%H;VkXBbbdpBx|2Hosu<%!i*PZsoH)s4xvaz500nJhP|A z>?as;22q zY2P$ogzekAcg5nv`Nn@Xi!^-9D&ILh=B2{V$wIbPw>u8xJ}sUVV|?k=%4L7OqE{?B zwJ+(n80P_tt#eft8E@rVwD)mMTh9Bx^|pQTTU!E(&nSOA`+u7mOaB%9PrHBZ+ALT# zXL0rHzOp@+I+lGaE#JX;>6PFr$ycGlZF|3-jrWhba&6;NAEj5ta~JOY@%}n*hjRE` zZE45lJ8zYJSh8!`m3{jznm_s0_xWuNXLh*qfr#qGD_^X>`lkEa+Pf>)8E=a{`({Df z+D}ve&fCB3w(>%z4{`7IWPZzB=U2TrX7A>C|LwN)a~&`|$MZ6qdF}Jqc#B83Wxt8- zmYorj8T&Yg;o83IGp`?7QFrOlAB&?L263nVM!36|HT8?~REGpI+&e9{Eq$BCfsDJq zS24Up=fS?83{ F1ORHcr_ulb literal 0 HcmV?d00001 diff --git a/test/fixtures/expected/threshold-128-transparency.webp b/test/fixtures/expected/threshold-128-transparency.webp new file mode 100644 index 0000000000000000000000000000000000000000..c86a254fb7fc8744b1f7d4b53a78a2f54e7da42b GIT binary patch literal 12188 zcmV;NFJsVBNk&GLF8}~nMM6+kP&il$0000G0000h0RSrj06|PpNS_D*009p${}B1YZad9mAhA0C|Np2Y|7lX9RE^$KI_JA%gcpq4RHm^M(LO z_uM>GI)4D?O62AWp+LEXx*`J7Kf8m-lHV@w1ga}xqUI~eRmGLCaH$!Dl$TryPinm) z3&E98Nl}m#kJp1V>l>4>NVB>mx$?MJG!Rd9$fkYHY!NHO7Y^%w) zpe(hYk>uv3$JxyosDskQjggDU-Hfpv7OU{B=;%gJ61DP6q<;F5&ZK1>GWAc?{DVQS zD9I^s+ykE>Kj6x^_7LsC)bcM$S9(RYCX+-kwY&hY$ep6X)rqmk20W!REhTg}iwn@> zFNmF@QroB^vt4&cmQGQ*tx^g;X(1v(vQ)dM(r%QfW5Q`iZEcN~uQa}?+Z3daV zp=Rh?y`R4#1(NQx+*#T$H|VKLI5aQCa_8B?4m@E)I`SqlqdCA0>Hwf@$)fI14f^&{ zBP14k-lOI8wn0ffqX@WQ8TB5lTcSWxV~hX2^8e+?nxh*OJvMGh~txBhoaONfbCP~$xQ=#k4D@?1Z0yPwpf`_zWr>dZE zj~iW@%#^^lsscrB_$U=TBW!!HjE~&o0!=!OIfa6DO@wrO5dmfCk#Cev)plNpfb-Tl zl$a$dc4TpG?Q)VYb(qx+i2|knkBB)C48kGwf0hv4bTCT32E_h@Mmj)UU~w);dzWw_ z1<({h#gvP!&rW(w5)k`HsJ{Umj8xw%;JF)pg51UpSj>v9ec+O4P(;=914bmp4G#Mw z<)i5+k$+rQfEUU~WWtq`iUJfoo?_RTh7>Ae3{u1trNMPVeZVd%s?{FU&4)Od;&3KV zi9k@fj&WpYp#Zy(DRP8^s9TW4KFST!=foXU>Ec3a-OzZTREca46xH?4tW>bqXslKy z4M2Xc8z{pNGGsUQ)jtrOL*RjMvjCFI55NIf1fD#dP%sKn;TlNL9J49T zB$e{zLl52J3Nqm2_8FW`Nb@vOn}!FHF@oNm) z7sT)+oDU+j9l;r}A}6*jw%c`58-lmUxFNNbDHq2GOSss8W9*+hF3yXm8~OPO4Tb;= z2D0^tUTCtpSf>C@a-Wc6W;IuC&pJKvnLA;+? zY$|d1=TS&bP>jy{lkXsJ7`kVH*rf-D*n}B($y=Ct$CVKk+z}~PcOo^6nR*hyxXonN z)6PK(ywAyRlrI^SNl#(p&wXQ0honYGb16eieFA0$qfgWC@%i075h(Tx?q%OU=G(`t zH1{Bqf z3okHMt~fm8&g95=smg#!SsX=?%dHi)!PU7{K|`PcvGop;n`o#J8+kW&>!s+7I|5U8 z4#alr931Hfl~3@jIl7u@tc)&QL`+dDqXa}q@8B_Stg@EIE4JVE4rECeS7Tk5L+8<5 z{e4nN9}QF`$xhf`Nlv=f!BuI4u@!Dr=?B2Rky8lJ!(k;g%JrWvnn@DYF0NI4z+T12 zv>gG7MClv*#Id_z>{QfO<9N!Ar?XRG?t0ub---m@^|&b-z&j{u)i`!gNQByr(Vlvx zuCaGxNI)eywiL>@q9`fUj5@vMh=LE}r)A+xv zDbhg?h5QS-beJd7SDRCui3jtu@i!z+jmEx+R?hCGzK-Mke z8920lT#&`4`ci!h;!6n}UTMuus%qzdxZb)DQF@(f@pmwZU#qkg$> zeR>`PJ3-i(DA&+RS{Qne6j@jpC#EPzd2g=FuRcmn0vQh6EI+TwDqV}EnF%0w)EB7T zocVa_d@Lr#%bH>4Oueu!2460mahzub2IUD4hqB|oE-^-rMlsr+4|InJE+n)mf(v|H zydm}++Oe;^7P(w7uD>X1nY`0e<%}0qg;+%-h#sn!8iH2WqQBE z(QJgy`ifhYa#Y%;Gl`8Fnxn z5UWz5fVbTXL&|dT)}*SAqeij=0-d~&SRZPeK=6n2b&Q(^QG$f5lcSixAT%YbMicR< zgD|J~P(&A*eQ6XAM&xWnDC#xK^kziaJq#Z*{_hz19Wm|NoaV!Ue@zr_YIWN5Zs=ti z`UmA!K3`LJTB2Q@d3lTJ=+&jU%?Q}x2d&+9Er8f)RXQZ$O}xAyqh9IGcwz()JqNR= z^+VvQ#P*$z4eJp$!A8Ac0RHM>GI(_d$nj!>H~8Q6^^$_w*L&V34FEU_&=<$wg|7Hr z&!hSM1R>}Z91Jf_n0@@yO&OVE(*oY7x5L_;;-h!)WhX_qD`8pTpOoagNC%W%`en5m zP$x8&*UzVR$<31ZAu;3?DH1OR_`=}t5|UDtG~L^1c>sbqbaf0$Pwf!Q(9yd$jWfmR z&8<>2Deg+>!6;xRPua;WL1R?NT&NXhBiU=CAj5Nqp^o@r5axr&jk*ZL ztq^)(XZj=@|ADN_>)~3cF!bBrVR*y4J*W(vU4PZi6pxm6Ho%khEl%yJEWf8NXG1mRaEdIEU8MX%k`sN8QUElZ~yv~ zLc7wakx_C;U4d{O+9~X;hZ5^hMplcRptx!#%o0YX#b&~+^$!|gQ4j!?jKMXClBbc* zB#HQZp%Dr~i&yIKDkY{$Vgg6!=6w0NF!=Qh1X;4dw9SmZ9QU^g=Ck@>v*`PHn>CX> zX#Q)!;FuMbc`DcGV*gJ0lj{|aRwafN1&}{S4gpV}Q`$WvH3cPalCYAXK+nLROZCro zrx6>zwXGmVWr=UaC!2AjBzGcTXH} zO}Tu&Qzt+?T%6*z2bL#Je4s@}KNEruw=J0wNj|m}ze1~^!u|@_bDe_hLlt^DWp%s# zxa)nPZf7n8O>>_!6o>$nsrtbpA|M1lIo^i5P-07siCik~^tbclbMVai2sP?9EE6by zFB}ZMxaxUh{0(0aBV8vx*d`JJxL=p4cHkBbI_8F7g(k#y%p!1Fu_jK30s z$2NmK{5`LF-x@cA%!gz`nf`tcrR5+-n4`AL7V(CGi@-PeO zkaYhO>0&mw^3oOz0dwJOb+3~OD4Glq-TjOR+;B1O6Bg#*Ky-*M8au%f0Nu}q4M8Z+ zQ~yGpynYc4EG;ytne2DLNVWWSJkhGel>mwW0?A|NF5cTEW!H5RM|$@CmCsXygBaZ1 z5dG8?*uxfAaV!xQ3rsB|!!=4pmL_0RDp^JJI6OIdzh%t76_BW4orc;=(}8i0MWm!r zX+J^8DUpZ$Yqr=jkiE`!P)0Cqh$!1ZSdzJaSyUIgB5O{E;y}^`!$+Rg2Oua{Kb42H z$n7_;3=FgdfZ^aezWaWfh8teoDiI%r9?{LBs=QqFOXnrKXx@L#vcb+`>bQq{C5-D# zf5($fW&VRw1%J~6UIY(d(73+*Lb+Fvb#GCy5HsIijFQ9B_F$>@q%J?>hls@2N!_ZT zKuG}iMe^+SI*Y42#+c445jLJQi1PxGtk}|0HhkW5kHe<=)*7y}|F(R0x+rhp4ibTV zw@6%?bi+u7d3qAPUka6e-GY))s@1se6+nqj@pyrQz$MCPYR}2am*94rNg;AexEh93c*J0o7$6M_6PP~Yo)f@f@ zpayAZyx7{?CaJS|-vcPqvfS*VDRik8$?b^ik;QJ$B&%LhNxoYKUmrv+pMxRO7i`|s zKFch^YrmK|{>VxRpp0|AOYk_i-1!^c+eHFfLU}P6_e=ffEm{Z+gw@l! za47h#R%BK3?qFUtekAs2ix=J=8t+Zd3&KXolk>(;Xnly8UuVg!!yh^2LX1ibK>1XS zy~ZbDiV9jcPK1@QR&^KPu3!C(=u_L?;Li~Dr6$KxUGrAt34ahE zH&D7z?SI&a=#m?selYT%?jFOjrDgs{SBc~);S|7Nbb$xeE}L9DSBqAdB?fQabE)dB z{ZAaVQpqRzS7m(qz<9vG-P8y2oW>a(q{Oc~kX|C-1)CRFzWumnJ=g{6d#lbmj_yvl zy2z2)5R(Z%gEwn*39 zPJhPY$p?-no@;P27dp9iB)nS%1Lbx>g`@;i15QlMtg3~bn8bFHfH*XRJT^79*FXn5zmu(R`to)d zuLBONXwcYNbZ1y;uFbz-3Q%pZnYlAjg!Awl0|%enAE_CWX{kMp9i6R3HrtA(9;et0 zM#P*cg|nHG%uc;IK7bPHUAP_v1<2czyC3|Uu#+He-(Y{*2o~izgluzfrFcEqqPurB zFqLyNT{0pB?$;@z|4vCjfX;uG;oa)xBaDpo&d*+N;X>@+jeTb!Dir@?{F}c%7)o6f z%NT#9Da_n~j~F0qlobecVx?E&$lw5+uMG3MK`yW?;Be9j*;K4t$9yd&{3V1hy4#F{ zgP;|X`Eld6?-~s~bW-h2|Ee-4T)W(=%ZU|lXkU1VMek}wmX?Y!+x40@C2sBSf`H9|Th_UMu*!kkh)B1iojATG9S`~dBrZE(A$Pe`3N#*V)GPH7$@u%$7Bl7N(TZzTy0&mzZVs2jCZ^4Zvlohx+q z$9J$QVCF7(HN7ueLR|nYlpR~7dTfwpMB1=T2MU(YaF`6T%`ZBuD<^ZdllD?trjk)E zth6c-%UF-RkuxrkIQ@UK`*X7WI(~~SD&9KN&#;G5Tk5KQJRjWD77+=5j`)?156R92 z2lUUAI$O&V;B1q<)+$+Pxq)9%FI{cbRc~#UYajuhVXWlUmzQlnZFbqPMUV2{eWObo z+>#~nG*V4YQN<#RFhyH-hrly)j|@N{hSI{El&K+tY}z&KaFWBLdvKfC3>?qQ_w0^bG8o?OEXTM;~v%Nxln(1H4-z9x!Ev7F$M zyDQ$Ff2i0SNtrCLOAu@GFjS;rdt}^v;{SjXL)F5#IyO+?Gx?l9chVaVgoty~yMRE0 z%KL^DgQBKmS-YkjeqIxQPc=kOk4Iuc=8W=HJbedJmL7ezVh2nBExG7(2>jx0K3Q}# z?ZF~*L}$v5m*0ZnVbBk-e`vbgR9SJXtR*b%rAu1918*tW?|*S7rMx zV}*Di0GiFIiLQ8!3vIq`*fw_V(wokLYYt^qNffH(Tk--KhXr89^)dCI_G@Ud z^fJdRj{|Ns>=74uoCq2c=f&$pY(u;54I}I(`#oJrQ~GZeFHW(yAR+^Jnx)>d#Y7wt zVo!)Iv~J|OD4_<7ILFk&a19_bk717XKt&#YO2lSDL1G0CB%&Cf=nqG-C>b#0%7y;{ zg)JU`cFm;`0Ugh@IZYleiD}xY&dSL;|4>_X@Gx^xTLlI)HlI9+$Op6fY&9Y$d!x5? zoJ^JfhXwCtX^h(R#q3u?xhN5%2r4B35q4SYQTih^II7MYy>me&rJ{fy81G6zqz}VOF^Cbtm9^Uwpj68B7@io1I%{6e=j@BWMdD%b}@HkeVFBR*ipBKEIBO3vT-k=r zca6WorNdnQ>4xm}F9Zwo^%Li~Q zPdnWq`@-9lW+u7}pbMTg)SS31=B=fV&_P}r9(mmsC2prx^n0LKh>4l>_M_!#Q)-ZO z{liQYj4Sa#98}DrJZqYwkUxl+JGqTLlQeDP!34#GW-xRyD~9wzA%v&i zL*(G2Pr}v{orETXg11}#k&9v488(GIA|C}Mf$tWaYOZf){Y5?U7sQL@7+JimF zc4}^aV;rjhsX~VsAj`rekVBJk_n6m=a4Woh*>2jYENz+Yd@K|&+C%RcEzPxP{fgbx z;R#b|f9(L#LL@9Dvo8cIFKh#Ln}R0PsI(Yod8b&g$nOzqHELVb#$)kF)9#`L{ASXh-;HktMR4X_o>BC zyizPbKIDWqHLMgsTOqX%)ehyxx=~OW-&WNPOlp05Iu#E8oll-Tl-56_UevJ9;=LY% zCY2XQT4c#}*j>UV^;c5_fY&!@na|piU~wF~RPbO6p9^Evt2D5nF4S3q;E7d?aJf&4 z*X&orI#y2sy?f!Zq36s`)JiE7y>urzcC=7}d&tm$S1meq+_G;cEQ@>BT3UyBzazj} zBobI7++uN6(qT%8lb>={`&kbmxUO=lSGM2li+RaSF$~RxDq25X%DFvi(XlYS_*Po#m`HqN4&V!sqw!!#B3!Fi8?gGjEN z=Ii?tpF@t5DB$+1siPu?+M>cgsY3msE*o_ioL-mjX0FYX9`)lD5US_rzh`U|+&|Ke^y2u>Zq;IgI4%v=Um5}u z@Cko{d}oyfsA%_6ujBlQ^N3ycmw#5Yql7x>X+uIwx2fg9(`5r&4ASmt9vD8p8Yr!> zvI|_lQq|*b0%)vZK8@YlZ~I`EJB|S}16;%+kE!Sa5H-eC{L`IC1JUADTtfv&R=kTw zEGftPprP`j{Zmmx)#68>Qex(&)~~>%%`zK`nPinz7er|juxUHmm!&{(SoU}780@h@S{NZsrmP4e3mzO{)1{RDZg9)rx>F?~Tz!^$xo{FG|x*M7P;kI z7zG6*S2yUR!d9g8Ltq_Qnh1RROTWP8U3>*6NOHTQ?aN8=3-73JU;%k(3++@zSGuS9 zFo7lxMVQjUAT&PEa~LkTXe6vCP|ar%ruV{_qlWo4vLxoC%Tq>z$NrapXpLY_pNqsH z|FCG{x+RfzL$J=ArM{-sByI>|yvnM7iZZy-91(`q0@+sYPgQ1M>C`D|Z!AbH0(VvO5!>k)D{^&P1z1#=B+flT zc;L@EN=k^Uo`~RWN&3cjCkF7af?#qMolvCnr94zAY_E{VXIzlk^jUzi4U?M}us^Ap zwYJ#mu6}qn9L%2M(LVQ-03+M3K;5K)gS@T$)tc%I#~=uF!Eh-uJ(_yyGz+S6IewzU zf`u$UeRQas0=gwcghWbR6w4TYr76taF}R!vK@BBf45srVjORA^{HLe8Jo%MLSZqb1 z_y9q9`sl7B`Rnq1HV%_o7P-RgY?guEWTIii#|Rt^#RLwBk49epYD_h~Oxt$z1GK!( zg+)7w39hdv?fjTFDbB72x3iCf2eb3n^$_Ji&T<1ml85t~nHD5lLq2?g@rh+~4TL|r zsbF^sSbEC{qu>WWJ0e#W9ZCi%0lrjNXWLaGdtZ?y+xU*2Q}C9@ED+fD`5z4C0o%nf zo!M?yazY}L4OYF7+P{#{i$7oTCfj!X*+HIWJtI#Op{^MI3`FgCL|6M4-v;jK}Im>+)NN%nX!K+MFvTRjVyu9H$@B1g*N250v)B0nv z{4HC4_PmO9;;}$>D}7T7jL3TUbhlBYc$P04WzLKF42jZU5>~mVv#==Y11CqrUY65! zT{8TP=5zWG^(j_wLg_yWxOCZX6T;K81tJPBP1TWYW2XVc@3qz;FJLD{Rb>uXzY^{AptmR1p4oBqDCP+L17NaFy8 z@v&o`$n^vN#+;rzGsn0;j*ft3josiiSBG~r$p}Fb$f|Zbq{X1zj9v*@^Boi%_EDCV z`cwES!Rb8H%Y&&+*q9Wapu!jwLSL4U{xEoafRM*ftH}aSA3|7GD@LSK&|{Vh9sQ$x z0m2K0yxlzkDPzaeZRbq4XG}?B^Qu%PAI%juk`4#@DhPsZ<%F_~&dD=EeF>mMBs&d9 zyC@gwaAcyL;RU)$L-x=ej>g-(ZzNxzrAn6cwzhCRJay&yyS(z7GBjbv&N%QvvnOw+ z2KpMt_)~N<=kTnV(m@k$Rwy&#QZ?&L`v+7AYquTfB{X~@b+H>LtlbPY;}iRfRESaS z^cTd0kXsAx~_dyy`3Yn@+qO@Mvh)q|6d^`AJmz zFh=^K4X|lJx@Wm$4y@|K?+upH3w{XWoa*rf5KcT+g|}I4uqx51MyyOcfqG&0s8q%k zNW20dS|<_s1cRXPwg>=zYr6XB;Rf!2R$#LW%hj1at|jVMA)gqp?~dQ^NUP>iq2hB9 z&$$+1>qSes==6)jZpS3Q&WK~}jnUN{#=qZVtclWAbX(QU_C+tL$nfH9#3o({`3Cd=;?!A9gCF8 zO$N?uV>bhEiaPl|^7nPtmo1yU;TH{1&hmQ<fQu7F?)#=fK53;;IIyv8{G{+Tmew zJf3CM_Y1}2Ai`i+f~yhcA2XVEkxpNTnL#d52UNL!Xg{c01{L-i7xC*Z@Gwy~MMoRLl)nIa)2 zgR14`6`t(k5gTL>Mb3I= zS)SNt7`>)arxc1O4&~N|hT(eyc0BF~!#FYIHjj4J-6+xRc zUDWzYYNJqHDj~7*`=BKwRhc`3=#rs^6}|oFYyy-|+v#|bOs(3+Zv$iAp#O7Y+n{T~ z9inCXOpq4?Lii9*gbLTzP7+Chi9&Gg=T!JPEzZs`2@b!F(-1P0#7(Kw9q3ENMbEUk zAqjmms4%os(Xdhha*h{AxWf}Q!A3I~eha)*+Xvk!vXmKdz4gOj)A($)J26TpfH%7f zrp}dNJdws1H=kXFIS1kcEeRQJM|g66Uqti^ybAvJs)@(W=*2<+ z60YY(=pKt#oYJ zBA%|rbPRIl#`nR>D5>rPD>Lk=EY(F0Jtq^7 zcDt()`Wt7I`H304mYm!oS;E9F|Dpm{#YC{_tF_&^^^Y3nq*sG_!Y9qle83`JV*Ekw zysl?bXnR+<_4wdA<3|gCWQLlkNu|s)(`OS^1mw}*kl6xve?@J5^)vToOph4~d z)Zg?dy&H8nHUo35{xCBNv$iYpFL<+P(PfrOP0*mq{;MuN=Fe_k17^>#PxfnRIPyw_ z>}Nhjray9p;`O**>5ozve4Q^?HdGEf%9c4pm-w|pY$029Z`7$Y6iZli<)OeTOxbV* zaNg&E<(9{80Bqyd{AkbRtis~EheI3@2jEyRqGsitIa>)H>{MtsG1rIM_+D$$bR8P~6n%dWvB z*ux(QYb^AV1(tYu&-ndlnbKu3dW3eA1V;0BoH;7q%9K-2Zd-pQ#CseP21nX+ZJ(a~ z{8R99%u215sub~s+*c{S7&OXK7@k9Tw}64_aMrTasU+jFRaattA-ht6DSXI9#;c)L zV*ER0rP1*b)b0+W-XRiftfxoGAJG^M=UZti&o52h1>IrL&3(=7|Y5nxlYx`C~r6ZfI%up;FuiDEV z_R#Y!$6Y6t;M5-r6{RAY@ftu7y#jDovk!=KizfLbi`x=}*D#PvCZu9ZEB~qUC|K~F e82Xcr^CLz;2DE|{I~>2)QS*E0?Y1Z)KmY&@vY);H literal 0 HcmV?d00001 diff --git a/test/fixtures/expected/threshold-128.jpg b/test/fixtures/expected/threshold-128.jpg new file mode 100644 index 0000000000000000000000000000000000000000..4075277715d3f122330cd6cf410f4a56d00d4516 GIT binary patch literal 14814 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

&E?=v(yb=GFk2Q=}v`Po41W zTABm1QHGds37O|SDy>!Xm7)M{(#{XV%Rq>Fuzri-NtIRf8B=PWa(+{qLU2rq(8aXw z2c-BcE8SWb7-GUe@_%ExobZDERXA9Ndh zlLN%2WVEJH9-|TF+F|p)Rgv4^tmtuWIr`wClGU{ZgHp7AD>V0c0zk9)2A6TQTWF=Z z4RsN~+#(FiH@HVPj+n}^w2p%~yp>Lh6%KcCKrLW2RRnHDza6K?)qUOZcGULY zAfMv_hvLlss@)6^!hR~OUl4D*Pk~-OQfr5Jw2>FMn)~c&G0PS#TR}z!hgCMPrVhx0 ze(Q5DS^ZtKIcvj=FsipcV?t3Y#u5=Bl2lINHRsVi+zttliCweNe(~Z^?N=j8W3ePW}R^>@haC{m(oDPy@f{munMaIS2?YrXTp+FeE_WyW14X+`Zk z;Ks!*x01#foZ(?tAl%WjfJia^c;k~H%GyeiGYCsb+UlB#aQboEo8G!T#q+A=rlnG1 zGjRm2QM+ro*41!2uxShp_2jq92z@uA+g|>SfBTU^`CcHEIe#`_skNyj`|pCQ!(0`Sp`OIeY!F2FxkK<&(_ zv-c2chF|XJFAs}-si^R6YmN|M<^7o49)dhbGdmQ;cSZ6MjVW)HR$V(TIe~- zJb1*w_9DfYxCD@*+Xgn$GBOi7dqui!`~+}RG^eJMz>TUsaueH`Yz?ku zOaHkbcc{pkGdC?7v^&cbzV`C#dZv=wI|Yw&FuGDkNm2)KXB1~Djk#Ce#|TI%X1yz@ zS}~cl_r{z5I`hK|r7~5GIKyvEqnDlTx!)bL2!xd6B@QWy3+pMPusB)vp~$3FG8?oI zNevH@4MH7*;iR9vxjBu(KXI$DOC2~KmYPQdDnDre#yX>I%> za}xF`K!gY&hCBXt?V~#P3VLgH<#r~>>d-355H+c+3+WR_G=q~3+s3Kn9Bs8+`njZD z^oaG(XP^pq4Rz1>K;00XXr$PqRuJ)}dD&7M1%B88%siOoj`Px3ANV;tFVSsyWFn&hrXBCAZZ!C%g5}R2c zmNsVsSqE>i<#PcP%e>o%JA=B;d$N#S$oLwUYcbCXFC6pu8`jy+jD1ar=%XN+e_uW1 zJP<@tS#78GX)Dl?B4);$uw7o+yupf@1G;?0YIQV+J@edZ40f^$w|TiQVv}6>+#E*m zkt2XMLlVUy70N)^xZZ8s^4ylNUUg`+N8>z;1zu5UdtC3~-$BD2sqSskzWXBWrWgAe zKO+$=qA=vc!v37vv=i~Aw6zl0S6b7bXxb{l;n9*%zf498 z9jsk-!^+4MV?>*f+a-LdyquC-t&hm~RsfzU71J0&k_JD=pTM@wpo*EC*I)TOxuv+q zG-_9k40kP%Dc4GUJ|==i~4D55@W|RYMj-EJ3eBZeK$ae%FCLW=OR4vY5D&EKvzhy literal 0 HcmV?d00001 diff --git a/test/fixtures/expected/threshold-40.jpg b/test/fixtures/expected/threshold-40.jpg new file mode 100644 index 0000000000000000000000000000000000000000..edc5795d52d2ed7211f68042862ab67be7f49800 GIT binary patch literal 16299 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 literal 0 HcmV?d00001 diff --git a/test/unit/threshold.js b/test/unit/threshold.js new file mode 100644 index 00000000..61a62a32 --- /dev/null +++ b/test/unit/threshold.js @@ -0,0 +1,105 @@ +'use strict'; + +var assert = require('assert'); + +var sharp = require('../../index'); +var fixtures = require('../fixtures'); + +sharp.cache(0); + +describe('Threshold', function() { + it('threshold 1 jpeg', function(done) { + sharp(fixtures.inputJpg) + .resize(320, 240) + .threshold(1) + .toBuffer(function(err, data, info) { + assert.strictEqual('jpeg', info.format); + assert.strictEqual(320, info.width); + assert.strictEqual(240, info.height); + fixtures.assertSimilar(fixtures.expected('threshold-1.jpg'), data, done); + }); + }); + + it('threshold 40 jpeg', function(done) { + sharp(fixtures.inputJpg) + .resize(320, 240) + .threshold(40) + .toBuffer(function(err, data, info) { + assert.strictEqual('jpeg', info.format); + assert.strictEqual(320, info.width); + assert.strictEqual(240, info.height); + fixtures.assertSimilar(fixtures.expected('threshold-40.jpg'), data, done); + }); + }); + + it('threshold 128', function(done) { + sharp(fixtures.inputJpg) + .resize(320, 240) + .threshold(128) + .toBuffer(function(err, data, info) { + assert.strictEqual('jpeg', info.format); + assert.strictEqual(320, info.width); + assert.strictEqual(240, info.height); + fixtures.assertSimilar(fixtures.expected('threshold-128.jpg'), data, done); + }); + }); + + it('threshold default jpeg', function(done) { + sharp(fixtures.inputJpg) + .resize(320, 240) + .threshold() + .toBuffer(function(err, data, info) { + assert.strictEqual('jpeg', info.format); + assert.strictEqual(320, info.width); + assert.strictEqual(240, info.height); + fixtures.assertSimilar(fixtures.expected('threshold-128.jpg'), data, done); + }); + }); + + it('threshold default png transparency', function(done) { + sharp(fixtures.inputPngWithTransparency) + .resize(320, 240) + .threshold() + .toBuffer(function(err, data, info) { + assert.strictEqual('png', info.format); + assert.strictEqual(320, info.width); + assert.strictEqual(240, info.height); + fixtures.assertSimilar(fixtures.expected('threshold-128-transparency.png'), data, done); + }); + }); + + it('threshold default png alpha', function(done) { + sharp(fixtures.inputPngWithGreyAlpha) + .resize(320, 240) + .threshold() + .toBuffer(function(err, data, info) { + assert.strictEqual('png', info.format); + assert.strictEqual(320, info.width); + assert.strictEqual(240, info.height); + fixtures.assertSimilar(fixtures.expected('threshold-128-alpha.png'), data, done); + }); + }); + + if (sharp.format.webp.output.file) { + it('threshold default webp transparency', function(done) { + sharp(fixtures.inputWebPWithTransparency) + .threshold() + .toBuffer(function(err, data, info) { + assert.strictEqual('webp', info.format); + fixtures.assertSimilar(fixtures.expected('threshold-128-transparency.webp'), data, done); + }); + }); + } + + it('invalid threshold -1', function() { + assert.throws(function() { + sharp(fixtures.inputJpg).threshold(-1); + }); + }); + + it('invalid threshold 256', function() { + assert.throws(function() { + sharp(fixtures.inputJpg).threshold(256); + }); + }); +});