这段时间,接到了一个需求,要求用户使用手机自带相机进行自拍,然后用户自由地将照片移动到一个背景图片合适的位置,最后进行合成,要求合成后的照片右下角要加上二维码。
刚开始我使用的是h5的canvas画布实现,后来发现使用h5画布实现会带来一些弊端,最恶心的是前置摄像头拍的照片的旋转问题,弊端就不详细说了。
总之,为了降低开发难度,我只能使用java后台代码实现图片的合成。
java合成图片的原理和 h5的canvas合成图片是一样的
第一步:
创建一个BufferedImage对象,参数只需要更改前边两个,第一个是画布的宽,第二个是高(这个宽高其实就是最终生成图片的像素宽高了)
BufferedImage thumbImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
第二步:
根据 BufferedImage 对象获取到 Graphics2D 对象
Graphics2D g = thumbImage.createGraphics();
第三步:
添加要进行合成的图片,这个说一下图片的顺序一定不能错,比如说一张照片右下角要加一个二维码,那么就先添加照片,再添加二维码,这样二维码就能覆盖掉照片的一部分了,如果顺序反了,那么照片就会把二维码覆盖掉
该方法的参数,width代表添加的图片的宽,height代表高,left代表图片距离画布最左端的距离,top代表图片距离画布最上端的距离(left,top其实就是图片的坐标了,通过他们我们可以把图片放到合适的位置)
File file = new File("参与合成的照片路径"); Image src = javax.imageio.ImageIO.read(file); g.drawImage(src.getScaledInstance(width,height,Image.SCALE_SMOOTH), left, top, null);
第四步:
生成新图片
String path = "新生成的照片路径"; BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(path));
String formatName = path.substring(path.lastIndexOf(".") + 1); ImageIO.write(thumbImage, /*"GIF"*/ formatName /* format desired */ , new File(path) /* target */ );
这样就能合成图片了。
贴一段完整代码,实现了人物照片和二维码图片的合成
File file = new File("人物照片路径"); File file2 = new File("二维码路径"); //人物照片 Image src1 = javax.imageio.ImageIO.read(file); //二维码图片 Image src2 = javax.imageio.ImageIO.read(file2); //获取人物照片宽高 int width = src1.getWidth(null); int height = src1.getHeight(null); //创建一个画布,设置宽高(这里人物照片宽高就是画布宽高) BufferedImage thumbImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics2D g = thumbImage.createGraphics(); //绘制人脸图片 g.drawImage(src1.getScaledInstance(width,height, Image.SCALE_SMOOTH), 0, 0, null); //绘制二维码图片(这里二维码的宽高就由人物照片决定好了,我这里二维码宽高都是照片的宽度四分之一,然后二维码位于照片右下角) g.drawImage(src3.getScaledInstance(width/4, width/4, Image.SCALE_SMOOTH), width/4*3, height-wwid/4, null); //获取项目的根路径 String path = request.getSession().getServletContext().getRealPath("/"); path = path +"image"; //使用uuid为图片生成一个名字 String name = UUID.randomUUID().toString(); name = name+".jpg"; path = path +File.separator+name; BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(path)); String formatName = path.substring(path.lastIndexOf(".") + 1); ImageIO.write(thumbImage, /*"GIF"*/ formatName /* format desired */ , new File(path) /* target */ ); //关闭输出流 out.close();