1
votes

enter image description here

I've been able to get a sketch effect (sort of) using a pixel bender shader available here: Adobe Pixel Bender. Sample photo right-below (the one with creepy eyes).

The right-top image was created with Balsamiq mockups and is pretty good example of photo-to-sketch effect. So how do I create something like this? Any link or source code is appreciated.

1
Flash has the capability to run Pixel Bender filters inside a swf. Here is a good basic tutorial on how to do it. gotoandlearn.com/play.php?id=83 - StapleGun
@StapleGun: I am aware of PB and used it to create the bottom right effect. But it's not good enough so I'm looking for some other filter that can do the effect on the top right. - Yeti

1 Answers

6
votes

sketch filter

the top picture is produced by flash with the code below and the bottom picture is what I understood should be the target. they're not exactly the same but somewhat close.

the result highly depends on fine tuning ( // desaturation + brightness + contrast ) performed on the source image, I don't think it can be automated on a series of pictures.

package
{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.BlendMode;
import flash.display.Sprite;
import flash.filters.ColorMatrixFilter;
import flash.filters.ConvolutionFilter;
import flash.geom.ColorTransform;
import flash.geom.Matrix;
import flash.geom.Point;
/**
 * @author Nicolas Barradeau
 * http://en.nicoptere.net
 */
public class Sketch extends Sprite
{
    [Embed(source = '../lib/test.jpg')]private var src:Class;
    private var bd:BitmapData = new src().bitmapData;
    public function Sketch() 
    {
        addChild( new Bitmap( bd ) );//need a bitmapData called bd
        sketch( bd );
    }

    private function sketch( bd:BitmapData ):void 
    {

        // desaturation + brightness + contrast 
        bd.applyFilter( bd, bd.rect, new Point, grayscale );
        bd.applyFilter( bd, bd.rect, new Point,brightness( 25 ) );
        bd.applyFilter( bd, bd.rect, new Point,contrast( 20 ) );
        bd.applyFilter( bd, bd.rect, new Point,brightness( 35 ) );

        //creates the outlines
        var outlines:BitmapData = bd.clone();
        outlines.applyFilter( outlines, outlines.rect, new Point, outline( 80 ) );
        outlines.applyFilter( outlines, outlines.rect, new Point, negative );
        outlines.applyFilter( outlines, outlines.rect, new Point, grayscale );

            //draws the outlines into the bd
            bd.draw( outlines, new Matrix( 1, 0, 0, 1 ), new ColorTransform( 1, 1, 1, .75 ), BlendMode.MULTIPLY );

        //creates some additionnal noise
        var noise:BitmapData = bd.clone();
        noise.noise( 0, 0, 255, 7, true);

            //draws the extra noise
            bd.draw( noise, new Matrix( 1, 0, 0, 1 ), new ColorTransform( 1, 1, 1, 0.15 ), BlendMode.ADD );

        //final contrast pass
        bd.applyFilter( bd, bd.rect, new Point, contrast( 55 ) );

    }

    private function outline( value:Number = 80 ):ConvolutionFilter
    {
        var q:Number = value / 4;
        return new ConvolutionFilter(   3,  3,  [
                                                0   ,    q  ,   0   , 
                                                q   ,   -value  ,   q   , 
                                                0   ,    q  ,   0   
                                                ],  10 );
    }

    private function get negative():ColorMatrixFilter
    {
        return new ColorMatrixFilter(   [
                                            -1  ,   0   ,   0   ,   0   ,   0xFF,
                                            0   ,   -1  ,   0   ,   0   ,   0xFF,
                                            0   ,   0   ,   -1  ,   0   ,   0xFF,
                                            0   ,   0   ,   0   ,   1   ,   0
                                        ]   );
    }

    private function get grayscale():ColorMatrixFilter
    {
        return new ColorMatrixFilter(   [
                                            .3086   ,   .6094   ,   .0820   ,   0   ,   0,
                                            .3086   ,   .6094   ,   .0820   ,   0   ,   0,
                                            .3086   ,   .6094   ,   .0820   ,   0   ,   0,
                                                0   ,   0   ,   0   ,   1   ,   0
                                        ]   );
    }

    private function brightness( value:Number ):ColorMatrixFilter
    {
        return new ColorMatrixFilter(   [
                                            1   ,   0   ,   0   ,   0   ,   value,
                                            0   ,   1   ,   0   ,   0   ,   value,
                                            0   ,   0   ,   1   ,   0   ,   value,
                                            0   ,   0   ,   0   ,   1   ,   0
                                        ]   );
    }

    private function contrast( value:Number ):ColorMatrixFilter
    {
        var a:Number = ( value * 0.01 + 1 )
        var b:Number = 0x80 * ( 1 - a );
        return new ColorMatrixFilter(   [
                                            a   ,   0   ,   0   ,   0   ,   b,
                                            0   ,   a   ,   0   ,   0   ,   b,
                                            0   ,   0   ,   a   ,   0   ,   b,
                                            0   ,   0   ,   0   ,   1   ,   0
                                        ] );
    }   
}
}