java操作二維碼生成與已有圖片合成與解析+pc攝像頭抓拍
效果
pom中依賴
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.3.3</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.9</version>
</dependency>
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>javacv-platform</artifactId>
<version>1.4.3</version>
</dependency>
代碼實現
-
Camera類
import org.bytedeco.javacv.OpenCVFrameGrabber; public class Camera { /** * 是否存儲圖片 */ public static enum Img { save, nosave } /** * 是否正常啓動攝像頭 true:正常啓動/false:異常啓動 */ public static boolean InitCamera; /** * 攝像頭資源 */ public static OpenCVFrameGrabber grabber; /** * 是否保存圖片,默認不保存 */ public static Img saveImage = Img.nosave; /** * 開始攝像頭 * * @throws Exception 攝像頭初始化失敗! */ public static void StartCamera() throws Exception { grabber.start(); } /** * 停止攝像頭 * * @throws Exception 攝像頭關閉異常! */ public static void StopCamera() throws Exception { grabber.stop(); } }
工具類
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class BaseUtil {
/**
* 二維碼信息和圖片合成新的圖片
*
* @param qrInfo 二維碼文字信息內容
* @param imagePath 輸入圖片文件路徑
* @param toPath 合成圖片文件路徑【注:路徑後綴爲.png】
* @param cachePath 緩存目錄路徑
* @return 是否操作成功
*/
public static boolean createQrMergeImage(String qrInfo, String imagePath, String toPath, String cachePath) {
try {
//判斷二維碼信息是否爲空
if (qrInfo == null || "".equals(qrInfo.trim())) {
System.err.println("Parameter \'qrInfo\' cannot be empty");
return false;
}
//判斷圖片路徑是否爲空
if (imagePath == null || "".equals(imagePath.trim())) {
System.err.println("Parameter \'imagePath\' cannot be empty");
return false;
}
//判斷圖片文件是否存在
File imageFile = new File(imagePath);
if (!imageFile.exists()) {
System.err.println("The image file is not exits");
return false;
}
//判斷緩存目錄是否爲空
if (cachePath == null || "".equals(cachePath.trim())) {
System.err.println("Parameter \'cachePath\' cannot be empty");
return false;
}
//判斷緩存目錄是否存在
File cacheFile = new File(cachePath);
if (!cacheFile.exists() || !cacheFile.isDirectory()) {
System.err.println("cachePath is not exits or is not directory");
return false;
}
//判斷輸出文件路徑是否爲空
if (toPath == null || "".equals(toPath.trim())) {
System.err.println("Parameter \'toPath\' cannot be empty");
return false;
}
//判斷輸出文件路徑是否.png結尾
if (!toPath.endsWith(".png")) {
System.err.println("Parameter \'toPath\' is not end \'.png\'");
return false;
}
//判斷輸出文件是否存在
File toFile = new File(toPath);
if (!toFile.exists()) {
toFile.createNewFile();
}
//判斷是否爲圖片
try {
Image image = ImageIO.read(imageFile);
if (image == null) {
System.err.println("The image file is not real picture");
return false;
}
} catch (IOException ex) {
System.err.println("The image file is not real picture");
return false;
}
//設置ImageIO的緩存目錄
ImageIO.setCacheDirectory(cacheFile);
//獲取圖片的高
BufferedImage bufferedImage = ImageIO.read(new FileInputStream(imageFile));
int height = bufferedImage.getHeight();
if (height <= 0) {
System.err.println("Get image file hight error");
return false;
}
//生成等高的二維碼
MultiFormatWriter multiFormatWriter = new MultiFormatWriter();
Map hints = new HashMap();
//設置UTF-8, 防止中文亂碼
hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
//設置二維碼四周白色區域的大小
hints.put(EncodeHintType.MARGIN, 0);
//設置二維碼的容錯性
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
//畫二維碼,記得調用multiFormatWriter.encode()時最後要帶上hints參數,不然上面設置無效
BitMatrix bitMatrix = multiFormatWriter.encode(qrInfo, BarcodeFormat.QR_CODE, height, height, hints);
//開始畫二維碼
BufferedImage bufferedImageQr = MatrixToImageWriter.toBufferedImage(bitMatrix);
//判斷生成的二維碼是否爲空
if (bufferedImageQr == null) {
System.err.println("Create Buffer Image Qr error");
return false;
}
//合併圖片與生成的二維碼
int w1 = bufferedImage.getWidth();
int h1 = bufferedImage.getHeight();
int w2 = bufferedImageQr.getWidth();
int h2 = bufferedImageQr.getHeight();
// 從圖片中讀取RGB
int[] ImageArrayOne = new int[w1 * h1];
ImageArrayOne = bufferedImage.getRGB(0, 0, w1, h1, ImageArrayOne, 0, w1); // 逐行掃描圖像中各個像素的RGB到數組中
int[] ImageArrayTwo = new int[w2 * h2];
ImageArrayTwo = bufferedImageQr.getRGB(0, 0, w2, h2, ImageArrayTwo, 0, w2);
// 生成新圖片
BufferedImage DestImage = null;
DestImage = new BufferedImage(w1 + w2, h1, BufferedImage.TYPE_INT_RGB);
DestImage.setRGB(0, 0, w1, h1, ImageArrayOne, 0, w1);
DestImage.setRGB(w1, 0, w2, h2, ImageArrayTwo, 0, w2);
ImageIO.write(DestImage, "png", new File(toPath));
return true;
} catch (Exception e) {
return false;
}
}
/**
* 解析圖片中的二維碼文本信息
*
* @param imagePath 含二維碼圖片的路徑
* @param cachePath 緩存目錄路徑
* @return 解析出的二維碼文本信息
*/
public static String decodeQRInfoFromImage(String imagePath, String cachePath) {
String qrInfo = null;
try {
//判斷圖片路徑是否爲空
if (imagePath == null || "".equals(imagePath.trim())) {
System.err.println("Parameter \'imagePath\' cannot be empty");
qrInfo = null;
return qrInfo;
}
//判斷圖片文件是否存在
File imageFile = new File(imagePath);
if (!imageFile.exists()) {
System.err.println("The image file is not exits");
qrInfo = null;
return qrInfo;
}
//判斷是否爲圖片
try {
Image image = ImageIO.read(imageFile);
if (image == null) {
System.err.println("The image file is not real picture");
qrInfo = null;
return qrInfo;
}
} catch (IOException ex) {
System.err.println("The image file is not real picture");
qrInfo = null;
return qrInfo;
}
//判斷緩存目錄是否爲空
if (cachePath == null || "".equals(cachePath.trim())) {
System.err.println("Parameter \'cachePath\' cannot be empty");
qrInfo = null;
return qrInfo;
}
//判斷緩存目錄是否存在
File cacheFile = new File(cachePath);
if (!cacheFile.exists() || !cacheFile.isDirectory()) {
System.err.println("cachePath is not exits or is not directory");
qrInfo = null;
return qrInfo;
}
ImageIO.setCacheDirectory(new File(cachePath));
BufferedImage image = ImageIO.read(new File(imagePath));
LuminanceSource source = new BufferedImageLuminanceSource(image);
Binarizer binarizer = new HybridBinarizer(source);
BinaryBitmap binaryBitmap = new BinaryBitmap(binarizer);
Map<DecodeHintType, Object> hints = new HashMap<DecodeHintType, Object>();
hints.put(DecodeHintType.CHARACTER_SET, "UTF-8");
com.google.zxing.Result result = new MultiFormatReader().decode(binaryBitmap, hints);
qrInfo = result.getText();
return qrInfo;
} catch (Exception e) {
qrInfo = null;
return qrInfo;
}
}
/**
* 調用相機拍照
*
* @param imagePath 存儲拍攝照片的路徑
* @param cameraNumber 相機的編號【-1手動選擇】【0表示本機相機】【1~n表示usb攝像頭(這裏限制n最大爲5)】
* @return 是否完成拍照
*/
public static boolean takePhoto(String imagePath, int cameraNumber) {
try {
//判斷圖片路徑是否爲空
if (imagePath == null || "".equals(imagePath.trim())) {
System.err.println("Parameter \'imagePath\' cannot be empty");
return false;
}
//判斷相機參數是否越界
if (cameraNumber < -1 || cameraNumber > 5) {
System.err.println("Parameter \'cameraNumber\' out range");
return false;
}
//拍照並保存
Camera.grabber = new OpenCVFrameGrabber(cameraNumber);
Camera.StartCamera();
Camera.InitCamera = true;
OpenCVFrameGrabber grabber = Camera.grabber;
OpenCVFrameConverter.ToIplImage converter = new OpenCVFrameConverter.ToIplImage();
try {
boolean imwrite = false;
if (Camera.InitCamera) {
opencv_core.Mat mat = converter.convertToMat(grabber.grabFrame());
Camera.saveImage = Camera.Img.save;
if (Camera.saveImage == Camera.Img.save) {
imwrite = opencv_imgcodecs.imwrite(imagePath, mat);
}
}
Camera.StopCamera();
return imwrite;
} catch (Exception e) {
System.err.println("take photo error");
return false;
}
} catch (Exception e) {
System.err.println("init camera error");
Camera.InitCamera = false;
return false;
}
}
}