Closed yhc-yhc closed 6 years ago
"Remove blue color from an image" can mean a couple of things. But you can do color manipulations per channel. The example below would mess with just the blue channel.
image.color([
{ apply: 'blue', params: [ <amount> ] }
]);
Where <amount>
is a value between 0 and 255.
I am not sure if you will get the desired effect from that. But, you have other actions to mess with using the same image.color
call. eg: hue
or spin
, tint
, mix
, xor
. There's some more details in the README and some examples in test/color.test.js
@steffkelsey like this picture, how can i conversion the blue pixel to transparent, i test the code image.color([*]) can not work well.
@theill @aurium @natecavanaugh @katzj can you help me?
I think the best way to accomplish this is to calculate the distance between the color you want to replace and the color of each pixel in the image, and, if that distance is smaller than a threshold, replace the color.
import Jimp from 'jimp';
Jimp.read('./green.png').then(image => {
const targetColor = {r: 60, g: 171, b: 118, a: 255}; // Color you want to replace
const replaceColor = {r: 0, g: 0, b: 0, a: 0}; // Color you want to replace with
const colorDistance = (c1, c2) => Math.sqrt(Math.pow(c1.r - c2.r, 2) + Math.pow(c1.g - c2.g, 2) + Math.pow(c1.b - c2.b, 2) + Math.pow(c1.a - c2.a, 2)); // Distance between two colors
const threshold = 32; // Replace colors under this threshold. The smaller the number, the more specific it is.
image.scan(0, 0, image.bitmap.width, image.bitmap.height, (x, y, idx) => {
const thisColor = {
r: image.bitmap.data[idx + 0],
g: image.bitmap.data[idx + 1],
b: image.bitmap.data[idx + 2],
a: image.bitmap.data[idx + 3]
};
if(colorDistance(targetColor, thisColor) <= threshold) {
image.bitmap.data[idx + 0] = replaceColor.r;
image.bitmap.data[idx + 1] = replaceColor.g;
image.bitmap.data[idx + 2] = replaceColor.b;
image.bitmap.data[idx + 3] = replaceColor.a;
}
});
image.write('transparent.png');
});
Image output:
@czycha thank you, but if i has many of this picture, the value of threshold must be changed to adapt each picture, so is any good ideas?
Unless you do some machine learning (which I haven't seen with Jimp), there's not much you can do about it. You can test manually on a bunch of sample inputs to try and find an optimal threshold.
I didn't realize you were trying to do background removal. It's just a completely different algorithm. You can find some examples if you look up Primatte Chromakey Algorithm. Also you can ness around with other algorithms using OpenCv and look for blue / green screen examples. I think you're not going to be satisfied with anything from Jump.
If you MUST do this in browser, I would recommend checking out WASM wrappers of OpenCV. Then you can run at closer to native speed and have all the algorithms you need abstracted for you. JIT JavaScript is just going to be too slow for this kind of thing right now. You need real threading
@czycha thank you, @steffkelsey yes , i do it at backend use Jimp with nodejs. I have another way that is use openCV to resolve this problem, but it may be must use machine learning yet, because in openCV the params also need changed to work well, thank you.
machine learning is just a bit out of scope for jimp ;) closing, but feel free to add ML to jimp if you ever get that working
Guys, I've created a small package for replacing color with another one pixel by pixel. I'll allow myself to share it with you. The package is called replace-color
and it implements one of the best color difference algorithm - CIEDE2000.
Image output:
@turakvlad did you build that to only change one hex code color? Or a range of colors?
@master-of-null, hey.
It works for one color only right now, but you can run a few iterations to change a range of colors.
I want remove blue color in a image, can jimp do this ?