這段時間,接到了一個需求,要求用戶使用手機自帶相機進行自拍,然后用戶自由地將照片移動到一個背景圖片合適的位置,最后進行合成,要求合成后的照片右下角要加上二維碼。
剛開始我使用的是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();