千图成像(用图片拼图片)的java教程
来源:互联网 发布:淘宝被投诉商标侵权 编辑:程序博客网 时间:2024/05/06 08:54
大题思路我在知乎有回答
在这里大概讲下代码。我实现的比较粗糙,只能使用正方形的图片,如有其他需要可以自行改动。
下面是主要代码。
这里面有俩自定义的类,VectorParser(实现AimParser接口,用于像素替代算法的实现,其中parse()函数输入原料图片的rgb数组和目标图片对象,返回一个二维数组,其中每个数代表一个原料图片在其数组中的索引,将用该图片替换相应像素)和DefaultSamping(实现PicSampling接口,返回采样后的图片对象,我只是简单的用默认的采样方法改变了图片大小,大家可以根据需要修改)
public class ImageStitch { public static int len = 25; BufferedImage aim = null; BufferedImage work = null; BufferedImage srcsOld[] = null; BufferedImage srcs[] = null; int rgbs[][] = null; int aimOfSrc[][]; int numSrc = 0; public ImageStitch(File aim, File[] srcs) throws IOException { //原料图片个数 numSrc = srcs.length; // 初始化插值后原料图片数组 this.srcs = new BufferedImage[numSrc]; //初始化原料图片的数组 srcsOld = new BufferedImage[numSrc]; //初始化图片的rgb数组 this.rgbs = new int[numSrc][]; // 读入目标图片(要拼的图片) this.aim = ImageIO.read(aim); DefaultSampling sampling = new DefaultSampling(); for (int i = 0; i < numSrc; ++i) { // 读入源(材料)图片并获取rgb数组 srcsOld[i] = ImageIO.read(srcs[i]); //对图片进行插值 this.srcs[i] = sampling.sampling(srcsOld[i]); int width = this.srcs[i].getWidth(); int height = this.srcs[i].getHeight(); this.rgbs[i] = new int[width * height]; //获取图片的rgb数组 this.rgbs[i] = this.srcs[i].getRGB(0, 0, width, height, this.rgbs[i], 0, width); } } public void parseAim(AimParser aimParser) { //得到替换像素的图片的索引的数组 aimOfSrc = aimParser.parse(rgbs, aim); //作品图片初始化 work = new BufferedImage(aim.getWidth() * len, aim.getHeight() * len, BufferedImage.TYPE_INT_RGB); int x = 0, y = 0; for(int i = 0; i < aimOfSrc.length; ++i){ x = 0; for(int j = 0; j < aimOfSrc[i].length; ++j){ //将小图片填入大图片中 work.setRGB(x, y, len, len, rgbs[aimOfSrc[j][i]], 0, len); x += len; } y += len; } //写图片到硬盘 FileOutputStream ops; try { ops = new FileOutputStream(new File("D:/Photo/stitch/znh.jpg")); ImageIO.write(work, "jpg", ops); ops.flush(); ops.close(); System.out.println("Success!"); } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) throws IOException { File aim = new File("D:/Photo/stitch/z5.jpg"); File[] srcs = new File[6]; srcs[0] = new File("D:/Photo/stitch/s1.jpg"); srcs[1] = new File("D:/Photo/stitch/s4.jpg"); srcs[2] = new File("D:/Photo/stitch/s3.jpg"); srcs[3] = new File("D:/Photo/stitch/s5.jpg"); srcs[4] = new File("D:/Photo/stitch/5.jpg"); srcs[5] = new File("D:/Photo/stitch/2.jpg"); ImageStitch imageStitch = new ImageStitch(aim, srcs); imageStitch.parseAim(new VectorParser()); }}
AimParser接口和PicSampling接口
public interface AimParser { public int[][] parse(int[][] rgbs, BufferedImage aim);}public interface PicSampling { public BufferedImage sampling(BufferedImage aim);}
VectorParser 回答中取平均色值和选取替换图片的过程
public class VectorParser implements AimParser { int[][] rgbs = null; int[] averageR = null; int[] averageG = null; int[] averageB = null; @Override public int[][] parse(int[][] r, BufferedImage aim) { int width = aim.getWidth(); int height = aim.getHeight(); int[][] aimOfSrc = new int[height][width]; rgbs = r; averageR = new int[rgbs.length]; averageG = new int[rgbs.length]; averageB = new int[rgbs.length]; for (int i = 0; i < rgbs.length; ++i) { for (int j = 0; j < rgbs[i].length; ++j) { averageR[i] += (rgbs[i][j] & 0xff0000) >> 16; averageG[i] += (rgbs[i][j] & 0xff00) >> 8; averageB[i] += rgbs[i][j] & 0xff; } averageR[i] /= rgbs[i].length; averageG[i] /= rgbs[i].length; averageB[i] /= rgbs[i].length; } for (int j = 0; j < height; ++j) { for (int i = 0; i < width; ++i) { int rgb = aim.getRGB(i, j); aimOfSrc[j][i] = choose(rgb); } } return aimOfSrc; } private int choose(int rgb) { int index = 0; int min = 2147483647; int r = (rgb & 0xff0000) >> 16; int g = (rgb & 0xff00) >> 8; int b = rgb & 0xff; for (int i = 0; i < rgbs.length; ++i) { int temp = (int)(Math.pow(averageR[i] - r, 2) + Math.pow(averageG[i] - g, 2) + Math.pow(averageB[i] - b, 2)); if(temp < min){ min = temp; index = i; } } return index; }}
DefaultSampling
public class DefaultSampling implements PicSampling{ @Override public BufferedImage sampling(BufferedImage aim) { BufferedImage ret = new BufferedImage(ImageStitch.len, ImageStitch.len, BufferedImage.TYPE_INT_RGB); ret.getGraphics().drawImage(aim, 0, 0, ImageStitch.len, ImageStitch.len, null); return aim; }}
That’s all.
有什么说的不清楚的地方随时提问。
0 0
- 千图成像(用图片拼图片)的java教程
- PS千图成像
- php滑动拼图片验证
- as3用鼠标拖动图形拼图——灰常简单的教程
- 用鼠标拖动图形拼图——灰常简单的教程
- Revolution Mosaic: 支持36万张照片为素材的马赛克拼图
- IPicture中获取图片的大小并转换成像素
- 图片缩放可以利用凸透镜成像的规律
- Java 多图拼图并实现下载
- 使用ps分隔图片,形成拼图的效果
- VideoPuzzle: 图片无法展现的拼图新玩法
- 拼图最后两张图片异位问题的解决
- java中用Thumbnailator对图片各种处理的方法(可做到对原图片压缩仅改变大小)
- java画图片和图片路径问题
- flash 中的简单图片裁剪(拼图代码)
- UITouch的一些属性(拼图)
- 照相机成像原理 数码相机的成像原理
- 图片片上传前的校验处理
- 15.停止线程 守护线程 join() yield()
- StringUtils的isBlank()和isEmpty()
- 常用基本控件测试用例
- spring boot 之HandlerInterceptor 自动注入
- 安卓阿里百川hotfix集成
- 千图成像(用图片拼图片)的java教程
- Java单例模式深入详解
- NameNode管理元数据的机制
- errno
- Python 函数与变量--习题19,learn python the hard way
- js跨域问题详解
- RSA加密
- C# 获取Byte[]类型的内存地址
- DataNode掉线判定时限