【问题标题】:HTML5 Canvas ImageData assignment acting weirdHTML5 Canvas ImageData 分配行为怪异
【发布时间】:2010-09-18 07:53:27
【问题描述】:

我不明白为什么这不起作用。我在画布上绘制图像,使用 getImageData,操作像素,然后存储该像素数组以备后用。当我准备好稍后绘制这些像素时,我在另一个相同大小的画布上使用 createImageData,将生成的 ImageData 对象的数据属性设置为我保存的像素数组,然后调用 putImageData。结果:保存的数组数据未分配给 ImageData 对象。下面是测试页面的代码:

<!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>

编辑:

我刚刚在新的 IE9 测试版中尝试这个时发现了一些有趣的东西。在 IE 中,我收到以下错误:SCRIPT65535: Invalid set operation on read-only property on originalData.data = songs[0].fadeImg; 我之前检查了 firefox,错误控制台中没有错误。也许Firefox只是默默地失败了。如果是这样的话,我怎样才能将数组复制回来而不会造成非常浪费的 for 循环?

【问题讨论】:

  • 现在正在调试它,通过查看代码我可以知道的一件事是img.widthimg.height 很可能是0,因为文档准备好不会等待图像被加载,你宁愿将所有代码附加到图像onload事件。
  • 如果您使用 getImageData 而不是 createImageData,您会看到结果是原始的副本,因此问题不存在。在我的实际代码中,它确实等待图像加载事件。

标签: javascript html canvas


【解决方案1】:

我最近也遇到了这个问题。

不幸的是,数据的直接分配似乎是不可能的,因为它是一个 Uint8ClampedArray。

根据Kronos.com

它的行为与其他类型化数组视图相同,只是设置器和构造器在转换传入的数值时使用钳位 [WEBIDL] 而不是模运算。

所以循环是要走的路... 应该这样做:

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

这很不方便,但这是我找到的唯一方法。

【讨论】:

    猜你喜欢
    • 2012-06-13
    • 2011-03-12
    • 1970-01-01
    • 1970-01-01
    • 2012-04-19
    • 1970-01-01
    • 1970-01-01
    • 2013-11-09
    • 1970-01-01
    相关资源
    最近更新 更多