HTML5/CSS/JavaScriptのみを使用してFlash/ActionScriptのように画像の色を変更する方法はありますか?
Flashの例を次に示します。 http://www.kirupa.com/developer/actionscript/color.htm編集:これは、複製したいプロセスです。
私はこのようなことを達成しようとしています(色の変化の側面、照明と影の保持): http://www.acura.com/ExteriorColor.aspx?model=TL 新しいものをロードして交換することなく毎回画像;色調を簡単に変更できるようにしたい(つまり、純粋なHTML5/CSS/JSメソッドを実行する)。 編集:これは私が達成したい結果であり、プロセスではありません。
基本的に、画像の他の側面(グラデーション、照明など)を維持しながら、画像のパレット/トーンを変更したいと思います。私は近づきましたが、十分に近づいていません。イメージマスクを使用して、元のイメージの上にそれを合成するようになりました(透明なイメージオーバーレイのようなものです)。以下にいくつかのサンプルコードを示します(これは単なるスニペットであるため、機能する場合と機能しない場合があります。サンプルコードのみを表示しているので、何をしようとしているのかがわかります)。
<div id='mask'>
<canvas id='canvas' width='100' height='100'></canvas>
</div>
<button data-rgba='255,0,0,0.5'>red</button>
<button data-rgba='0,255,0,0.5'>green</button>
<script>
foo = {};
foo.ctx = jQuery('#canvas')[0];
foo.ctx_context = foo.ctx.getContext('2d');
foo.mask = jQuery('#mask')[0];
foo.img = new Image();
foo.img_path = '/path/to/image_mask.png'; // 100px x 100px image
foo.changeColor = function(rgba){
foo.ctx_context.clearRect(0, 0, 100, 100);
foo.ctx_context.fillStyle = 'rgba(' + rgba + ')';
foo.ctx_context.fillRect(0, 0, 100, 100);
foo.ctx_context.globalCompositeOperation = 'destination-atop';
foo.ctx_context.drawImage(foo.img, 0, 0);
foo.ctx_context.css({'background-image': "url(" + foo.ctx.toDataURL("image/png") + ")"});
};
jQuery("button").click(function(){
foo.changeColor(jQuery(this).attr('data-rgba'));
});
</script>
このアプローチを使用する際の主な問題は、画像が非常にフラットに見えることです。他に何か足りないものがあるか、私が使用しているマスク(白一色の不規則な形の画像)は間違ったアプローチです。
この関数では、イメージをロードする必要があり、同じドメインからのものである必要があります(クロスドメインポリシーのため)
function tintImage(imgElement,tintColor) {
// create hidden canvas (using image dimensions)
var canvas = document.createElement("canvas");
canvas.width = imgElement.offsetWidth;
canvas.height = imgElement.offsetHeight;
var ctx = canvas.getContext("2d");
ctx.drawImage(imgElement,0,0);
var map = ctx.getImageData(0,0,320,240);
var imdata = map.data;
// convert image to grayscale
var r,g,b,avg;
for(var p = 0, len = imdata.length; p < len; p+=4) {
r = imdata[p]
g = imdata[p+1];
b = imdata[p+2];
// alpha channel (p+3) is ignored
avg = Math.floor((r+g+b)/3);
imdata[p] = imdata[p+1] = imdata[p+2] = avg;
}
ctx.putImageData(map,0,0);
// overlay filled rectangle using lighter composition
ctx.globalCompositeOperation = "lighter";
ctx.globalAlpha = 0.5;
ctx.fillStyle=tintColor;
ctx.fillRect(0,0,canvas.width,canvas.height);
// replace image source with canvas data
imgElement.src = canvas.toDataURL();
}
マークアップが次のようになっていると仮定します。
<img id='myimage' src='image.jpg'/>
次のパラメーターを指定して呼び出すことで使用できます。
tintImage(
document.getElementById('myImage'),
"#550000" // for a redish tint
);
ここでの作業例: http://jsfiddle.net/pHwmL/1/
確かに、ピクセルデータを取得し、HSV調整を行うことができます。必要なメソッドはgetImageDataです(通常のjs配列ではなく、UInt8Arrayを返します)。
素敵な記事があります ここ これで始められるはずです。透明なキャンバス要素を互いに重ねることができます。これにより、ベースコンポーネント(車の例では、タイヤ、窓など)の調整に関する問題を回避できます。