Tengo un lienzo en mi página web; Creo un nuevo dato de Imagen en este lienzo y luego modifico un poco de píxel a través de myImgData.data [] array. Ahora me gustaría escalar esta imagen y agrandarla. Intenté escalando el contexto pero la imagen sigue siendo pequeña. ¿Es posible hacer esto? Gracias¿Cómo escalar un imageData en el lienzo HTML?
Respuesta
Puede dibujar el imageData en un nuevo lienzo, escalar el lienzo original y luego dibujar el nuevo lienzo en el lienzo original.
Algo como esto debería funcionar:
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);
He aquí una demostración funcionamiento http://jsfiddle.net/Hm2xq/2/.
Necesitaba hacerlo sin la interpolación que provoca putImageData(), así que lo hice escalando los datos de la imagen en un nuevo objeto ImageData con el tamaño cambiado. No puedo pensar en ningún otro momento he pensado que el uso de los bucles anidados 5 era una buena idea:
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;
}
espero que al menos otro programador puede copiar y pegar esto en su editor mientras murmuraba, "No hay más que por la gracia de Dios, voy yo".
También es posible usar más métodos de interpolación de calidad, como bilineal o spline. –
@KvanTTT es totalmente cierto, aunque a veces quieres esos píxeles gruesos. –
¿A qué se refiere la variable 'c'? –
Puede escalar el lienzo utilizando el método drawImage.
context = canvas.getContext('2d');
context.drawImage(canvas, 0, 0, 2*canvas.width, 2*canvas.height);
Esto escalaría la imagen para duplicar el tamaño y representar la parte noroeste de la misma. El escalado se logra con los parámetros tercero y cuarto del método drawImage, que especifican el ancho y el alto resultantes de la imagen.
Ver documentos en el MDN https://developer.mozilla.org/en-US/docs/DOM/CanvasRenderingContext2D#drawImage%28%29
Sé que es un viejo tema, pero como la gente como les puede resultar útil, agrego mi optimización al código 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;
}
Este código utiliza menos gira y funciona aproximadamente 30 veces más rápido. Por ejemplo, en un zoom de 100x de un área de 100 * 100, este código toma 250 ms mientras que el otro tarda más de 8 segundos.
@ La respuesta de Castrohenge funciona, pero como señala Muhammad Umer, desordena las coordenadas del mouse en el lienzo original después de eso. Si desea mantener la capacidad de realizar escalas adicionales (para recortar, etc.), entonces necesita utilizar un segundo lienzo (para escalar) y luego buscar los datos de imagen del segundo lienzo y ponerlos en el lienzo original. Como lo siguiente:
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;
}
para, 'canvas.width', y' canvas.height', ¿dónde se define la variable 'canvas'? –
- 1. lienzo ImageData eliminar píxeles blancos
- 2. JavaScript: obtener ImageData sin lienzo
- 3. Cómo dibujar un rectángulo redondeado en el lienzo HTML?
- 4. Cómo clonar ImageData?
- 5. escribiendo en IplImage imageData
- 6. ¿Cómo giro un único objeto en un lienzo html 5?
- 7. Dibuje un polígono que se interseca en el lienzo HTML
- 8. Crear enlaces en lienzo HTML
- 9. Construir un calibre circular html 5 lienzo
- 10. Cómo escalar correctamente un juego en Android
- 11. Lienzo HTML - Dibujar flechas curvas
- 12. Cómo evitar la auto-estiramiento lienzo HTML
- 13. Cómo cambiar el tamaño del elemento de lienzo html?
- 14. lienzo html: recorte y texto
- 15. html lienzo texto desbordamiento elipsis
- 16. Dibujando una espiral en un lienzo HTML usando JavaScript
- 17. Lienzo HTML como superposición en Google Maps
- 18. ¿Puede tener múltiples regiones de recorte en un lienzo HTML?
- 19. Cómo dibujar y escalar un mapa de bits en un lienzo utilizando la interpolación bicúbica en Android?
- 20. Uso del relleno par impar en el lienzo HTML
- 21. Interfaz de usuario con zoom en el lienzo HTML
- 22. cómo escalar un camino en raphael.js
- 23. Lienzo HTML - el dibujo desaparece al cambiar el tamaño
- 24. Escalar un SVG en Java
- 25. obtener clics a través del lienzo html
- 26. ¿Puedo poner un botón HTML dentro del lienzo?
- 27. Imagen de dibujo en Lienzo en un ángulo SIN rotar el lienzo
- 28. Lienzo HTML: trazo punteado alrededor del círculo
- 29. putImageData() en lienzo girado trabajo incorrecto
- 30. ¿Cómo le doy a un lienzo HTML el foco del teclado usando jquery?
Esto funciona perfectamente. – mikechambers
Me gustaría agregar que puede hacer esto sin crear otro lienzo como ctx.drawImage (ctx.canvas, 0,0); dibuja el lienzo sobre sí mismo, y puede escalar a medida que dibuja esto. – Overcode
pero esa escala también altera las coordenadas 10 x es 1.5 * 10. ¿Cómo se puede compensar por eso –