Weboldal keresés

angular - Kép méretének megváltoztatása a ctx.putImageData segítségével


Egy Angular projekten dolgozom, és fel kell tennem egy képet egy vászonra. A kép nincs helyileg tárolva, csak a képadataim vannak, így ezt használom.

this.context.putImageData(imgData, firstPointX, firstPointY);

Most a problémám az, hogy a kapott képek 640 * 480 méretűek. Arra gondoltam, van-e mód a kép méretének megváltoztatására, hogy nagyobban tudjam megjeleníteni, mint 640 * 480?

Válasz #1

putImageData() mindig a saját width és height értékeit fogja használni a destinationWidth és destinationHeight számára, amit a drawImage() esetében megadhatnánk.

Ez nem értelmes a kontextusmátrix-transzformációra, és így annak átméretezése nem lesz hatással erre a módszerre.

Az egy dolog, amivel azonban rendelkezik, az a dirtyWidth és a dirtyHeight argumentumok, amelyek nem sokat segítenek nekünk, mivel bár csökkenthetik a festendő felület területét, nem módosítják a benne lévő pixeleket, és egyébként sem lesznek képesek megnövelni ezt a felületet... (Egy részletesebb áttekintésért lásd ezt a K/K-t)

Ahhoz, hogy elérd, amit akarsz, valójában le kellene renderelned a ImageData-t, majd a drawImage-gel rajzolnod a renderelt képet.

A legátfogóbb módja ennek valószínűleg egy második vászon használata:

var ctx = canvas.getContext('2d'),
  cW = canvas.width,
  cH = canvas.height,
  imgW = 20,
  imgH = 20;

// generate a 20*20 ImageData full of noise
var data = new Uint8Array(imgW * imgH * 4);
crypto.getRandomValues(data);
var img = new ImageData(new Uint8ClampedArray(data.buffer), imgW, imgH);


// generate a second canvas
var renderer = document.createElement('canvas');
renderer.width = img.width;
renderer.height = img.height;
// render our ImageData on this canvas
renderer.getContext('2d').putImageData(img, 0, 0);
// Now we can scale our image, by drawing our second canvas
ctx.drawImage(renderer, 0,0, cW, cH);
<canvas id="canvas" height="100" width="100"></canvas>

A modern böngészőkben az egész folyamat tisztább módon kezelhető, köszönhetően az ImageBitmap objektumnak:

var ctx = canvas.getContext('2d'),
  cW = canvas.width,
  cH = canvas.height,
  imgW = 20,
  imgH = 20;

// generate a 20*20 ImageData full of noise
var data = new Uint8Array(imgW * imgH * 4);
crypto.getRandomValues(data);
var img = new ImageData(new Uint8ClampedArray(data.buffer), imgW, imgH);

createImageBitmap(img).then(renderer => 
  ctx.drawImage(renderer, 0,0, cW, cH)
)
<canvas id="canvas" height="100" width="100"></canvas>

És egy harmadik mód, amely csak az ImageData felskálázására működik, és elkerüli a második vászon használatát, valamint minden implementációban elérhető lesz, az, hogy ugyanazt a vásznat használjuk, mint az ImageBitmap renderelő, és ezt a vásznat önmagára rajzoljuk kompozitálással:

var ctx = canvas.getContext('2d'),
  cW = canvas.width,
  cH = canvas.height,
  imgW = 20,
  imgH = 20;

// generate a 20*20 ImageData full of noise
var data = new Uint8Array(imgW * imgH * 4);
crypto.getRandomValues(data);
var img = new ImageData(new Uint8ClampedArray(data.buffer), imgW, imgH);

// we use the main canvas as renderer
ctx.putImageData(img, 0, 0);
// Now we have an unscaled version of our ImageData
// let's make the compositing mode to 'copy' so that our next drawing op erases whatever was there previously
// just like putImageData would have done
ctx.globalCompositeOperation = 'copy';
// now we can draw ourself over ourself.
ctx.drawImage(canvas,
  0,0, img.width, img.height, // grab the ImageData part
  0,0, canvas.width, canvas.height // scale it
);
<canvas id="canvas" height="100" width="100"></canvas>

Válasz #2

A scale() módszer a jelenlegi rajzot nagyobbra vagy kisebbre méretezi.

this.context.putImageData(imgData, firstPointX, firstPointY);
this.context.scale(1.5,1.5);
this.context.drawImage(this.canvas, 0, 0); // <-- added

Kapcsolódó cikkek