2016-06-26 10 views
2

画像を、2(モノクロ/白黒)から256(フルグレースケール)までの可変数のグレースケールに変換したい場合は、 。イメージをグレースケールの可変数に変換する

私はこれを、CSSフィルタとsvgフィルタの両方で達成しようとしました。 CSSで:

filter: grayscale(100%) 

は、私は階調数を制限しない

filter: grayscale(10%) 

のように256の階調が、他の値のためにしたいが、唯一の数を減らしたいものです階調の画像を変換し、ピクチャに使用されている色の数が多いため、これらのフィルタを使用してモノクロの結果を得ることはできません。

ありがとうございました。

+0

最初にイメージを取得してキャンバスに描画し、ピクセルのRGB値に1つずつアクセスすることができます。次に、Y(輝度)は、式「Y = 0.299 * R + 0.587 * G + 0.114 * B」で計算され、計算されたYがピクセルごとにR、G、Bの場所に挿入されます。 – Redu

+0

将来的には、以下の解説のように、この技術を達成しようとしていることを「量子化」といいます。 –

答えて

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> 

10の値のグレースケールのためのフィルタは、次のようになります

<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を入力されるように範囲の適切な数で書くことかわった。

+0

ありがとう、これは私が望んでいた解決策のタイプでした!私はあなたがJavaScriptを使ってtableValuesを提案し修正すると、フィルタはCSSを使って画像に適用されます。これはChromeでうまく動作しますが、Firefoxでは何もしません。 – dlkmp

+0

コードを見ることなく、接頭辞の問題だと思います。 Firefoxは接頭辞なしのフィルタを使用します(Firefoxでは-moz-filterはありません)。 –

2

私は示唆している:

  1. は色の数を減らす視覚的に魅力的な因子
  2. によって重み付け各カラーチャンネルを組み合わせることによってグレースケールにキャンバス画像データを縮小キャンバス
  3. から<image>又は<svg>描画最も近い色に丸めることにより、[0, 255/(n-1), 255/(n-2), ..., 255]
  4. キャンバス画像データを必要に応じて<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>にリサイズリスナーを添付し、結果のグレースケール画像を表示するそれぞれの次元のキャンバス要素で動的にオーバーレイします。

サンプル画像:

Sample picture

+0

あなたのソリューションもありがとう。私はJavaScriptですべてを手作業でやることを避けることを望んでいましたが、これはおそらくブラウザーに依存しないソリューションです。 – dlkmp

関連する問題