Convert images to black or white (No grey)
Using NodeJS (>18), you can achieve this easily.
Using the package named sharp
.
Setup
npm init -y
npm install sharp
Images that are already grey-ish
Create an index.js
file.
const sharp = require("sharp");
// Works with .jpg and .png files (tested only these two.)
const src = "image.png";
(async () => {
await sharp(src)
.greyscale()
.linear(1, 0)
.png({ colors: 2 })
.toFile(`bw-${src}`);
})();
Change the src
variable to your image, and run the script using : node index.js
The converted image will be prefixed with bw-
You can tweak the linear value
to change the amount of white vs black pixels. (I tested between 1 to 6 and having pretty good results)
I tested that solution with images that are mostly already black and white.
Images with colors
index.js
(async () => {
await sharp(src)
.gamma(1)
.greyscale()
.linear(2.5, 0)
.png({ colors: 2 })
.toFile(`bw-${src}`);
})();
This code is preferable when your image have more colors (more than grey-ish colors),
You need to tweak the gamma (between 1 to 3), the linear value (between 1 to 10) to get good results.
The dithering effect is quite nice. If you do not want the dithering effect at all (yes you will loose details), you can try that snippet:
index.js
(async () => {
await sharp(src)
.sharpen()
.greyscale()
.gamma(1)
.linear(1, 0)
.png({ colors: 2 })
.median(3)
.threshold(128)
.toFile(`bw-${src}`);
})();
Yet again, you have to tweak the gamma
, linear
, median
and threshold
values
You can also try to reorder the manipulation, but so far it was the best output I had...
If you have a bunch of images to process you can create a loop and go through all of your images quite easily and quickly !
You can also create arrays for each parameters and loop for values, this way you can generate alternate output automatically.