使用getImageData在画布上褪色图像边缘

时间:2014-08-08 18:07:27

标签: javascript html arrays canvas getimagedata

使用getImageData,我尝试在图像上创建径向淡入淡出效果,其中点(0,0)的alpha值为0,而点(img.width,img.height)的alpha值为0.5像这样:

radial fade (最后一个点的alpha为1.0,但想象它是0.5。)

我已经能够使用

在我的for循环中创建线性alpha增加
    imgData.data[i+3]=i/imgData.length;

但是当循环迭代时,左边缘(显然)变得更加明确。

我尝试过使用两个循环,一个用于创建行"中断"在数组中,另一个像这样处理alpha操作:

    for(var j=0;j<imgData.height;j++){
        for(var i=0;i<imgData.data.length;i+=4){
            imgData.data[i+3] = 0 + 125 * i/imgData.data.length;
            }
    }

但这种表现非常缓慢,并没有达到我所寻求的褪色。我也不确定我是否正确地做到了这一点。我还尝试了Mozilla Hacks网站上概述的Faster Canvas Pixel Manipulation with Typed Arrays,但是图像甚至没有使用该方法绘制到画布上。 (我使用的是Chrome - 不确定是否存在问题,或者它是否是我的代码。)

有什么想法吗?

编辑:感谢markE提供了出色的解决方案 - 它速度非常快。我在给他的评论中提到了这一点,但这里是创建灰度图像(我的要求的一部分)的完整代码,其中包含了标记演示中的淡入淡出。

    img_width = window.innerWidth/2.5;
    img_height = img_width * (9/16);

    //hidden_ctx is hidden behind a background layer                    
    var g1=hidden_ctx.createRadialGradient(500,500,550,500,500,650);
    g1.addColorStop(0.00,"rgba(0,0,0,0.7)");
    g1.addColorStop(0.30,"rgba(0,0,0,0.35)");
    g1.addColorStop(1.00,"rgba(0,0,0,0.00)");

    hidden_ctx.fillStyle=g1;
    hidden_ctx.fillRect(0, 0, img_width, img_height);

    hidden_ctx.globalCompositeOperation="source-in";

    //custom drawImage method where selected[num] contains
    //contains images & metadata
    drawIt(hidden_ctx, selected[num].image[0], 0, 0, img_width, img_height);

    imgData=hidden_ctx.getImageData(0, 0, img_width, img_height);

    // invert colors
    for (var i=0;i<imgData.data.length;i+=4)
        {
           grayscaled = 0.34 * imgData.data[i] + 0.5 * imgData.data[i + 1] + 0.16 * imgData.data[i + 2];
           imgData.data[i]=grayscaled;
           imgData.data[i+1]=grayscaled;
           imgData.data[i+2]=grayscaled;

        }

    //places the converted image in the lower right corner where 
    //WIDTH/HEIGHT is window.innerWidth/window.innerHeight
    ctx.putImageData(imgData, WIDTH-img_width, HEIGHT-img_height);

1 个答案:

答案 0 :(得分:3)

您可以使用合成来更有效地实现淡入淡出效果。

  • 在左上角绘制一个渐变为透明的径向渐变。

  • 调整径向渐变以满足您的设计需求。

  • 将合成设置为source-in,这会导致任何后续绘制仅显示在现有的非透明像素上。

  • 绘制图像(图像会以与径向渐变相同的方式淡化)

如果设备具有GPU,则使用合成尤其有效,因为合成将使用它。

enter image description here

示例代码和演示:http://jsfiddle.net/m1erickson/thqamsLk/

<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
    canvas{ background-color: lightgray; }
    canvas{border:1px solid red;}
</style>
<script>
$(function(){

    var canvas=document.getElementById("canvas");
    var ctx=canvas.getContext("2d");

    var cw=canvas.width;
    var ch=canvas.height;

    var img=new Image();
    img.onload=start;
    img.src="https://dl.dropboxusercontent.com/u/139992952/multple/reef.jpg";
    function start(){

        canvas.width=img.width;
        canvas.height=img.height;

        var g1=ctx.createRadialGradient(500,500,550,500,500,650);
        g1.addColorStop(0.00,"rgba(0,0,0,1.00)");
        g1.addColorStop(0.30,"rgba(0,0,0,0.75)");
        g1.addColorStop(1.00,"rgba(0,0,0,0.00)");

        ctx.fillStyle=g1;
        ctx.fillRect(0,0,cw,ch);

        ctx.globalCompositeOperation="source-in";

        ctx.drawImage(img,0,0);
    }

}); // end $(function(){});
</script>
</head>
<body>
    <h4>Fading an image using compositing</h4>
    <canvas id="canvas" width=300 height=300></canvas>
</body>
</html>