12

我有一些 JS 可以对图像进行一些操作。我想拥有类似像素艺术的图形,所以我不得不在图形编辑器中放大原始图像。但我认为使用小图像进行所有操作然后使用 html5 功能将其放大是个好主意。这将节省大量处理时间(例如,因为现在我的演示警告:域名可能会导致工作中的一些问题等)在 Firefox 中加载时间过长)。但是当我尝试调整图像大小时,它会被重新采样。如何在不重新采样的情况下调整图像大小?有没有跨浏览器的解决方案?

4

6 回答 6

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

http://phrogz.net/tmp/canvas_image_zoom.html可以使用 canvas 和getImageData. 简而言之:

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

更多:关于图像渲染的 MDN 文档

于 2011-10-19T00:53:41.833 回答
5

不久前,我使用 ImageData 编写了一个 NN 调整大小的脚本(大约第 1794 行)

https://github.com/arahaya/ImageFilters.js/blob/master/imagefilters.js

你可以在这里看到一个演示

http://www.arahaya.com/imagefilters/

不幸的是,内置调整大小应该稍微快一些。

于 2011-10-20T23:29:57.523 回答
0

我会回应其他人所说的话,并告诉您这不是内置功能。遇到同样的问题后,我在下面做了一个。

它使用fillRect()而不是循环遍历每个像素并绘制它。对所有内容都进行了注释,以帮助您更好地了解它的工作原理。

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

下面是它的使用示例。

您的图像将出现在 HTML 中,如下所示:

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

data-src标记包含您要放大的图像的 URL。这是一个自定义数据标签。下面的代码将从数据标签中获取图像 URL 并将其放入调整大小函数,返回更大的图像(原始大小的 30 倍),然后将其注入到标签的src属性中。img

请记住在包含以下内容之前将函数Resize_Nearest_Neighbour(上方)放入标签中。<script>

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") );
于 2018-01-15T23:37:26.000 回答
0

canvas 元素上的这个 CSS 有效:

image-rendering: pixelate;

截至 2021 年 9 月,这适用于 Chrome 93。

于 2021-09-10T14:23:53.237 回答
-1

没有内置的方法。你必须自己做getImageData

于 2011-10-18T15:03:38.770 回答
-1

根据 Paul Irish 的评论:

function resizeBase64(base64, zoom) {
    return new Promise(function(resolve, reject) {
        var img = document.createElement("img");

        // once image loaded, resize it
        img.onload = function() {
            // get image size
            var imageWidth = img.width;
            var imageHeight = img.height;

            // create and draw image to our first offscreen canvas
            var canvas1 = document.createElement("canvas");
            canvas1.width = imageWidth;
            canvas1.height = imageHeight;
            var ctx1 = canvas1.getContext("2d");
            ctx1.drawImage(this, 0, 0, imageWidth, imageHeight);

            // get pixel data from first canvas
            var imgData = ctx1.getImageData(0, 0, imageWidth, imageHeight).data;

            // create second offscreen canvas at the zoomed size
            var canvas2 = document.createElement("canvas");
            canvas2.width = imageWidth * zoom;
            canvas2.height = imageHeight * zoom;
            var ctx2 = canvas2.getContext("2d");

            // draw the zoomed-up pixels to a the second canvas
            for (var x = 0; x < imageWidth; ++x) {
                for (var y = 0; y < imageHeight; ++y) {
                    // find the starting index in the one-dimensional image data
                    var i = (y * imageWidth + 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);
                }
            }

            // resolve promise with the zoomed base64 image data
            var dataURI = canvas2.toDataURL();
            resolve(dataURI);
        };
        img.onerror = function(error) {
            reject(error);
        };
        // set the img soruce
        img.src = base64;
    });
}

resizeBase64(src, 4).then(function(zoomedSrc) {
    console.log(zoomedSrc);
});

https://jsfiddle.net/djhyquon/69/

于 2019-05-02T12:48:58.127 回答