2011-10-18 16 views
10

Mam trochę JS, który wykonuje pewne manipulacje z obrazami. Chcę mieć grafikę podobną do pixelart, więc musiałem powiększyć oryginalne obrazy w edytorze graficznym. Ale myślę, że byłoby dobrze zrobić wszystkie manipulacje przy pomocy małego obrazu, a następnie powiększyć go za pomocą funkcji html5. Pozwoli to zaoszczędzić mnóstwo czasu przetwarzania (ponieważ teraz my demo (ostrzeżenie: nazwa-domeny może powodować pewne problemy w pracy itp.) Ładuje się wyjątkowo długo w Firefoksie, na przykład). Ale kiedy próbuję zmienić rozmiar obrazu, zostaje on resampled dwukropkowo. Jak zmienić rozmiar obrazu bez ponownego próbkowania? Czy istnieje rozwiązanie crossbrowser?Płaszczyzna HTML5: czy istnieje możliwość zmiany rozmiaru obrazu przy użyciu "najbliższego sąsiada"?

+11

Wielu z nas ma pracę - proszę ostrzegać użytkowników o dowolnym łączu do czegoś NSFW typu "anal-niewolnictwo". – MusiGenesis

+2

Nie ma nic NSFW. To tylko mój serwer testowy z taką 'dziwną 'nazwą domeny. – ABTOMAT

+1

Sam link jest problemem i jest * wyjątkowo * NSFW. – MusiGenesis

Odpowiedz

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

http://phrogz.net/tmp/canvas_image_zoom.html może stanowić przypadek awaryjnej za pomocą płótna i getImageData. W skrócie:

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

Więcej: MDN docs on image-rendering

+0

Komentarz dla przyszłych czytelników: Optymalizacja obrazu CSS zostanie zaokrąglona do najbliższego piksela, co nie zawsze może być idealne dla obrazów. Twoje kosmiczne najeźdźców mogą stać się nierówne, a Mario może być zdeformowany. Najlepiej użyć metody kodu opisanej powyżej - lub powiększyć obrazy x3, aby efekty dwumianowego renderowania obrazu były pomijalne. – Polyducks

0

Nie ma wbudowanego sposobu. Musisz to zrobić samodzielnie, pod numerem getImageData.

+0

Zastanowiłem się nad tym, ale czy nie będzie to bardzo powolne? – ABTOMAT

+0

Krótko mówiąc, tak. Będzie bardzo wolno. Jest inny sposób, w jaki mogę pomyśleć o włączeniu płótna w pamięci i dużej ilości wywołań drawImage, ale może nie być spójny w różnych przeglądarkach z powodu różnic w wygładzaniu i może nie być znacznie szybszy. –

0

Będę powtarzać to, co powiedzieli inni i powiedzieć, że nie jest to funkcja wbudowana. Po uruchomieniu w tym samym wydaniu ułożyłem jeden poniżej.

Używa fillRect() zamiast przechodzić przez każdy piksel i malować go. Wszystko jest komentowane, aby pomóc Ci lepiej zrozumieć, jak to działa.

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

Poniżej znajduje się przykład jego użycia.

Twój obraz wydaje w HTML tak:

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

Znacznik data-src zawiera adres URL obrazu, który chcesz powiększyć. To jest niestandardowy tag danych. Poniższy kod pobierze adres URL obrazu ze znacznika danych i przełączy go przez funkcję zmiany rozmiaru, zwracając większy obraz (30x pierwotny rozmiar), który następnie zostanie wprowadzony do atrybutu src znacznika img.

Pamiętaj, aby umieścić funkcję Resize_Nearest_Neighbour (powyżej) w tagu <script> przed dołączeniem następujących elementów.

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