我想将图像转换为可变数量的灰度,这个数字可由用户配置,范围从2(单色/黑白)到256(全灰度)。
我试图用css和svg过滤器完成此操作,例如在CSS中:
CREATE TABLE IF NOT EXISTS `wp_rdp_category_images` (
`id` int(12) NOT NULL AUTO_INCREMENT,
`category_name` varchar(32) NOT NULL,
`category_image` varchar(64) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=22 ;
INSERT INTO `wp_rdp_category_images` (`id`, `category_name`, `category_image`) VALUES
(1, 'natuur', 'natuur1.jpg'),
(2, 'natuur', 'natuur4.jpg'),
(4, 'aarde', 'aarde3.jpg'),
(5, 'sport', 'sport2.jpg'),
(6, 'aarde', 'aarde3.jpg'),
(7, 'auto', 'autogrijs.jpg'),
(8, 'auto', 'autowit.jpg'),
(9, 'auto', 'autoblack.jpg'),
(10, 'auto', 'autoroodzwart.jpg'),
(11, 'aarde', 'aarde1.jpg'),
(12, 'aarde', 'aarde2.jpg'),
(13, 'sport', 'sport4.jpg'),
(14, 'sport', 'sport3.jpg'),
(15, 'sport', 'sport1.jpg'),
(16, 'natuur', 'natuur2.jpg'),
(17, 'natuur', 'natuur3.jpg'),
(18, 'people', 'people1.jpg'),
(19, 'people', 'people2.jpg'),
(20, 'people', 'people3.jpg'),
(21, 'people', 'people4.jpg');
将图像转换为灰度,这就是我想要的256灰度,但其他值如
filter: grayscale(100%)
不限制灰度的数量,但只减少图片中使用的颜色数量,因此我永远无法使用这些滤镜获得单色效果。
感谢您的帮助。
答案 0 :(得分:2)
我建议:
<image>
或<svg>
绘制到画布[0, 255/(n-1), 255/(n-2), ..., 255]
<image>
。
function rgbaToNGrayscales(src, numScales) {
var d = (numScales - 1) / 255,
inv_d = 1 / d,
round = Math.round;
for (var i = 0; i < src.length; i += 4) {
src[i] = src[i + 1] = src[i + 2] = round(((src[i] * 4899 + src[i + 1] * 9617 + src[i + 2] * 1868 + 8192) >> 14) * d) * inv_d;
}
}
var source = document.getElementById("source");
var target = document.getElementById("target");
var slider = document.getElementById("slider");
slider.addEventListener("input", function(event) {
var canvas = document.createElement('canvas'),
context = canvas.getContext('2d');
canvas.width = source.width;
canvas.height = source.height;
context.drawImage(source, 0, 0);
var imageData = context.getImageData(0, 0, canvas.width, canvas.height);
rgbaToNGrayscales(imageData.data, slider.value);
context.putImageData(imageData, 0, 0);
target.src = canvas.toDataURL();
});
<input id="slider" type="range" min="1" max="10" value="0">
<image id="source" crossOrigin="anonymous" src="http://cors.io?u=http://i.stack.imgur.com/kTjOI.png">
<image id="target">
此算法速度非常快,但如果原始图像中没有颜色落入指定的颜色范围之一,则生成的图像可能会少于指定的颜色数。在这种情况下,您需要more advanced color quantization algorithm such as median cut。
根据您的需要,将调整大小的侦听器附加到<svg>
并使用相应尺寸的画布元素动态覆盖它,以显示生成的灰度图像。
样本图片:
答案 1 :(得分:2)
您可以使用SVG过滤器执行此操作,但在Internet Explorer中限制为最多64个值。直黑/白色的过滤器是这样的:
<filter id="greyscale-posterize" color-interpolation-filters="sRGB">
<feColorMatrix type="saturate" values="0"/>
<feComponentTransfer>
<feFuncR type="discrete" tableValues="0 1"/>
<feFuncG type="discrete" tableValues="0 1"/>
<feFuncB type="discrete" tableValues="0 1"/>
</feComponentTransfer>
</filter>
十值灰度的过滤器将是:
<filter id="greyscale-posterize" color-interpolation-filters="sRGB">
<feColorMatrix type="saturate" values="0"/>
<feComponentTransfer>
<feFuncR type="discrete" tableValues="0 .1 .2 .3 .4 .5 .6 .7 .8 .9 1"/>
<feFuncG type="discrete" tableValues="0 .1 .2 .3 .4 .5 .6 .7 .8 .9 1"/>
<feFuncB type="discrete" tableValues="0 .1 .2 .3 .4 .5 .6 .7 .8 .9 1"/>
</feComponentTransfer>
</filter>
在输入更改时,使用JavaScript在适当数量的范围内写入。