生成素描图片

import java.awt.color.ColorSpace;

import java.awt.image.BufferedImage;

import java.awt.image.ColorConvertOp;

import java.io.File;



import javax.imageio.ImageIO;

/**

 * 生成素描

 * @author 老陈

 * @version 1.0

 * @since 2014-11-12

 */

public class sketch {

    public static void main(String[] args) throws Exception{

        String file1 = "D:/100.jpg";//原文件

        String file2 = "D:/06.jpg";//素描

        File inputFile = new File(file1);

        BufferedImage old = ImageIO.read(inputFile);

        //去色

        BufferedImage b1 = discolor(old);

        

        //反相

        b1 = invert(b1);

        

        //高斯模糊

        float[][] matric = gaussian2DKernel(3, 3f);

        b1 = convolution(b1, matric);

        

        //叠加

        b1 = deceaseColorCompound(old, b1);

        

        //黑白

        ColorSpace cs1 = ColorSpace.getInstance(ColorSpace.CS_GRAY);

        ColorConvertOp op1 = new ColorConvertOp(cs1, null);

        BufferedImage b2 =  new BufferedImage(old.getWidth(), old.getHeight(), BufferedImage.TYPE_INT_RGB);

            op1.filter(b1, b2);

        ImageIO.write(b2, "jpg", new File(file2));

        System.out.println("生成素描");

    }

    

    //去色

    public static BufferedImage discolor(final BufferedImage sourceImage) {

        final int width = sourceImage.getWidth();

        final int height = sourceImage.getHeight();

        final BufferedImage retImage = new BufferedImage(width, height,

                BufferedImage.TYPE_INT_ARGB);

        for (int i = 0; i < width; i++) {

            for (int j = 0; j < height; j++) {

                                

                final int color1 = sourceImage.getRGB(i, j);



                final int a1 = (color1 >> 24) & 0xff;

                final int r1 = (color1 >> 16) & 0xff;

                final int g1 = (color1 >> 8) & 0xff;

                final int b1 = color1 & 0xff;



                double sumA = a1;

                double sumR = 0;

                double sumG = 0;

                double sumB = 0;

                sumR = sumG = sumB = r1 * 0.299 + g1 * 0.587 + b1 * 0.114;

                

                final int result = (((int) sumA)<<24)

                | (((int) sumR) << 16) | (((int) sumG) << 8) | ((int) sumB);

                

                retImage.setRGB(i, j, result);

            }

        }

        return retImage;

    }

    

    //反相

    public static BufferedImage invert(final BufferedImage sourceImage) {

        final int width = sourceImage.getWidth();

        final int height = sourceImage.getHeight();

        final BufferedImage retImage = new BufferedImage(width, height,

                BufferedImage.TYPE_INT_ARGB);

        for (int i = 0; i < width; i++) {

            for (int j = 0; j < height; j++) {

                                

                final int color1 = sourceImage.getRGB(i, j);



                final int a1 = (color1 >> 24) & 0xff;

                final int r1 = (color1 >> 16) & 0xff;

                final int g1 = (color1 >> 8) & 0xff;

                final int b1 = color1 & 0xff;



                int a = a1;

                int r = 255 - r1;

                int g = 255 - g1;

                int b = 255 - b1;

                

                int result = (a << 24) | (r << 16) | (g << 8) | b;

                if(result > 255) result = 255;

                retImage.setRGB(i, j, result);

            }

        }

        return retImage;

    }

    

    //叠加:两张图片颜色减淡混合

    // C =MIN( A +(A×B)/(256-B),255)

    public static BufferedImage deceaseColorCompound(final BufferedImage sourceImage,

            final BufferedImage targetImage) {

        final int width = sourceImage.getWidth() > targetImage.getWidth() ? sourceImage

                .getWidth() : targetImage.getWidth();

        final int height = sourceImage.getHeight() > targetImage.getHeight() ? sourceImage

                .getHeight() : targetImage.getHeight();

        final BufferedImage retImage = new BufferedImage(width, height,

                BufferedImage.TYPE_INT_ARGB);

        for (int i = 0; i < width; i++) {

            for (int j = 0; j < height; j++) {

                if(i>=sourceImage.getWidth() || j>=sourceImage.getHeight()){

                    if(i>=targetImage.getWidth() || j>=targetImage.getHeight()){

                        retImage.setRGB(i, j, 0);

                        continue;

                    }

                    retImage.setRGB(i, j, targetImage.getRGB(i, j));

                    continue;

                }

                if(i>=targetImage.getWidth() || j>=targetImage.getHeight()){

                    retImage.setRGB(i, j, sourceImage.getRGB(i, j));

                    continue;

                }

                

                final int color1 = sourceImage.getRGB(i, j);

                final int color2 = targetImage.getRGB(i, j);



                final int a1 = (color1 >> 24) & 0xff;

                final int r1 = (color1 >> 16) & 0xff;

                final int g1 = (color1 >> 8) & 0xff;

                final int b1 = color1 & 0xff;



                final int a2 = (color2 >> 24) & 0xff;

                final int r2 = (color2 >> 16) & 0xff;

                final int g2 = (color2 >> 8) & 0xff;

                final int b2 = color2 & 0xff;



                final int a = deceaseColorChannel(a1, a2);

                final int r = deceaseColorChannel(r1, r2);

                final int g = deceaseColorChannel(g1, g2);

                final int b = deceaseColorChannel(b1, b2);



                final int result = (a << 24) | (r << 16) | (g << 8) | b;

                retImage.setRGB(i, j, result);

            }

        }

        return retImage;

    }



    // C =MIN( A +(A×B)/(256-B),255)

    private static int deceaseColorChannel(final int source, final int target) {

        final int result = source + source * target / (256 - target);

        return result > 255 ? 255 : result;

    }

    

    //高斯模糊

    public static BufferedImage convolution(final BufferedImage image,

            final float kernel[][]) {

        final int width = image.getWidth();

        final int height = image.getHeight();

        final int radius = kernel.length / 2;

        final BufferedImage retImage = new BufferedImage(width, height,

                BufferedImage.TYPE_INT_ARGB);

        for (int i = 0; i < width; i++) {

            for (int j = 0; j < height; j++) {

                double sumA = 0;

                double sumR = 0;

                double sumG = 0;

                double sumB = 0;

                for (int x = i - radius; x <= i + radius; x++) {

                    for (int y = j - radius; y <= j + radius; y++) {

                        final int posX = x < 0 ? 0 : x >= width ? width - 1 : x;

                        final int posY = y < 0 ? 0 : y >= height ? height - 1

                                : y;

                        final int color = image.getRGB(posX, posY);

                        final int a = (color >> 24) & 0xff;

                        final int r = (color >> 16) & 0xff;

                        final int g = (color >> 8) & 0xff;

                        final int b = color & 0xff;



                        final int kelX=x - i + radius;

                        final int kelY=y - j + radius;

                        sumA += kernel[kelX][kelY] * a;

                        sumR += kernel[kelX][kelY] * r;

                        sumG += kernel[kelX][kelY] * g;

                        sumB += kernel[kelX][kelY] * b;

                    }

                }

                final int blurColor = (((int) sumA)<<24)

                        | (((int) sumR) << 16) | (((int) sumG) << 8) | ((int) sumB);

                retImage.setRGB(i, j, blurColor);

            }

        }

        return retImage;

    }

    

    //2D高斯卷积矩阵

    // G(x,y)=[1/(2*PI*sigma^2)]*e^[-((x^2+y^2)/(2*sigma^2))]

    // x,y->[-radius,radius)

    public static float[][] gaussian2DKernel(final int radius, final float sigma) {

        final int length = 2 * radius;

        final float[][] matric = new float[length + 1][length + 1];

        final float sigmaSquare2 = 2 * sigma * sigma;

        float sum = 0;

        for (int x = -radius; x <= radius; x++) {

            for (int y = -radius; y <= radius; y++) {

                matric[radius + x][radius + y] = (float) (Math.pow(Math.E, -(x

                        * x + y * y)

                        / sigmaSquare2) / (Math.PI * sigmaSquare2));

                sum += matric[radius + x][radius + y];

            }

        }

        for (int x = 0; x < length; x++) {

            for (int y = 0; y < length; y++) {

                matric[x][y] /= sum;

            }

        }

        return matric;

    }

}

 

你可能感兴趣的:(图片)