6

だから私が自分自身のために作った挑戦はそのようなものです.

ソース写真があります:

ソース写真

色の値をマッピングし、div を使用してピクセル化された表現を作成していること

結果は次のとおりです。

結果写真

私がこれを達成しているコードは次のとおりです。

'use strict';

var imageSource = 'images/unicorn.jpg';

var img = new Image();
img.src = imageSource;
var canvas = $('<canvas/>')[0];
canvas.width = img.width;
canvas.height = img.height;
canvas.getContext('2d').drawImage(img, 0, 0, img.width, img.height);
var context = canvas.getContext('2d');

console.log('img height: ' + img.height);
console.log('img width: ' + img.width);

var pixelDensity = 70;

var timerStart = new Date();


for (var i = pixelDensity/2; i < img.height; i += (img.height/pixelDensity) ) {
    $('.container').append($('<div class="row">'));
    for(var j = pixelDensity/2; j < img.width; j += img.height/pixelDensity) {
        var value = context.getImageData(j, i, 1, 1).data;
        var colorValue = 'rgb(' + value[0] + ', ' + value[1] + ', ' + value[2] + ')';
        $('.row:last').append($('<div class="block">').css({'background-color' : colorValue}));
    }
}

var timerStop = new Date();

console.log(timerStop - timerStart + ' ms');

pixelDensity 変数は、カラー サンプルがどの程度接近しているかを制御します。数値が小さいほど、サンプル数が少なくなり、結果を生成するのにかかる時間が短くなります。数を増やすと、サンプルが増え、関数の速度が大幅に低下します。

何がこれほど長い時間をかけているか知りたいです。画像データをはるかに高速に処理する、わずかに類似したプロジェクト (特にJscii ) を見てきましたが、パフォーマンスが向上している違いが何であるかはわかりません。

ご協力いただきありがとうございます!

4

4 に答える 4

1

主な問題は、ループ内のページにDOM要素を追加することです。実際にページに追加する前にすべてのデータを使用してラッパー要素を作成すると、これははるかに高速に実行されます。

編集: 私はあなたがcontext.getImageDataすべてのピクセルを要求していることにも気づきました、これはほとんどの時間かかるものです。代わりに、画像データを変数にキャッシュし、そこから色の値を取得する必要があります。@Travis Jが述べたように、ループ条件をキャッシュして丸める必要もあります。

var wrapper = $('<div class="container">');
var imgData = context.getImageData(0, 0, img.width, img.height).data;
var getRGB = function(i) { return [imgData[i], imgData[i+1], imgData[i+2]]; };
var start = Math.round(pixelDensity/2),
    inc = Math.round(img.height/pixelDensity);

for (var i = start; i < img.height; i += inc) {
    var row = $('<div class="row">');
    for(var j = start; j < img.width; j += inc) {
        var colorValue = getRGB((i * (img.width*4)) + (j*4));
        row.append($('<div class="block">').css({'background-color' : 'rgb('+(colorValue.join(','))+')'}));
    }
    wrapper.append(row);
}

$('body').append(wrapper);

これにより、時間が6〜9秒から600〜1000ミリ秒に短縮されます。jqueryの代わりにプレーンなjavascriptを使用してDOM要素を操作し、さらに高速化することもできます。

于 2013-01-31T19:22:18.240 に答える
1

たくさんの div を作成する代わりに、結果をキャンバスに描画することを検討してみませんか? 理論的には、はるかに高速なはずです...

于 2013-01-31T19:12:03.847 に答える
0

私は以前に同様の速度の問題を抱えていました-時間がかかる理由は、テキストの形式でHTMLを与えることによって要素を追加しているためです。つまり、毎回そのテキストを解析する必要があります。JavaScript DOMを使用して新しい要素を追加すると、速度が大幅に向上します。

編集:この方法で新しい要素を作成することに慣れていない場合、構文は次のようになります。

var newPixel = document.createElement('div');
newPixel.style.height = 3;
newPixel.style.backgroundColor = 'black';
// etc...
parentElement.appendChild(newPixel);
于 2013-01-31T19:15:41.250 に答える
0

jqueryルックアップの数を減らすことで、いくらかスピードアップできます。たとえば、最初のループを開始する前に、次のようにします。

var $container = $('.container');

これで、毎回コンテナを検索する必要がなくなります。

また、行を作成するときは、同じトリックを使用して「row:last」ルックアップを回避します。

var $row = $('<div class="row">');
$container.append($row);
...
$row.append($('<div class="block">')...
于 2013-01-31T19:17:13.810 に答える