java图片处理(混合层叠图片)

java图片处理(混合层叠图片)


package test;

import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.ArrayList;
import java.util.Random;

/**
 * Created by liwensheng on 2017/6/13.
 */
public class imagetest {

    //图片分辨率640 * 360
    private static int widthSize = 640;
    private static int heightSize = 360;

    //层叠图片的底片比重,默认0.6
    public static float alpha = 0.6f;

    private static String SOURCE="source_";
    private static String TARGET="target_";

    private static int MAXWIDHT=8;
    private static int MAXHEIGHT=8;

    /*
     *获取指定目录下的图片路径
     */
    public ArrayList<String> getAllImages(String path){

        ArrayList<String> list = new ArrayList<>();

        File file = new File(path);
        File[] files = file.listFiles();

        if (file.isDirectory())
            for (File f: files) {
                list.add(f.getPath());
            }

        return list;
    }

    /*
     *层叠图片计算
     */
    public int[][]  cascadeImageCal(int[][] data,int width,int height,float value){
        int[][] imageData=null;
        for (int x = 0;x < width;x++)
            for (int y = 0;y < height;y++){

                //获取像素值得到r、g、b值
                int pixel = data[x][y];

                //rgb 3*8 像素,红(R)、绿(G)、蓝(B)三个颜色通道的变化以及它们相互之间的叠加来得到各式各样的颜色
                //r、g、b值 0 - 255,如(0,0,0)为黑色,(255,255,255)为白色
                int r = (pixel & 0xff0000) >> 16;
                int g = (pixel & 0xff00) >> 8;
                int b = pixel & 0xff;

                // int alp=(int)(((pixel & 0xff000000)>>24)*value);
                // r=(((int)(r*(1-value)))<<16)&0xff0000;
                // g=(((int)(g*(1-value)))<<16)&0xff00;
                //  b=(((int)(b*(1-value)))<<16)&0xff;

                //重新计算r、g、b在层叠图片中的比重
                r=(int)(r*(value));
                g=(int)(g*(value));
                b=(int)(b*(value));

                //更新层叠的像素值
                data[x][y]=(((r)<<16)|(g<<8)|(b));
            }
        return data;
    }

    /*
     *将图片转换为指定640 * 360
     */
    public int[][] transferImage(String path,int width,int height){
        int[][] data = null;
        try {

            BufferedInputStream inputStream = new BufferedInputStream(new FileInputStream(path));
            Image image = ImageIO.read(inputStream);

            //改变图片大小
            BufferedImage bufferedImage = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
            bufferedImage.getGraphics().drawImage(image,0,0,width,height,null);

            //返回图片数据
            data =new  int[bufferedImage.getWidth()][bufferedImage.getHeight()];
            for (int x = 0;x < bufferedImage.getWidth();x++)
                for (int y = 0;y < bufferedImage.getHeight();y++)
                    data[x][y] = bufferedImage.getRGB(x,y);

            inputStream.close();
        }catch (IOException e){
            e.printStackTrace();
        }
        return data;
    }

    /*
     *合成图片
     */
    public int[][] composeImage(int x,int y,int[][] targetData,int[][] sourceData){
        for (int i = 0;i < widthSize;i++)
            for (int j = 0;j < heightSize;j++)
                targetData[(x * widthSize) + i][(y * heightSize) + j]+=sourceData[i][j];
        return targetData;
    }

    /*
     *保存最终图片
     */
    public void writeImage(int x,int y,int[][] data,String path,int widthNum,int heightNum){

        int maxWidth = (widthNum > MAXWIDHT?MAXWIDHT:widthNum);
        int maxHeigth = (heightNum > MAXHEIGHT?MAXHEIGHT:heightNum);

        BufferedImage sourceImage = new BufferedImage(x,y,BufferedImage.TYPE_INT_RGB);
        BufferedImage targetImage = new BufferedImage(widthSize*maxWidth,heightSize*maxHeigth,BufferedImage.TYPE_INT_RGB);

        for (int i = 0;i < x;i++)
            for (int j = 0;j < y;j++)
                sourceImage.setRGB(i,j,data[i][j]);

        //sourceImage.getGraphics().drawImage(sourceImage,0,0,widthSize*MAX,heightSize*MAX,null);
        targetImage.getGraphics().drawImage(sourceImage,0,0,widthSize*maxWidth,heightSize*maxHeigth,null);
        try {
            //对图片进行编码,降低
            FileOutputStream outputStream = new FileOutputStream(path+"sou.jpg");
            JPEGImageEncoder encoder= JPEGCodec.createJPEGEncoder(outputStream);
            encoder.encode(targetImage);

            //ImageIO.write(sourceImage, "png", new FileOutputStream(path+"tar.jpg"));
        }catch (IOException e){
            e.printStackTrace();
        }
    }

    /*
     *创建最终生成图片
     */
    public void createNewImage(String cascadeImagePath,String imagePath,int widthNum,int heightNum){

        ArrayList<String> allImagePath=getAllImages(imagePath);
        ArrayList<int[][]> datas1=new ArrayList<>();
        ArrayList<int[][]> datas=new ArrayList<>();
        int[][] cascadeImageData=null;

        Random random = new Random();

        //层叠底片的宽度和高度
        int imageWidthSize  = widthNum * widthSize;
        int imageHeightSize = heightNum * heightSize;

        int[][] tempImageData=null;

        for (String string:allImagePath)
            datas.add(cascadeImageCal(transferImage(string,widthSize,heightSize),
                    widthSize,heightSize,(1 - alpha)));

        cascadeImageData = cascadeImageCal(transferImage(cascadeImagePath,(imageWidthSize),(imageHeightSize)),
                (imageWidthSize),(imageHeightSize),alpha);

        for (int x = 0;x < widthNum;x++)
            for (int y = 0;y < heightNum;y++){
                tempImageData=datas.get(random.nextInt(datas.size()));
                cascadeImageData=composeImage(x,y,cascadeImageData,tempImageData);
            }

        writeImage(imageWidthSize,imageHeightSize,cascadeImageData,cascadeImagePath,widthNum,heightNum);
    }


    public static void main(String[] args){
        imagetest test=new imagetest();
        test.createNewImage("D:\\test\\mm.jpg","D:\\test\\photo",5,5);
    }
}

createNewImage有四个参数

  • 第一个参数 

    层叠图片的底片 


第二个参数为层叠图片路径  

  • 第三和第四参数 
    分别为底片宽高的层叠数,如宽5高5.

最终生成效果 
选用合适的图片效果更佳。其中代码有许多不足之处。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值