zoukankan      html  css  js  c++  java
  • 生成素描图片

    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;
        }
    }
  • 相关阅读:
    ITK+VTK+VS环境搭建.Q:vs编译出问题参见VTK(一)哈。
    shell按关键字批量杀进程
    lua使用笔记
    for (; ; )和while (true) 没有区别
    git笔记
    ArrayList LinkedList
    面试整理
    这个相机不错
    idea激活服务器
    git 笔记
  • 原文地址:https://www.cnblogs.com/chrischen662/p/4588610.html
Copyright © 2011-2022 走看看