Tôi có một số JS làm cho một số thao tác với hình ảnh. Tôi muốn có đồ họa giống như pixelart, vì vậy tôi phải phóng to hình ảnh gốc trong trình chỉnh sửa đồ họa. Nhưng tôi nghĩ sẽ tốt hơn nếu bạn thực hiện tất cả các thao tác với hình ảnh nhỏ và sau đó phóng to nó bằng chức năng html5. Điều này sẽ tiết kiệm thời gian xử lý (vì bây giờ my demo (cảnh báo: tên miền có thể gây ra một số vấn đề trong công việc, v.v.) tải rất lâu trong Firefox chẳng hạn). Nhưng khi tôi cố gắng thay đổi kích thước hình ảnh, nó được lấy lại bằng phương pháp bicubically. Làm thế nào để làm cho nó thay đổi kích thước hình ảnh mà không cần resampling? Có giải pháp crossbrowser nào không?Canvas HTML5: có cách nào để thay đổi kích thước hình ảnh bằng cách "lấy lại hàng xóm gần nhất" không?
Trả lời
image-rendering: -webkit-optimize-contrast; /* webkit */
image-rendering: -moz-crisp-edges /* Firefox */
http://phrogz.net/tmp/canvas_image_zoom.html có thể cung cấp trường hợp dự phòng bằng canvas và getImageData
. Nói tóm lại:
// 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);
}
}
Nhận xét cho người đọc trong tương lai: Tối ưu hóa hình ảnh CSS sẽ tròn thành pixel gần nhất, có thể không phải lúc nào cũng lý tưởng cho hình ảnh của bạn. Kẻ xâm lược không gian của bạn có thể trở nên sần sùi và Mario có thể bị biến dạng. Tốt nhất để sử dụng phương pháp mã chi tiết ở trên - hoặc phóng to hình ảnh x3 của bạn để các hiệu ứng của hình ảnh hiển thị nhị thức là không thể bỏ qua. – Polyducks
Không có cách tích hợp sẵn. Bạn phải tự mình thực hiện với getImageData
.
Suy nghĩ về điều đó, nhưng nó sẽ không được rất chậm? – ABTOMAT
Tóm lại, vâng. Nó sẽ rất chậm. Có một cách khác mà tôi có thể nghĩ đến liên quan đến canvas trong bộ nhớ và số lượng lớn các cuộc gọi drawImage nhưng nó có thể không nhất quán trên trình duyệt vì sự khác biệt chống răng cưa và có thể không nhanh hơn nhiều. –
Tôi đã viết một NN thay đổi kích thước kịch bản một lúc trước sử dụng imageData (khoảng dòng 1794)
https://github.com/arahaya/ImageFilters.js/blob/master/imagefilters.js
Bạn có thể xem demo ở đây
http://www.arahaya.com/imagefilters/
không may thay đổi kích thước nội trang sẽ nhanh hơn một chút.
Tôi sẽ lặp lại những gì người khác đã nói và cho bạn biết đó không phải là chức năng được tích hợp sẵn. Sau khi chạy vào cùng một vấn đề, tôi đã thực hiện một bên dưới.
Sử dụng fillRect() thay vì lặp qua từng pixel và vẽ nó. Mọi thứ đều được nhận xét để giúp bạn hiểu rõ hơn cách hoạt động của nó.
//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;
}
Dưới đây là ví dụ về việc sử dụng.
Hình ảnh của bạn sẽ xuất hiện trong HTML như thế này:
<img id="pixel-image" src="" data-src="pixel-image.png"/>
Thẻ data-src
chứa URL cho hình ảnh mà bạn muốn phóng to. Đây là thẻ dữ liệu tùy chỉnh. Mã bên dưới sẽ lấy URL hình ảnh từ thẻ dữ liệu và đặt nó qua chức năng thay đổi kích thước, trả về một hình ảnh lớn hơn (kích thước ban đầu 30x), sau đó được đưa vào thuộc tính src
của thẻ img
.
Hãy nhớ đặt hàm Resize_Nearest_Neighbour
(ở trên) vào thẻ <script>
trước khi bạn bao gồm những điều sau đây.
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"));
Nhiều người trong chúng ta có việc làm - hãy cảnh báo người dùng ở đây về bất kỳ liên kết nào đến một thứ gì đó của NSFW như "nô lệ hậu môn". – MusiGenesis
Không có gì là NSFW. Đó chỉ là máy chủ thử nghiệm của tôi với tên miền 'lạ' như vậy. – ABTOMAT
Bản thân liên kết là vấn đề và rất * NSFW. – MusiGenesis