在Canvas javascript上应用并保存图像效果

时间:2016-07-05 06:43:59

标签: css image canvas css-filters

我必须使用灰度,模糊等效果实现图像滤镜。 我有dataURL格式的图像。有人可以指导我实现它的过程而不会丢失图像大小吗?

如果我将图像添加到画布进行操作,它会缩放到画布框大小。也无法在canvas / image上应用css过滤器并保存它。保存时,它有原始图像

2 个答案:

答案 0 :(得分:0)

将图像添加到另一张图像的来源:

var canvas = document.getElementById('id');
var ctx = myCanvas.getContext('2d');
var img = new Image();
img.onload = function(){
    canvas.width = img.width;
    canvas.height = img.height;
    //The 4th, and 5th parameters set the image at it's own dimensions.
    //The 2nd, and 3rd parameters set the image at the upper left of the canvas.
    ctx.drawImage(img, 0, 0, img.width, img.height);
    //Your image manipulation code here.
};
img.src = dataurlString;

这会使画布与图像一样大,但我假设您希望保留分辨率。

您还需要将所有操作都放在onload侦听器中。

答案 1 :(得分:0)

使用画布应用过滤器

过滤属性

虽然chrome和firefox都支持ctx.filter属性,但它们需要设置浏览器标志才能激活。激活后,2d Context的filter属性使用CSS过滤器语法,并将过滤器应用于所有渲染调用。 ref MDN CanvasRenderingContext2D.filter

ctx.filter = "blur(5px)";  // only applies to proceeding rendering calls existing
                           // current pixels remain unchanged
ctx.drawImage(image,0,0);  // draw an image blurred 5px

将滤镜应用于图像。 仅限适用于Chrome和FIrefox,且设置了相应的浏览器标记。

// assume image is a loaded image
var filteredImage = document.createElement("canvas");
var ctx = filteredImage.getContext('2d');
filteredImage.width = image.width;
filteredImage.height = image.height;
ctx.filter = "blur(10px) grayscale(100%)";
ctx.drawImage(image, 0, 0); // draw the image applying the filter
ctx.filter = ""; // turn off the filter as no needed any more

// You can now save the image filteredImage by using
ctx.toDataURL("image/jpeg",0.75); 

最简单的解决方案

如果您需要完整的浏览器支持,您必须找到一个Javascript过滤器库,有许多可供选择,但我不会认可其中任何一个。

自己编写

另一种方法是编写自己的过滤器(一个很好的学习机会),大多数过滤器都是非常简单的像素操作功能,并且有大量关于各种过滤器如何工作的信息。要了解有关2D API MDN CanvasRenderingContext2D的更多信息以及卷积过滤器的快速入门Image Filters with Canvas

例如灰度滤镜(最基本的卷积滤镜,红色,绿色蓝色通道的加权和转换为灰度)

const PERS_R = 0.2;  // approx human perceptual frequency / intensity response for r,g,b popular in the CG world and based on Manhattan 0.2126, 0.7152, 0.0722
const PERS_G = 0.7;  // for red green and blue
const PERS_B = 0.1; 
function applyGreyScale(image, percent, perc){ // 0 < percent >= 100
    if(image === null || image === undefined){
        throw new ReferenceError("applyGreyScale argument image is undefined or null");
    }
    const p = percent === undefined ? 1: percent / 100;
    const rp = 1-p; // reciprocal of p
    perc = 1 - (perc === undefined ? 0 : Math.min(1, Math.max(0,perc))); // clamp if defined
    var filteredImage = document.createElement("canvas");
    var ctx = filteredImage.getContext('2d');
    const w = filteredImage.width = image.width;
    const h = filteredImage.height = image.height;
    ctx.drawImage(image, 0, 0); // draw the image
    var imageData = ctx.getImageData(0, 0, w ,h); // get the pixel data
    var dat = imageData.data; // reference the pixel data
    var ind = (w * h * 4) - 4; // pixel data array index point to last pixel each pixel is 4 bytes RGBA
    const mean = 1/3; // mean contribution of each channel to gray
    const pr = PERS_R + perc * (mean - PERS_R);
    const pg = PERS_G - perc * (PERS_G- mean);
    const pb = PERS_B + perc * (mean - PERS_B);
    var grey; 
    while(ind >= 0){  // do for all pixels
        grey = dat[ind] * pr;      // get gray by adding each channel's contribution
        grey += dat[ind + 1] * pg; 
        grey += dat[ind + 2] * pb;
        dat[ind] = rp * dat[ind] + p * grey; // mix the grey with the existing colour
        dat[ind + 1] = rp * dat[ind + 1] + p * grey; // mix the grey with the existing colour        
        dat[ind + 2] = rp * dat[ind + 2] + p * grey; // mix the grey with the existing colour
        ind -= 4;
    }
    ctx.putImageData(imageData,0,0); // put the new pixels back on the image
    filteredImage.ctx = ctx; // Add 2D context for later use
    return filteredImage; // return the filtered image
}

/*
To use applyGreyScale(image [, percent [, perc]]) where percent and perc are optional
image is the image to get a gray scale from
percent is the amount of gray to apply 0 is none 100 is full. Default 100
perc is the amount of the perception curve applied to the grey. 0 no perception adjustment, 1 is full perceptual adjustment. Default is 1
Returns image with ctx property added for access to 2D interface
*/

相对容易使用

// convert image to greyscaled image
var dataURL = applyGreyScale(image).ctx.toDataURL("image/jpeg",0.75);