2011-10-18 19 views
10

Tengo algunos JS que hacen algunas manipulaciones con imágenes. Quiero tener gráficos parecidos a pixelart, así que tuve que agrandar las imágenes originales en el editor de gráficos. pero creo que sería buena idea hacer todas las manipulaciones con la imagen pequeña y luego aumentarla con la funcionalidad de HTML5. Esto ahorrará montón de tiempo de procesamiento (porque ahora my demo (advertencia: de nombre de dominio puede causar algunos problemas en el trabajo, etc.) cargas extremadamente largo en Firefox, por ejemplo). Pero cuando trato de cambiar el tamaño de la imagen, se vuelve a muestrear de forma bicúbica. ¿Cómo hacer que cambie el tamaño de la imagen sin remuestrear? ¿Hay alguna solución con navegador cruzado?Lienzo HTML5: ¿hay alguna manera de cambiar el tamaño de la imagen con el remuestreo del "vecino más cercano"?

+11

Muchos de nosotros tenemos trabajos - por favor avisar a los usuarios de estos vínculos aquí a algo NSFW como "anal-esclavitud". – MusiGenesis

+2

No hay nada NSFW. Es solo mi servidor de prueba con ese nombre de dominio 'raro'. – ABTOMAT

+1

El enlace en sí es el problema, y ​​es * extremadamente * NSFW. – MusiGenesis

Respuesta

12
image-rendering: -webkit-optimize-contrast; /* webkit */ 
image-rendering: -moz-crisp-edges /* Firefox */ 

http://phrogz.net/tmp/canvas_image_zoom.html puede proporcionar un caso de repliegue utilizando tela y getImageData. En resumen:

// Create an offscreen canvas, draw an image to it, and fetch the pixels 
var offtx = document.createElement('canvas').getContext('2d'); 
offtx.drawImage(img1,0,0); 
var imgData = offtx.getImageData(0,0,img1.width,img1.height).data; 

// Draw the zoomed-up pixels to a different canvas context 
for (var x=0;x<img1.width;++x){ 
    for (var y=0;y<img1.height;++y){ 
    // Find the starting index in the one-dimensional image data 
    var i = (y*img1.width + x)*4; 
    var r = imgData[i ]; 
    var g = imgData[i+1]; 
    var b = imgData[i+2]; 
    var a = imgData[i+3]; 
    ctx2.fillStyle = "rgba("+r+","+g+","+b+","+(a/255)+")"; 
    ctx2.fillRect(x*zoom,y*zoom,zoom,zoom); 
    } 
} 

Más: MDN docs on image-rendering

+0

Un comentario para lectores en el futuro: la optimización de imágenes CSS se redondeará al píxel más cercano, lo que puede no ser siempre ideal para sus imágenes. Tus invasores del espacio pueden llenarse de bultos y Mario puede estar deformado. Lo mejor es utilizar el método de código detallado más arriba, o ampliar las imágenes x3 para que los efectos de la representación binomial de la imagen sean insignificantes. – Polyducks

0

No hay manera integrada. Tienes que hacerlo tú mismo con getImageData.

+0

Pensado en eso, pero ¿no será muy lento? – ABTOMAT

+0

En resumen, sí. Será muy lento Hay otra forma en que se me ocurre incluir un lienzo en memoria y una gran cantidad de llamadas a DrawImage, pero puede no ser consistente en el navegador debido a las diferencias de antialiasing y puede que no sea mucho más rápido. –

0

voy a repetir lo que otros han dicho y te digo que no es una función incorporada. Después de encontrarme con el mismo problema, hice uno a continuación.

Utiliza fillRect() en lugar de recorrer cada píxel y pintarlo. Todo se comenta para ayudarlo a comprender mejor cómo funciona.

//img is the original image, scale is a multiplier. It returns the resized image. 
function Resize_Nearest_Neighbour(img, scale){ 
    //make shortcuts for image width and height 
    var w = img.width; 
    var h = img.height; 

    //--------------------------------------------------------------- 
    //draw the original image to a new canvas 
    //--------------------------------------------------------------- 

    //set up the canvas 
    var c = document.createElement("CANVAS"); 
    var ctx = c.getContext("2d"); 
    //disable antialiasing on the canvas 
    ctx.imageSmoothingEnabled = false; 
    //size the canvas to match the input image 
    c.width = w; 
    c.height = h; 
    //draw the input image 
    ctx.drawImage(img, 0, 0); 
    //get the input image as image data 
    var inputImg = ctx.getImageData(0,0,w,h); 
    //get the data array from the canvas image data 
    var data = inputImg.data; 

    //--------------------------------------------------------------- 
    //resize the canvas to our bigger output image 
    //--------------------------------------------------------------- 
    c.width = w * scale; 
    c.height = h * scale; 
    //--------------------------------------------------------------- 
    //loop through all the data, painting each pixel larger 
    //--------------------------------------------------------------- 
    for (var i = 0; i < data.length; i+=4){ 

     //find the colour of this particular pixel 
     var colour = "#"; 

     //--------------------------------------------------------------- 
     //convert the RGB numbers into a hex string. i.e. [255, 10, 100] 
     //into "FF0A64" 
     //--------------------------------------------------------------- 
     function _Dex_To_Hex(number){ 
      var out = number.toString(16); 
      if (out.length < 2){ 
       out = "0" + out; 
      } 
      return out; 
     } 
     for (var colourIndex = 0; colourIndex < 3; colourIndex++){ 
      colour += _Dex_To_Hex(data[ i+colourIndex ]); 
     } 
     //set the fill colour 
     ctx.fillStyle = colour; 

     //--------------------------------------------------------------- 
     //convert the index in the data array to x and y coordinates 
     //--------------------------------------------------------------- 
     var index = i/4; 
     var x = index % w; 
     //~~ is a faster way to do 'Math.floor' 
     var y = ~~(index/w); 
     //--------------------------------------------------------------- 
     //draw an enlarged rectangle on the enlarged canvas 
     //--------------------------------------------------------------- 
     ctx.fillRect(x*scale, y*scale, scale, scale); 
    } 

    //get the output image from the canvas 
    var output = c.toDataURL("image/png"); 
    //returns image data that can be plugged into an img tag's src 
    return output; 
} 

A continuación, se muestra un ejemplo de uso.

su imagen aparecería en el HTML de la siguiente manera:

<img id="pixel-image" src="" data-src="pixel-image.png"/> 

data-src La etiqueta contiene la dirección URL de la imagen que desea ampliar. Esta es una etiqueta de datos personalizada. El código siguiente tomará el URL de la imagen de la etiqueta de datos y ponerla a través de la función de cambio de tamaño, el retorno de una imagen más grande (30x el tamaño original) que luego se inyecta en el atributo src de la etiqueta img.

Recuerde poner la función Resize_Nearest_Neighbour (arriba) en la etiqueta <script> antes de incluir lo siguiente.

function Load_Image(element){ 
    var source = element.getAttribute("data-src"); 
    var img = new Image(); 

    img.addEventListener("load", function(){ 

     var bigImage = Resize_Nearest_Neighbour(this, 30); 
     element.src = bigImage; 

    }); 

    img.src = source; 
} 

Load_Image(document.getElementById("pixel-image")); 
Cuestiones relacionadas