Разница между ImageBitmap и ImageData - PullRequest
0 голосов
/ 03 февраля 2020

В чем разница между ImageBitmap и ImageData в JavaScript? когда вы хотите один или другой?

1 Ответ

4 голосов
/ 03 февраля 2020

ImageBitmap содержит ссылку на растровые данные, которые могут быть переданы и сохранены непосредственно в графическом процессоре.

ImageData содержит ссылку на пиксель холста ArrayBuffer , который сам представляет необработанные значения пикселей в виде массива необумноженных значений цветового канала RGBA, который используется только процессором.

Первый может быть нарисован непосредственно графическим процессором, без каких-либо других операций. Последние должны быть прочитаны (часто с предварительным умножением альфа), а затем перемещены в графический процессор, прежде чем его можно будет нарисовать.

Им не потребуется столько же времени, чтобы скопировать их в растровое изображение холста (иначе) нарисовал ").

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 });
};
<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 + для ImageBitmap при Chrome (44K против 125K в фф).

Однако вы не можете ни изменять ImageBitmap, ни читать его содержимое каким-либо значимым образом.

Итак,

  • Если вам нужно нарисовать растровое изображение, используйте ImageBitmap.
  • Если вам нужно прочитать / манипулировать данными изображения, тогда используйте ImageData ,

И помните, что теперь у нас также есть средства для хранения контекстов холста непосредственно в Worker благодаря API-интерфейсу OffscreenCanvas, которые также могут удовлетворить ваши потребности.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...