9

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>

このアプローチを使用する際の主な問題は、画像が非常に平坦に見えることです。他に欠けているものがあるか、使用しているマスク (白​​一色の不規則な形の画像) が間違ったアプローチです。

4

3 に答える 3

14

この関数では、イメージをロードする必要があり、同じドメインからのものである必要があります (クロスドメイン ポリシーのため)。

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/

于 2012-11-15T15:59:51.387 に答える
3

確かに、ピクセル データを取得して、HSV 調整を行うことができます。必要なメソッドは getImageData (通常の js 配列ではなく UInt8Array を返します) です。

ここに、あなたが始めるべき素晴らしい記事があります。透明なキャンバス要素を互いに重ねることができます。これにより、ベース コンポーネント (車の例では、タイヤ、窓など) を調整する際の問題を回避するのに役立ちます。

于 2012-04-09T16:36:03.803 に答える
-2

通常、画像をピクセルごとに変更するようなことは、ブラウザにとって非常に重いため、サーバー側で行うことです。Acura Web サイトの場合、難しいことは何もありません。さまざまな JPG がたくさんあるだけです。Processing.js を調べることもできます。

于 2012-04-09T06:21:11.603 に答える