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"?
Płaszczyzna HTML5: czy istnieje możliwość zmiany rozmiaru obrazu przy użyciu "najbliższego sąsiada"?
Odpowiedz
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
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
Nie ma wbudowanego sposobu. Musisz to zrobić samodzielnie, pod numerem getImageData
.
Zastanowiłem się nad tym, ale czy nie będzie to bardzo powolne? – ABTOMAT
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. –
Napisałem NN zmiany rozmiaru skrypt jakiś czas temu za pomocą imageData (wokół linii 1794)
https://github.com/arahaya/ImageFilters.js/blob/master/imagefilters.js
Można zobaczyć demo tutaj
http://www.arahaya.com/imagefilters/
Niestety zmiana rozmiaru wbudowanego powinna być nieco szybsza.
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"));
Wielu z nas ma pracę - proszę ostrzegać użytkowników o dowolnym łączu do czegoś NSFW typu "anal-niewolnictwo". – MusiGenesis
Nie ma nic NSFW. To tylko mój serwer testowy z taką 'dziwną 'nazwą domeny. – ABTOMAT
Sam link jest problemem i jest * wyjątkowo * NSFW. – MusiGenesis