2010-09-18 3 views
1

Я не могу понять, почему это не работает. Я рисую изображение на холст, использую getImageData, манипулирую пикселями, а затем сохраняю этот массив пикселей на потом. Когда я буду готов нарисовать эти пиксели позже, я использую createImageData на другом холсте с одинаковым размером, задав свойство данных объекта изображения ImageData в массив пикселей, которые я сохранил, а затем вызовите putImageData. Результат: данные сохраненного массива не назначены объекту ImageData. Ниже приведен код для тестовой страницы:HTML5 Canvas ImageData assigning weird

<!DOCTYPE html> 
<html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en-US' lang='en-US'> 
<head> 
<meta http-equiv='content-type' content='text/html;charset=UTF-8' /> 
<link rel="stylesheet" type="text/css" href="styles.css" media="screen" /> 
<script type='text/javascript' src='http://code.jquery.com/jquery-1.4.2.min.js'></script> 
<title>Audio Browser</title> 
</head> 
<body> 

<script type='text/javascript'> 
$(document).ready(function() 
{ 
    var copy = document.createElement('canvas'); 
    var viewer = $('#viewer')[0]; 
    var output = $('#output')[0]; 
    var ctx = viewer.getContext('2d'); 
    var outputContext = output.getContext('2d'); 
    var img = $('#input')[0]; 
    var imageData; 
    var songs = []; 

    output.width = copy.width = img.width; 
    output.height = copy.height = img.height; 
    copy.getContext('2d').drawImage(img, 0, 0); 

    viewer.width = 1500; 
    viewer.height = 800; 

    originalData = copy.getContext('2d').getImageData(0, 0, copy.width, copy.height); 
    imageData = originalData.data; 

    for(var i = 3; i < imageData.length; i+=4) 
    { 
    var row = Math.floor(i/copy.width/4); 

    imageData[i] *= 1-((copy.height - row)/copy.height*2); 
    } 

    songs.push({'fadeImg' : imageData}); 


    draw(); 

    function draw() 
    { 
    originalData = copy.getContext('2d').createImageData(copy.width, copy.height); 

    originalData.data = songs[0].fadeImg; 

    outputContext.putImageData(originalData, 0, 0); 
    } 
}); 

</script> 

<img id='input' src='albumArt/small.png' /> 
<canvas id='output'></canvas> 
<br /> 
<canvas id='viewer'></canvas> 
</body> 
</html> 

EDIT:

Я только что нашел что-то интересное, когда пытаются это в новом IE9 бета. В IE я получаю следующую ошибку: SCRIPT65535: Invalid set operation on read-only property на originalData.data = songs[0].fadeImg; Я раньше проверял firefox и ошибок в консоли ошибок не было. Возможно, firefox просто молчал. Если это так, как я могу скопировать массив обратно без чрезмерного рационализации цикла?

+0

Отладка его прямо сейчас, одна вещь, которую я могу сказать, просто посмотрев на код, заключается в том, что 'img.width' и' img.height' скорее всего будут '0', поскольку готовый документ не ждет, пока изображения будут вы скорее должны приложить весь код к событию 'onload' изображений. –

+0

Если вы используете getImageData вместо createImageData, вы увидите, что результат является копией оригинала, поэтому проблемы там нет. В моем фактическом коде он ожидает события загрузки изображения. – Telanor

ответ

0

Недавно я столкнулся с этой проблемой.

К сожалению, кажется, что прямое назначение данных невозможно, так как это Uint8ClampedArray.

По Kronos.com:

It behaves identically to the other typed array views, except that the setters and constructor use clamping [WEBIDL] rather than modulo arithmetic when converting incoming number values.

Так петля путь ... Это должно сделать:

for (var i in songs[0].fadeImg){ 
    originalData.data[i] = songs[0].fadeImg[i]; 
} 

Это очень неудобно, но это единственный способ, Я нашел.