htmlimagecanvaseffectsglow

Glow Effect on HTML Canvas, Potentially Using Convolute Kernel / Matrix


I am drawing a PNG image to an HTML canvas and I have implemented a filter system to allow convolute filters to be executed against the image data before it is blitted to the canvas.

Does anyone have an idea how to create a glow effect using either a convolute kernel / matrix (I'm not sure what the terminology is but I'm talking about these: http://www.html5rocks.com/en/tutorials/canvas/imagefilters/) or by other means such as using the globalCompositeOperation (https://developer.mozilla.org/samples/canvas-tutorial/6_1_canvas_composite.html)?

I am aware that you can start with a low opacity and a scaled image then increase opacity while scaling the image down a bit. This works to create a sort-of glow effect but only around the edge of an image.

In an ideal world it would be great to be able to designate areas of the image that have glow using a secondary glow texture. Any ideas on either scenario? :)


Solution

  • Hope the following is along the lines of what you were looking to do, I think it turned out pretty well. So I used the filter library code from the article, and just created a new glow filter for the library, since his code was done pretty well to begin with. Here is a Live Demo showing the glow effect in action.

    This is the filter code that you need to add to the library

    Filters.glow = function(pixels, passes, image, glowPasses){
            for(var i=0; i < passes; i++){  
                pixels = Filters.convolute(pixels, 
                    [1/9,  1/9,  1/9,
                    1/9,  1/9,  1/9,
                    1/9,  1/9,  1/9 ]);
            }
            
            var tempCanvas = document.createElement("canvas"),
                glowCanvas = document.createElement("canvas"),
                tCtx = tempCanvas.getContext("2d"),
                gCtx = glowCanvas.getContext("2d");
            
            tempCanvas.width = glowCanvas.width = pixels.width;
            tempCanvas.height = tempCanvas.height = pixels.height;
            
            tCtx.putImageData(pixels, 0, 0);
            gCtx.drawImage(image, 0, 0);
    
            gCtx.globalCompositeOperation = "lighter";
    
            for(i = 0; i < glowPasses; i++){
                gCtx.drawImage(tempCanvas,0,0);
            }
            
            return Filters.getPixels(glowCanvas);
        }
    

    And this is how you would use the above filter.

    var glowImage = document.images[1],
        glowMask = document.images[0],
        c = document.getElementById("canvas"),
        ctx = c.getContext("2d");
    
    window.onload = function() {
        var pData = Filters.filterImage(Filters.glow, glowImage, 5, glowMask, 2);
        c.width = pData.width;
        c.height = pData.height;
        ctx.putImageData(pData, 0, 0);
    }
    

    You need to provide it with 2 images. The first is the image you want the glow to appear on, and the second is the actual glow mask that is applied to the image. You can then specify how many blur passes to perform, which makes the glow more prominent, and how many glow passes to perform, which add the glow to the image. I use the lighter global composition for the canvas which alpha blends it.

    This article is a pretty great resource on creating a glow effect, its also where I got the graphics in order to test my results against theirs.