2011-10-18 8 views
10

Ho qualche JS che rende alcune manipolazioni con le immagini. Voglio avere una grafica simile a pixelart, quindi ho dovuto ingrandire le immagini originali nell'editor di grafica. Ma penso che sarebbe una buona idea fare tutte le manipolazioni con la piccola immagine e poi ingrandirla con la funzionalità html5. Ciò farà risparmiare tempo di elaborazione (perché ora my demo (avviso: nome di dominio potrebbe causare alcuni problemi sul lavoro ecc.) Carichi estremamente lunghi in Firefox, ad esempio). Ma quando provo a ridimensionare l'immagine, viene ricampionato bicubicamente. Come si fa a ridimensionare l'immagine senza ricampionare? C'è una soluzione crossbrowser?Tela HTML5: esiste un modo per ridimensionare l'immagine con il ricampionamento "più vicino"?

+11

Molti di noi hanno un lavoro - si prega di avvertire gli utenti qui di qualsiasi collegamento a qualcosa di NSFW come "schiavitù anale". – MusiGenesis

+2

Non c'è niente NSFW. Questo è solo il mio server di test con un nome di dominio "strano". – ABTOMAT

+1

Il collegamento stesso è il problema ed è * estremamente * NSFW. – MusiGenesis

risposta

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

http://phrogz.net/tmp/canvas_image_zoom.html in grado di fornire un caso di ripiego utilizzando tela e getImageData. In breve:

// 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); 
    } 
} 

Più: MDN docs on image-rendering

+0

Un commento per i futuri lettori: l'ottimizzazione dell'immagine CSS verrà arrotondata al pixel più vicino, che potrebbe non essere sempre l'ideale per le tue immagini. I tuoi invasori spaziali potrebbero diventare bitorzoluti e Mario potrebbe essere deformato. Meglio usare il metodo di codice sopra descritto - o ingrandire le immagini x3 in modo che gli effetti del rendering di immagini binomiale siano trascurabili. – Polyducks

0

Non esiste un modo integrato. Devi farlo da solo con getImageData.

+0

Pensato, ma non sarà molto lento? – ABTOMAT

+0

In breve, sì. Sarà molto lento. C'è un altro modo in cui posso pensare di coinvolgere una tela in memoria e una grande quantità di chiamate drawImage, ma potrebbe non essere coerente attraverso il browser a causa delle differenze di anti-aliasing e potrebbe non essere molto più veloce. –

0

echo quello che altri hanno detto e ti dico che non è una funzione incorporata. Dopo aver incontrato lo stesso problema, ne ho creato uno qui sotto.

Usa fillRect() invece di scorrere ogni pixel e dipingerlo. Tutto è commentato per aiutarti a capire meglio come funziona.

//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; 
} 

Di seguito è riportato un esempio in uso.

La tua immagine apparirà nella HTML come questo:

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

Il tag data-src contiene l'URL per l'immagine che si desidera ingrandire. Questo è un tag dati personalizzato. Il codice riportato di seguito prenderà l'URL dell'immagine dal tag dati e lo metterà nella funzione di ridimensionamento, restituendo un'immagine più grande (30 volte la dimensione originale) che poi viene iniettata nell'attributo src del tag img.

Ricordare di inserire la funzione Resize_Nearest_Neighbour (sopra) nel tag <script> prima di includere quanto segue.

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")); 
Problemi correlati