简体   繁体   English

JavaScript canvas图像数据处理

[英]JavaScript canvas image data manipulation

I want to resize image using very simple algorithm. 我想使用非常简单的算法来调整图像大小。 I have something like this: 我有这样的事情:

var offtx = document.createElement('canvas').getContext('2d');
offtx.drawImage(imageSource, offsetX, offsetY, width, height, 0, 0, width, height);
this.imageData = offtx.getImageData(0, 0, width, height).data;
offtx.clearRect(0, 0, width, height);

for(var x = 0; x < this.width; ++x)
{
    for(var y = 0; y < this.height; ++y)
    {
        var i = (y * this.width + x) * 4;
        var r = this.imageData[i ];
        var g = this.imageData[i+1];
        var b = this.imageData[i+2];
        var a = this.imageData[i+3];
        offtx.fillStyle = "rgba("+r+","+g+","+b+","+(a/255)+")";
        offtx.fillRect(0.5 + (x * this.zoomLevel) | 0, 0.5 + (y*this.zoomLevel) | 0, this.zoomLevel, this.zoomLevel);
    }
}

this.imageData = offtx.getImageData(0, 0, this.width * this.zoomLevel, this.height * this.zoomLevel);

However, the problem I have with this solution, is that the image looses any transparency information that way. 但是,此解决方案的问题在于,图像会以这种方式失去任何透明度信息。 I don't know if this happens somewere in this algorithm, or maybe putImageData that I am using later to display that image is doing this, but I can't seem to be able to preserve transparency. 我不知道这种情况是否发生在此算法中,或者我稍后用来显示该图像的putImageData正在执行此操作,但是我似乎无法保持透明度。

Each time I do this I create a canvas, I put the image on that canvas and use getImageData to get image from that canvas as you can see in the first lines of the code. 每次执行此操作时,都会创建一个画布,然后将图像放在该画布上,并使用getImageData从该画布获取图像,如您在代码的第一行中所看到的。 Maybe there is no other way, so I might not mind that... 也许别无选择,所以我可能不在乎...

But the problem is I use two for loops to draw resized image and then use getImageData to store that image information. 但是问题是我使用两个for循环绘制调整大小的图像,然后使用getImageData存储该图像信息。 This is a wierd way to do it. 这是一种奇怪的方法。 I would prefer to create empty image data and fill it with all the original image information only resized. 我希望创建空的图像数据,并用仅调整大小的所有原始图像信息填充它。 I can't grasp that with my mind, I can't image the loop structure for this. 我无法理解这一点,因此无法想象循环结构。 To show what I mean: 为了表明我的意思:

for(var x = 0; x < this.width; ++x)
{
    for(var y = 0; y < this.height; ++y)
    {
        var i = (y * this.width + x) * 4;
        var r = this.imageData[i ];
        var g = this.imageData[i+1];
        var b = this.imageData[i+2];
        var a = this.imageData[i+3];
        //I WOULD LIKE MAGIC TO HAPPEN HERE THAT WILL
        //RESIZE THAT CURRENT PIXEL AND MOVE IT TO THE NEW IMAGE DATA RESIZED
        //SO EVERYTHING IS DONE NICE AND CLEAN IN THIS LOOP WITHOUT THE 
        //GETIMAGEDATA LATER AND MAYBE SET TRANSPARENT PIXELS WHILE I'M AT IT
    }
}

I can't figure out the MAGIC part. 我不知道魔术部分。

Thank you for reading! 感谢您的阅读!

Why not just use the built-in drawImage combined with image smoothing disabled? 为什么不只使用内置的drawImage并禁用图像平滑功能? Doing this operation in a loop is not only relative slow but also prone to errors (as you already discovered). 循环执行此操作不仅相对较慢,而且容易出错(如您已经发现的)。

Doing it the following way will give you the "pixel art" look and will also preserve the alpha channel: 按以下方式进行操作将使您具有“像素艺术”外观,并且还将保留Alpha通道:

var factor = 4; /// will resize 4x

offtx.imageSmoothingEnabled = false; /// prefixed in some browsers
offtx.drawImage(imageSource, offsetX, offsetY, width, height,
                             0, 0, width * factor, height * factor);

Here is an online demo . 这是一个在线演示

Try using this library I recently made which can load an image, resize it fixed width & height or precentage. 尝试使用我最近制作的该库,该库可以加载图像,调整图像的大小,固定宽度和高度或百分比。

It does exactly what you need, and much more like converting canvas to base64, blob, etc... 它完全满足您的需求,并且更像将canvas转换为base64,blob等。

var CanvaWork = new CanvaWork();
CanvaWork.canvasResizeAll(obj.canvas, function(canvases){
    // "canvases" will be an array containing 3 canvases with different sizes depending on initial options
});

https://github.com/vnbenny/canvawork.js https://github.com/vnbenny/canvawork.js

Hope this helps you! 希望这对您有所帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM