最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java實(shí)現(xiàn)識(shí)別二維碼圖片功能

 更新時(shí)間:2022年04月21日 15:43:17   作者:weijx_  
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)識(shí)別二維碼圖片功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

本文實(shí)例為大家分享了java實(shí)現(xiàn)識(shí)別二維碼圖片功能,供大家參考,具體內(nèi)容如下

所需maven依賴(lài)

<dependency>
? ?<groupId>com.google.zxing</groupId>
? ?<artifactId>javase</artifactId>
? ?<version>3.2.1</version>
</dependency>
<dependency>
? ? <groupId>com.google.zxing</groupId>
? ? <artifactId>core</artifactId>
? ? <version>3.3.3</version>
</dependency>

實(shí)現(xiàn)的java類(lèi)

import com.google.zxing.*;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.common.HybridBinarizer;
import sun.misc.BASE64Decoder;
?
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
/**
?* 作用:二維碼識(shí)別(圖片)
?* 類(lèi)名:QRCodeUtils
?**/
public class QRCodeUtils {
? ? /**
? ? ?* 解析二維碼,此方法解析一個(gè)路徑的二維碼圖片
? ? ?* path:圖片路徑
? ? ?*/
? ? public static String deEncodeByPath(String path) {
? ? ? ? String content = null;
? ? ? ? BufferedImage image;
? ? ? ? try {
? ? ? ? ? ? image = ImageIO.read(new File(path));
? ? ? ? ? ? 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");
? ? ? ? ? ? Result result = new MultiFormatReader().decode(binaryBitmap, hints);//解碼
? ? ? ? ? ? System.out.println("圖片中內(nèi)容: ?");
? ? ? ? ? ? System.out.println("content: " + result.getText());
? ? ? ? ? ? content = result.getText();
? ? ? ? } catch (IOException e) {
? ? ? ? ? ? e.printStackTrace();
? ? ? ? } catch (NotFoundException e) {
?? ??? ??? ?//這里判斷如果識(shí)別不了帶LOGO的圖片,重新添加上一個(gè)屬性
? ? ? ? ? ? try {
?? ??? ??? ??? ?image = ImageIO.read(new File(path));
?? ??? ??? ??? ?LuminanceSource source = new BufferedImageLuminanceSource(image);
?? ??? ??? ??? ?Binarizer binarizer = new HybridBinarizer(source);
?? ??? ??? ??? ?BinaryBitmap binaryBitmap = new BinaryBitmap(binarizer);
?? ??? ??? ??? ?Map<DecodeHintType, Object> hints = new HashMap<DecodeHintType, Object>();
?? ??? ??? ??? ?//設(shè)置編碼格式
?? ??? ??? ??? ?hints.put(DecodeHintType.CHARACTER_SET, "UTF-8");
?? ??? ??? ??? ?//設(shè)置優(yōu)化精度
?? ??? ??? ??? ?hints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);
?? ??? ??? ??? ?//設(shè)置復(fù)雜模式開(kāi)啟(我使用這種方式就可以識(shí)別微信的二維碼了)
?? ??? ??? ??? ?hints.put(DecodeHintType.PURE_BARCODE,Boolean.TYPE);
?? ??? ??? ??? ?Result result = new MultiFormatReader().decode(binaryBitmap, hints);//解碼
?? ??? ??? ??? ?System.out.println("圖片中內(nèi)容: ?");
?? ??? ??? ??? ?System.out.println("content: " + result.getText());
?? ??? ??? ??? ?content = result.getText();
?? ??? ??? ?} catch (IOException e) {
?? ??? ??? ??? ?e.printStackTrace();
?? ??? ??? ?} catch (NotFoundException e) {
?? ??? ??? ??? ?e.printStackTrace();
?? ??? ??? ?}
? ? ? ? }
? ? ? ? return content;
? ? }
}

測(cè)試

public static void main(String [] args){
?? ?deEncodeByPath("D:\\Users/admin/Desktop/erweima/timg (5).jpg");//二維碼圖片路徑
}

輸出結(jié)果:

圖片中內(nèi)容:
content: http://qrcode.online

如果上述不能識(shí)別的話(huà),那么就需要對(duì)圖片處理一次,然后再進(jìn)行識(shí)別,這里是個(gè)調(diào)優(yōu)圖片的工具類(lèi)。

package com.face.ele.common.utils;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

/**
?* @author weijianxing
?* @description: TODO
?* @date 2020/11/26 9:28
?*/
public class ImageOptimizationUtil {

? ? // 閾值0-255
? ? public static int YZ = 150;

? ? /**
? ? ?* 圖像二值化處理
? ? ?*
? ? ?* @param filePath 要處理的圖片路徑
? ? ?* @param fileOutputPath 處理后的圖片輸出路徑
? ? ?*/
? ? public static void binarization(String filePath, String fileOutputPath) throws IOException {
? ? ? ? File file = new File(filePath);
? ? ? ? BufferedImage bi = ImageIO.read(file);
? ? ? ? // 獲取當(dāng)前圖片的高,寬,ARGB
? ? ? ? int h = bi.getHeight();
? ? ? ? int w = bi.getWidth();
? ? ? ? int arr[][] = new int[w][h];

? ? ? ? // 獲取圖片每一像素點(diǎn)的灰度值
? ? ? ? for (int i = 0; i < w; i++) {
? ? ? ? ? ? for (int j = 0; j < h; j++) {
? ? ? ? ? ? ? ? // getRGB()返回默認(rèn)的RGB顏色模型(十進(jìn)制)
? ? ? ? ? ? ? ? arr[i][j] = getImageGray(bi.getRGB(i, j));// 該點(diǎn)的灰度值
? ? ? ? ? ? }
? ? ? ? }

? ? ? ? // 構(gòu)造一個(gè)類(lèi)型為預(yù)定義圖像類(lèi)型,BufferedImage
? ? ? ? BufferedImage bufferedImage = new BufferedImage(w, h, BufferedImage.TYPE_BYTE_BINARY);

? ? ? ? // 和預(yù)先設(shè)置的閾值大小進(jìn)行比較,大的就顯示為255即白色,小的就顯示為0即黑色
? ? ? ? for (int i = 0; i < w; i++) {
? ? ? ? ? ? for (int j = 0; j < h; j++) {
? ? ? ? ? ? ? ? if (getGray(arr, i, j, w, h) > YZ) {
? ? ? ? ? ? ? ? ? ? int white = new Color(255, 255, 255).getRGB();
? ? ? ? ? ? ? ? ? ? bufferedImage.setRGB(i, j, white);
? ? ? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? ? ? int black = new Color(0, 0, 0).getRGB();
? ? ? ? ? ? ? ? ? ? bufferedImage.setRGB(i, j, black);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }

? ? ? ? }
? ? ? ? ImageIO.write(bufferedImage, "jpg", new File(fileOutputPath));
? ? }

? ? /**
? ? ?* 圖像的灰度處理
? ? ?* 利用浮點(diǎn)算法:Gray = R*0.3 + G*0.59 + B*0.11;
? ? ?*
? ? ?* @param rgb 該點(diǎn)的RGB值
? ? ?* @return 返回處理后的灰度值
? ? ?*/
? ? private static int getImageGray(int rgb) {
? ? ? ? String argb = Integer.toHexString(rgb);// 將十進(jìn)制的顏色值轉(zhuǎn)為十六進(jìn)制
? ? ? ? // argb分別代表透明,紅,綠,藍(lán) 分別占16進(jìn)制2位
? ? ? ? int r = Integer.parseInt(argb.substring(2, 4), 16);// 后面參數(shù)為使用進(jìn)制
? ? ? ? int g = Integer.parseInt(argb.substring(4, 6), 16);
? ? ? ? int b = Integer.parseInt(argb.substring(6, 8), 16);
? ? ? ? int gray = (int) (r*0.28 + g*0.95 + b*0.11);
? ? ? ? return gray;
? ? }

? ? /**
? ? ?* 自己加周?chē)?個(gè)灰度值再除以9,算出其相對(duì)灰度值
? ? ?*
? ? ?* @param gray
? ? ?* @param x 要計(jì)算灰度的點(diǎn)的橫坐標(biāo)
? ? ?* @param y 要計(jì)算灰度的點(diǎn)的縱坐標(biāo)
? ? ?* @param w 圖像的寬度
? ? ?* @param h 圖像的高度
? ? ?* @return
? ? ?*/
? ? public static int getGray(int gray[][], int x, int y, int w, int h) {
? ? ? ? int rs = gray[x][y] + (x == 0 ? 255 : gray[x - 1][y]) + (x == 0 || y == 0 ? 255 : gray[x - 1][y - 1])
? ? ? ? ? ? ? ? + (x == 0 || y == h - 1 ? 255 : gray[x - 1][y + 1]) + (y == 0 ? 255 : gray[x][y - 1])
? ? ? ? ? ? ? ? + (y == h - 1 ? 255 : gray[x][y + 1]) + (x == w - 1 ? 255 : gray[x + 1][y])
? ? ? ? ? ? ? ? + (x == w - 1 || y == 0 ? 255 : gray[x + 1][y - 1])
? ? ? ? ? ? ? ? + (x == w - 1 || y == h - 1 ? 255 : gray[x + 1][y + 1]);
? ? ? ? return rs / 9;
? ? }

? ? /**
? ? ?* 二值化后的圖像的開(kāi)運(yùn)算:先腐蝕再膨脹(用于去除圖像的小黑點(diǎn))
? ? ?*
? ? ?* @param filePath 要處理的圖片路徑
? ? ?* @param fileOutputPath 處理后的圖片輸出路徑
? ? ?* @throws IOException
? ? ?*/
? ? public static void opening(String filePath, String fileOutputPath) throws IOException {
? ? ? ? File file = new File(filePath);
? ? ? ? BufferedImage bi = ImageIO.read(file);
? ? ? ? // 獲取當(dāng)前圖片的高,寬,ARGB
? ? ? ? int h = bi.getHeight();
? ? ? ? int w = bi.getWidth();
? ? ? ? int arr[][] = new int[w][h];
? ? ? ? // 獲取圖片每一像素點(diǎn)的灰度值
? ? ? ? for (int i = 0; i < w; i++) {
? ? ? ? ? ? for (int j = 0; j < h; j++) {
? ? ? ? ? ? ? ? // getRGB()返回默認(rèn)的RGB顏色模型(十進(jìn)制)
? ? ? ? ? ? ? ? arr[i][j] = getImageGray(bi.getRGB(i, j));// 該點(diǎn)的灰度值
? ? ? ? ? ? }
? ? ? ? }

? ? ? ? int black = new Color(0, 0, 0).getRGB();
? ? ? ? int white = new Color(255, 255, 255).getRGB();
? ? ? ? BufferedImage bufferedImage = new BufferedImage(w, h, BufferedImage.TYPE_BYTE_BINARY);
? ? ? ? // 臨時(shí)存儲(chǔ)腐蝕后的各個(gè)點(diǎn)的亮度
? ? ? ? int temp[][] = new int[w][h];
? ? ? ? // 1.先進(jìn)行腐蝕操作
? ? ? ? for (int i = 0; i < w; i++) {
? ? ? ? ? ? for (int j = 0; j < h; j++) {
? ? ? ? ? ? ? ? /*
? ? ? ? ? ? ? ? ?* 為0表示改點(diǎn)和周?chē)?個(gè)點(diǎn)都是黑,則該點(diǎn)腐蝕操作后為黑
? ? ? ? ? ? ? ? ?* 由于公司圖片態(tài)模糊,完全達(dá)到9個(gè)點(diǎn)全為黑的點(diǎn)太少,最后效果很差,故改為了小于30
? ? ? ? ? ? ? ? ?* (寫(xiě)30的原因是,當(dāng)只有一個(gè)點(diǎn)為白,即總共255,調(diào)用getGray方法后得到255/9 = 28)
? ? ? ? ? ? ? ? ?*/
? ? ? ? ? ? ? ? if (getGray(arr, i, j, w, h) < 30) {
? ? ? ? ? ? ? ? ? ? temp[i][j] = 0;
? ? ? ? ? ? ? ? } else{
? ? ? ? ? ? ? ? ? ? temp[i][j] = 255;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? }

? ? ? ? // 2.再進(jìn)行膨脹操作
? ? ? ? for (int i = 0; i < w; i++) {
? ? ? ? ? ? for (int j = 0; j < h; j++) {
? ? ? ? ? ? ? ? bufferedImage.setRGB(i, j, white);
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? for (int i = 0; i < w; i++) {
? ? ? ? ? ? for (int j = 0; j < h; j++) {
? ? ? ? ? ? ? ? // 為0表示改點(diǎn)和周?chē)?個(gè)點(diǎn)都是黑,則該點(diǎn)腐蝕操作后為黑
? ? ? ? ? ? ? ? if (temp[i][j] == 0) {
? ? ? ? ? ? ? ? ? ? bufferedImage.setRGB(i, j, black);
? ? ? ? ? ? ? ? ? ? if(i > 0) {
? ? ? ? ? ? ? ? ? ? ? ? bufferedImage.setRGB(i-1, j, black);
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? if (j > 0) {
? ? ? ? ? ? ? ? ? ? ? ? bufferedImage.setRGB(i, j-1, black);
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? if (i > 0 && j > 0) {
? ? ? ? ? ? ? ? ? ? ? ? bufferedImage.setRGB(i-1, j-1, black);
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? if (j < h-1) {
? ? ? ? ? ? ? ? ? ? ? ? bufferedImage.setRGB(i, j+1, black);
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? if (i < w-1) {
? ? ? ? ? ? ? ? ? ? ? ? bufferedImage.setRGB(i+1, j, black);
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? if (i < w-1 && j > 0) {
? ? ? ? ? ? ? ? ? ? ? ? bufferedImage.setRGB(i+1, j-1, black);
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? if (i < w-1 && j < h-1) {
? ? ? ? ? ? ? ? ? ? ? ? bufferedImage.setRGB(i+1, j+1, black);
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? if (i > 0 && j < h-1) {
? ? ? ? ? ? ? ? ? ? ? ? bufferedImage.setRGB(i-1, j+1, black);
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? }

? ? ? ? ImageIO.write(bufferedImage, "jpg", new File(fileOutputPath));
? ? }

? ? public static void main(String[] args) {
? ? ? ? String fullPath="E:\\weijianxing\\img\\微信圖片_20201202160240.jpg";
? ? ? ? String newPath="E:\\weijianxing\\img\\1new_微信圖片_20201202160240.jpg";
? ? ? ? try {
? ? ? ? ? ? ImageOptimizationUtil.binarization(fullPath,newPath);
? ? ? ? } catch (IOException e) {
? ? ? ? ? ? e.printStackTrace();
? ? ? ? }
? ? }
}

可以手動(dòng)測(cè)試,然后對(duì)改代碼的部分進(jìn)行調(diào)正對(duì)應(yīng)的參數(shù)-- gray變量里的計(jì)算進(jìn)行灰度調(diào)整

private static int getImageGray(int rgb) {
? ? ? ? String argb = Integer.toHexString(rgb);// 將十進(jìn)制的顏色值轉(zhuǎn)為十六進(jìn)制
? ? ? ? // argb分別代表透明,紅,綠,藍(lán) 分別占16進(jìn)制2位
? ? ? ? int r = Integer.parseInt(argb.substring(2, 4), 16);// 后面參數(shù)為使用進(jìn)制
? ? ? ? int g = Integer.parseInt(argb.substring(4, 6), 16);
? ? ? ? int b = Integer.parseInt(argb.substring(6, 8), 16);
? ? ? ? int gray = (int) (r*0.28 + g*0.95 + b*0.11);
? ? ? ? return gray;
? ? }

等調(diào)整之后,在對(duì)圖片進(jìn)行識(shí)別即可。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • RocketMQ?Broker實(shí)現(xiàn)高可用高并發(fā)的消息中轉(zhuǎn)服務(wù)

    RocketMQ?Broker實(shí)現(xiàn)高可用高并發(fā)的消息中轉(zhuǎn)服務(wù)

    RocketMQ消息代理(Broker)是一種高可用、高并發(fā)的消息中轉(zhuǎn)服務(wù),能夠接收并存儲(chǔ)生產(chǎn)者發(fā)送的消息,并將消息發(fā)送給消費(fèi)者。它具有多種消息存儲(chǔ)模式和消息傳遞模式,支持水平擴(kuò)展和故障轉(zhuǎn)移等特性,可以為分布式應(yīng)用提供可靠的消息傳遞服務(wù)
    2023-04-04
  • Nett中的心跳機(jī)制與斷線重連詳解

    Nett中的心跳機(jī)制與斷線重連詳解

    這篇文章主要介紹了Nett中的心跳機(jī)制與斷線重連詳解,我們以客戶(hù)端發(fā)送心跳為例,平時(shí)我們的心跳實(shí)現(xiàn)方式可能是搞個(gè)定時(shí)器,定時(shí)發(fā)送是吧,但是在Netty中卻不一樣,心跳被稱(chēng)為空閑檢測(cè),需要的朋友可以參考下
    2023-12-12
  • Mybatis之collection標(biāo)簽中javaType和ofType屬性的區(qū)別說(shuō)明

    Mybatis之collection標(biāo)簽中javaType和ofType屬性的區(qū)別說(shuō)明

    這篇文章主要介紹了Mybatis之collection標(biāo)簽中javaType和ofType屬性的區(qū)別說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • Java?Runtime的使用詳解

    Java?Runtime的使用詳解

    這篇文章主要介紹了Java?Runtime的使用詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • Java19新特性虛擬線程的具體使用

    Java19新特性虛擬線程的具體使用

    Java 19 引入了虛擬線程,這是 JDK Project Loom 項(xiàng)目中的重要新特性,目的是簡(jiǎn)化 Java 中的并發(fā)編程,并提高線程管理的效率和性能,下面就來(lái)具體介紹下
    2024-09-09
  • Java實(shí)現(xiàn)文件分割與合并

    Java實(shí)現(xiàn)文件分割與合并

    這篇文章主要介紹了Java實(shí)現(xiàn)文件分割與合并,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-05-05
  • Java中ByteArrayOutputStream亂碼問(wèn)題解決

    Java中ByteArrayOutputStream亂碼問(wèn)題解決

    本文主要介紹了Java中ByteArrayOutputStream亂碼問(wèn)題解決,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-07-07
  • bootstrap.yml如何讀取nacos配置中心的配置文件

    bootstrap.yml如何讀取nacos配置中心的配置文件

    這篇文章主要介紹了bootstrap.yml讀取nacos配置中心的配置文件問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • 簡(jiǎn)單介紹Java網(wǎng)絡(luò)編程中的HTTP請(qǐng)求

    簡(jiǎn)單介紹Java網(wǎng)絡(luò)編程中的HTTP請(qǐng)求

    這篇文章主要介紹了簡(jiǎn)單介紹Java網(wǎng)絡(luò)編程中的HTTP請(qǐng)求,需要的朋友可以參考下
    2015-09-09
  • Java面向?qū)ο笾^承性的實(shí)例代碼詳解

    Java面向?qū)ο笾^承性的實(shí)例代碼詳解

    這篇文章主要介紹了Java面向?qū)ο笾^承性,文中代碼簡(jiǎn)單易懂,可以更好的幫助大家學(xué)習(xí),有興趣的小伙伴快來(lái)了解下
    2020-05-05

最新評(píng)論

嘉禾县| 宜兰县| 定结县| 诏安县| 阳信县| 视频| 榆社县| 丹江口市| 阜南县| 墨玉县| 渭源县| 万源市| 武陟县| 商河县| 汉沽区| 鸡东县| 浠水县| 潜江市| 珲春市| 德惠市| 资兴市| 陆川县| 永清县| 辰溪县| 香河县| 乾安县| 阜平县| 吴川市| 墨江| 沈丘县| 江城| 东城区| 江永县| 从江县| 固安县| 仙居县| 德兴市| 禄劝| 雷山县| 湾仔区| 道孚县|