Javascript - 图像数据处理和div渲染

tyl*_*vis 6 javascript jquery canvas

所以我为自己创造的挑战就是这样.

我有一张来源照片:

来源照片http://f.cl.ly/items/012t1M250f0T101F2L0n/unicorn.jpg

我正在映射颜色值并使用div创建它的像素化表示

这是结果:

结果照片http://f.cl.ly/items/2t1F2Q0Y2w0K250L0t0v/Screen%20Shot%202013-01-31%20at%2010.52.19%20AM.png

我正在完成的代码是:

'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');
Run Code Online (Sandbox Code Playgroud)

pixelDensity变量控制颜色样本的接近程度.数字越小,样本越少,产生结果的时间越少.当您增加数量时,样本会上升并且功能会大幅减慢.

我很想知道是什么让这件事花了这么长时间.我看过稍微类似的项目 - 最着名的是Jscii--它可以更快地处理图像数据,但我无法弄清楚提供增加性能的区别.

谢谢你的帮助!

dim*_*sic 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);
Run Code Online (Sandbox Code Playgroud)

这会将时间从 6-9 秒减少到 600-1000 毫秒。您还可以使用纯 JavaScript 来操作 DOM 元素而不是 jquery,以使其更快。