首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ImageBitmap与ImageData的区别

ImageBitmap与ImageData的区别
EN

Stack Overflow用户
提问于 2020-02-02 23:19:34
回答 1查看 8.6K关注 0票数 15

ImageBitmapImageData在JavaScript中有什么区别?你什么时候想要一个还是另一个?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-02-03 05:32:51

ImageBitmap保存对位图数据的引用,位图数据可以传递给GPU并直接存储在GPU中。

ImageData保存对canvas pixel ArrayBuffer的引用,该引用本身将原始像素值表示为非乘RGBA颜色通道值的Array,仅供CPU使用。

前者可以直接由GPU绘制,无需其他操作。后者需要读取(通常使用alpha预乘法),然后移动到GPU,然后才能绘制。

它们将不会花费同样的时间被复制到画布位图(即“绘制”)。

代码语言:javascript
复制
var target = document.getElementById('target');
var ctx = target.getContext("2d");

var imageData = ctx.createImageData(300,150);
var imageBitmap = null;

// fill our ImageData with noise
const data = new Uint32Array(imageData.data.buffer);
for(let i=0; i<data.length; i++) {
  data[i] = Math.random()*0xFFFFFF + 0xFF000000;
}
// initial draw
ctx.putImageData(imageData, 0,0);
// we create our ImageBitmap from the current state
// (=> ~ same bitmap as 'imageData')
createImageBitmap(target).then((bmp)=>{
    imageBitmap = bmp;
  btn.disabled = false;
});


// Benchmark.js playground borrowed from 
// https://jsfiddle.net/533hc71h/

var test1_name = 'ImageData';
function test1()
{
    ctx.putImageData(imageData, 0, 0);
}
var test2_name = 'ImageBitmap';
function test2()
{
    ctx.drawImage(imageBitmap, 0, 0);
}
function teardown()
{
    ctx.clearRect(0,0,target.width,target.height);
}

var cycleResults = document.getElementById('cycleResults');
var result = document.getElementById('result');
var btn = document.getElementById('btn');

// BENCHMARK ====================
btn.onclick = function runTests(){

  btn.setAttribute('disable', true);
    cycleResults.innerHTML = '';
  result.textContent = 'Tests running...';
  
  var suite = new Benchmark.Suite;

  // add tests
  suite
  .add(test1_name || 'test1', test1)
  .add(test2_name || 'test2', test2)
  // add listeners
  .on('cycle', function(event) {
    var result = document.createElement('li');
    result.textContent = String(event.target);
    
    document.getElementById('cycleResults')
        .appendChild(result);
  })
  .on('complete', function() {
    result.textContent = 'Fastest is ' + this.filter('fastest').pluck('name');
    btn.setAttribute('disable', false);
    teardown();
  })
  // run async
  .run({ 'async': true });
};
代码语言:javascript
复制
<script src="https://cdnjs.cloudflare.com/ajax/libs/benchmark/1.0.0/benchmark.min.js"></script>

<ul id='cycleResults'>

</ul>
<div id="result">

</div>
<br>
<button id="btn" disabled>
Run Tests
</button><br>

<canvas id="target"></canvas>

运行上面的代码片段,我得到了大约5K的OPS (每秒钟的操作)来绘制ImageData,200K+用于Chrome上的ImageBitmap (在FF中是44K和125 K)。

但是,您不能修改ImageBitmap,也不能以任何有意义的方式读取其内容。

所以,

如果需要绘制位图,请使用需要读取/操作图像数据的ImageBitmap.

  • If,然后使用ImageData.

请记住,由于Worker API的存在,现在我们还可以直接将画布上下文保存在OffscreenCanvas中,这可能也适合您的需要。

票数 30
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60031536

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档