Comment mettre à l'échelle une imageData dans une toile HTML?
j'ai une toile dans ma page web; Je crée une nouvelle Image dans cette toile puis je modifie un pixel à travers myImgData.données tableau []. Maintenant, je voudrais mettre cette image à l'échelle et la rendre plus grande. J'ai essayé de mettre à l'échelle le contexte mais l'image reste petite. Est-il possible de faire cela? Merci
5 réponses
Vous pouvez dessiner l'imageData sur une nouvelle toile, mettre à l'échelle la toile originale et ensuite dessiner la nouvelle toile sur la toile originale.
quelque Chose comme ça devrait fonctionner:
var imageData = context.getImageData(0, 0, 100, 100);
var newCanvas = $("<canvas>")
.attr("width", imageData.width)
.attr("height", imageData.height)[0];
newCanvas.getContext("2d").putImageData(imageData, 0, 0);
context.scale(1.5, 1.5);
context.drawImage(newCanvas, 0, 0);
Voici une démo fonctionnelle http://jsfiddle.net/Hm2xq/2/.
j'avais besoin de le faire sans l'interpolation que putImageData() provoque, donc je l'ai fait en mettant à l'échelle les données d'image dans un nouvel objet ImageData redimensionné. Je ne peux pas penser à tout autre moment, j'ai pensé que l'utilisation de 5 boucles for imbriquées était une bonne idée:
function scaleImageData(imageData, scale) {
var scaled = c.createImageData(imageData.width * scale, imageData.height * scale);
for(var row = 0; row < imageData.height; row++) {
for(var col = 0; col < imageData.width; col++) {
var sourcePixel = [
imageData.data[(row * imageData.width + col) * 4 + 0],
imageData.data[(row * imageData.width + col) * 4 + 1],
imageData.data[(row * imageData.width + col) * 4 + 2],
imageData.data[(row * imageData.width + col) * 4 + 3]
];
for(var y = 0; y < scale; y++) {
var destRow = row * scale + y;
for(var x = 0; x < scale; x++) {
var destCol = col * scale + x;
for(var i = 0; i < 4; i++) {
scaled.data[(destRow * scaled.width + destCol) * 4 + i] =
sourcePixel[i];
}
}
}
}
}
return scaled;
}
j'espère qu'au moins un autre programmeur pourra copier et coller ceci dans son éditeur en murmurant, "là, mais pour la grâce de Dieu va I."
Vous pouvez dimensionner la toile en utilisant la méthode drawImage.
context = canvas.getContext('2d');
context.drawImage( canvas, 0, 0, 2*canvas.width, 2*canvas.height );
ceci aurait l'échelle de l'image pour doubler la taille et rendre la partie nord-ouest de celui-ci à la toile. La mise à l'échelle est réalisée avec les troisième et quatrième paramètres de la méthode drawImage, qui spécifient la largeur et la hauteur résultantes de l'image.
voir docs à MDN https://developer.mozilla.org/en-US/docs/DOM/CanvasRenderingContext2D#drawImage%28%29
je sais que c'est un vieux sujet, mais puisque les gens comme peuvent le trouver utile, j'ajoute mon optimisation du code de rodarmor :
function scaleImageData(imageData, scale) {
var scaled = ctx.createImageData(imageData.width * scale, imageData.height * scale);
var subLine = ctx.createImageData(scale, 1).data
for (var row = 0; row < imageData.height; row++) {
for (var col = 0; col < imageData.width; col++) {
var sourcePixel = imageData.data.subarray(
(row * imageData.width + col) * 4,
(row * imageData.width + col) * 4 + 4
);
for (var x = 0; x < scale; x++) subLine.set(sourcePixel, x*4)
for (var y = 0; y < scale; y++) {
var destRow = row * scale + y;
var destCol = col * scale;
scaled.data.set(subLine, (destRow * scaled.width + destCol) * 4)
}
}
}
return scaled;
}
ce code utilise moins de boucles et court environ 30 fois plus vite. Par exemple, sur un zoom 100x 100*100, ce codes faut 250 ms, tandis que l'autre prend plus de 8 secondes.
la réponse de@Castrohenge fonctionne, mais comme le souligne Muhammad Umer, elle perturbe les coordonnées de la souris sur la toile originale après cela. Si vous souhaitez maintenir la capacité d'effectuer des balances supplémentaires (pour la coupe, etc. ensuite, vous devez utiliser une deuxième toile (pour la mise à l'échelle), puis récupérer les données d'image de la deuxième toile et les mettre dans la toile originale. Comme ceci:
function scaleImageData(imageData, scale){
var newCanvas = $("<canvas>")
.attr("width", imageData.width)
.attr("height", imageData.height)[0];
newCanvas.getContext("2d").putImageData(imageData, 0, 0);
// Second canvas, for scaling
var scaleCanvas = $("<canvas>")
.attr("width", canvas.width)
.attr("height", canvas.height)[0];
var scaleCtx = scaleCanvas.getContext("2d");
scaleCtx.scale(scale, scale);
scaleCtx.drawImage(newCanvas, 0, 0);
var scaledImageData = scaleCtx.getImageData(0, 0, scaleCanvas.width, scaleCanvas.height);
return scaledImageData;
}