PDF無法複製或圖片文字時,用java開發一個小程序來解決,下載jar包直接使用

目錄

1 申請百度AI賬號

 2 創建AipOcr客戶端client對象 

3 創建圖片操作對象 

4 創建OcrServiceApplication對象

 5 打jar包方便以後使用

不足之處:


最近在閱讀PDF文檔做筆記時,發現無法複製內容,手機QQ有功能(圖片文字識別)可以但電腦上來回傳輸太麻煩.

需求分析:截圖PDF==>文字識別OCR==>輸出文字 

三個步驟中其他功能好實現,只有OCR不好自己實現;如何解決實現文字識別呢?網上搜索了一下,最後決定使用百度提供的文字識別API。

1 申請百度AI賬號

http://ai.baidu.com/?track=cp:aipinzhuan|pf:pc|pp:AIpingtai|pu:title|ci:|kw:10005792

點鏈接,進去後點擊控制檯:

然後點擊創建應用,信息隨便填一填就好了,我這裏已經創建好了:

\

 2 創建AipOcr客戶端client對象 

閱讀AIPOcr的api創建client客戶端: 

public class OcrClient {
    //設置APPID/AK/SK
    public static final String APP_ID = "自己申請的";
    public static final String API_KEY = "自己申請的";
    public static final String SECRET_KEY = "自己申請的";

    public static  AipOcr createClient() {
        return new AipOcr(APP_ID, API_KEY, SECRET_KEY);
    }
    //文字識別
    public static void ocrOps( String fileName,AipOcr client) {//文字識別
        JSONObject res= client.basicAccurateGeneral(fileName,new HashMap<String, String>());
        JSONArray jsonArray = res.getJSONArray("words_result");
        int num = (int)res.get("words_result_num");
        for (int i = 0; i < num; i++) {
            String words = jsonArray.getJSONObject(i).get("words").toString();
            System.out.println(words);
        }
    }
}

 

把圖片保存到本地並提取filename(路徑及圖片名),測試一下

結果: 測試文字識別成功

3 創建圖片操作對象 

爲了減小存儲壓力,我把截取的圖片又刪除了; 

public class ImageOps {
    //保存文件
    public static void saveToFile(String pathStr, String fileName, BufferedImage saveImage){
        SimpleDateFormat sdf=new SimpleDateFormat("yyyymmddHHmmss");
        String name=sdf.format(new Date());
        File path= FileSystemView.getFileSystemView().getHomeDirectory();
        //pathStr= OcrServiceApplication.class.getResource("/").getPath();//class下
        String format="png";
        pathStr = path + "\\";
        //fileName = path + File.separator + name + "." + format;
        fileName = pathStr  + name + "." + format;
        File f=new File(fileName);
        try {
            ImageIO.write(saveImage, format, f);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    //快照截屏
    public static void snapshot(BufferedImage image ){
        try {
            Robot robot= new Robot();
            Dimension d=Toolkit.getDefaultToolkit().getScreenSize();
            image=robot.createScreenCapture(new Rectangle(0,0,d.width,d.height));
        } catch (AWTException e) {
            e.printStackTrace();
        }
    }
    //刪除本地圖片
    public static  void deleteDir(String path) {
        File file = new File(path);
        if (!file.exists()) {//判斷是否待刪除目錄是否存在
            System.err.println("The dir are not exists!");
        }

        String[] content = file.list();//取得當前目錄下所有文件和文件夾
        for (String name : content) {
            if (name.endsWith(".png")) {
                File temp = new File(path, name);
                if (temp.isDirectory()) {//判斷是否是目錄
                    deleteDir(temp.getAbsolutePath());//遞歸調用,刪除目錄裏的內容
                    temp.delete();//刪除空目錄
                } else {
                    if (!temp.delete()) {//直接刪除文件
                        System.err.println("Failed to delete " + name);
                    }
                }
            }
        }
    }
}

4 創建OcrServiceApplication對象

@SpringBootApplication
@Slf4j
public class OcrServiceApplication  extends JFrame{

    private static final long serialVersionUID = 1L;
    int orgx,orgy,endx,endy;
    static BufferedImage image;
    static BufferedImage tempImage;
    static BufferedImage saveImage;
    Graphics g;

    static String fileName;
    static String pathStr;
    static AipOcr client ;

    //繪製圖片
    @Override
    public void paint(Graphics g) {
        //縮放因子和偏移量
        RescaleOp ro=new RescaleOp(0.8f, 0, null);
        tempImage=ro.filter(image, null);
        g.drawImage(tempImage, 0, 0,this);
    }
    //構造器初始化監聽器
    public OcrServiceApplication(){
        setVisible(true);//可視化
        //setSize(d);//最大化窗口
        setDefaultCloseOperation(EXIT_ON_CLOSE);//關閉退出

        this.addMouseListener(new MouseAdapter(){
            public void mousePressed(MouseEvent e){
                orgx=e.getX();
                orgy=e.getY();
            }
        });
        //鼠標運動監聽器
        this.addMouseMotionListener(new MouseMotionAdapter() {//鼠標拖拽事件
            public void mouseDragged(MouseEvent e) {
                endx=e.getX();
                endy=e.getY();
                g=getGraphics();
                g.drawImage(tempImage, 0, 0, OcrServiceApplication.this);
                int x=Math.min(orgx, endx);
                int y=Math.min(orgy,endy);
                //加上1,防止width,height爲0
                int width=Math.abs(endx-orgx)+1;
                int height=Math.abs(endy-orgy)+1;
                g.setColor(Color.BLUE);
                g.drawRect(x-1, y-1, width+1, height+1);
                //減1,加1都是爲了防止圖片將矩形框覆蓋掉
                saveImage=image.getSubimage(x, y, width, height);
                g.drawImage(saveImage, x, y,OcrServiceApplication.this);
            }
        });
        //鍵盤監聽器
        this.addKeyListener(new KeyAdapter() {
            @Override
            public void keyReleased(KeyEvent e){
                    if (e.isControlDown() && e.isShiftDown() && e.getKeyCode() == KeyEvent.VK_H) {
                        log.debug("鍵盤按下了ctrl+shift+j:開始截圖了");
                        image=ImageOps.snapshot(image);
                        log.debug("開始截圖了成功");
                        setExtendedState(MAXIMIZED_BOTH);//最大化
                    }
                    if (e.getKeyCode() == KeyEvent.VK_ENTER) {
                        log.debug("鍵盤按下了enter");
                        fileName=ImageOps.saveToFile(pathStr,fileName,saveImage);
                        log.debug("保存圖片成功");
                        OcrClient.ocrOps(fileName, client);
                        log.debug("文字識別");
                        ImageOps.deleteDir(fileName.substring(0, fileName.lastIndexOf("\\")+1));
                        log.debug("刪除圖片");
                        setExtendedState(JFrame.ICONIFIED);//最小化
                    }
                    if(e.getKeyCode()==27){
                        System.exit(0); //按Esc鍵退出
                    }
            }
        });
    }

    public static void main(String[] args) {
        // 初始化一個AipOcr
        client = OcrClient.createClient();
        SpringApplication.run(OcrServiceApplication.class, args);
    }

}

 5 打jar包方便以後使用

 下載資源jar包:   點擊 OCR.jar包下載使用

百度網盤:

鏈接:https://pan.baidu.com/s/1KJ1NXFVzDtGkaEAScUPnOA 提取碼:cp26

操作: 先點擊激活窗體,在按Ctrl+Shift+H鍵並且鼠標拖拉選中截圖,然後按Enter鍵OCR識別文字輸出使用;Esc鍵或×號關閉程序

不足之處:

每次使用前都要點擊程序圖標激活(沒有使用全局鍵盤監聽,不能直接使用Ctrl+Shift+H鍵).

歡迎各位大佬幫忙提建議改善一下!

出現:

測試要提取的文字圖片:

結果展示使用:

文字使用: 

1、520那天我給我喜歡的女生髮了520的紅包。
女生也給我回了個520的紅包。
把我高興壞了。。。
後來約她出來看電影的時候,姑娘說:我不是把紅包還你了麼,你還約我出來幹嘛。

2、別人問你有談戀愛嗎?只要說現在沒有,能掩蓋過去也沒有的事實。
3、"一隻小鳥受傷了,小鳥媽媽關心地問道:“是怎麼受的傷?”小鳥說:“我跟在爸爸身後,

料爸爸放了個屁,我一捂嘴巴,結果掉到地上受傷了鳥媽媽語重心長的說:“前事不忘後事之
師,傻孩子,記住了,以後別人放屁千萬別捂嘴了。”
4、公司新來了一個小夥,斯斯文文挺乾淨的感覺。
公司一女的對他有意思,但她性格要強,抹不開面,於是就每天利用工作找他麻煩,和他鬥嘴,
想着
能像電視裏那樣成爲一對歡喜冤家。
果然,沒過幾天,小夥子打了她一頓,辭職走了。

 歡迎各位大佬幫忙提建議改善一下!

 

改善一下: 使用全局監聽

1.加入jintellitype依賴

 <dependency>
   <groupId>com.melloware</groupId>
   <artifactId>jintellitype</artifactId>
   <version>1.3.9</version>
 </dependency>

2.把JIntellitype.dll和JIntellitype64.dll複製到java的bin文件夾下如:D:\Java\jdk1.8.0_40\bin

否則,會拋出異常:

Exception in thread "main" com.melloware.jintellitype.JIntellitypeException: Could not load JIntellitype.dll from local file system or from inside JAR
at com.melloware.jintellitype.JIntellitype.<init>(JIntellitype.java:114)
at com.melloware.jintellitype.JIntellitype.getInstance(JIntellitype.java:177)
at com.bjlemon.automsg.Application.<init>(Application.java:50)
at com.bjlemon.automsg.Application.main(Application.java:29)
Caused by: java.io.IOException: FromJarToFileSystem could not load DLL: com/melloware/jintellitype/JIntellitype.dll
at com.melloware.jintellitype.JIntellitype.fromJarToFs(JIntellitype.java:150)
at com.melloware.jintellitype.JIntellitype.<init>(JIntellitype.java:105)
... 3 more
Caused by: java.lang.NullPointerException
at com.melloware.jintellitype.JIntellitype.fromJarToFs(JIntellitype.java:146)
... 4 more 

解決方法: 

把JIntellitype.dll和JIntellitype64.dll複製到JAVA_HOME使用到的java的bin文件夾下如:D:\Java\jdk1.8.0_40\bin

3.修改程序中的鍵盤監聽器

 

//鍵盤監聽器
        this.addKeyListener(new KeyAdapter() {
            @Override
            public void keyReleased(KeyEvent e){
                if (e.isControlDown() && e.isShiftDown() && e.getKeyCode() == KeyEvent.VK_H) {
                    log.debug("鍵盤按下了ctrl+shift+j:開始截圖了");
                    image=ImageOps.snapshot(image);
                    log.debug("開始截圖了成功");
                    setExtendedState(MAXIMIZED_BOTH);//最大化
                }
                if (e.getKeyCode() == KeyEvent.VK_ENTER) {
                    log.debug("鍵盤按下了enter");
                    fileName=ImageOps.saveToFile(pathStr,fileName,saveImage);
                    log.debug("保存圖片成功");
                    OcrClient.ocrOps(fileName, client);
                    log.debug("文字識別");
                    ImageOps.deleteDir(fileName.substring(0, fileName.lastIndexOf("\\")+1));
                    log.debug("刪除圖片");
                    setExtendedState(JFrame.ICONIFIED);//最小化
                }
                if(e.getKeyCode()==27){
                    System.exit(0); //按Esc鍵退出
                }
            }
        });

修改後:

    // ......
     //鍵盤監聽器
       init();
    }

    // 初始化
    private void init() {
        // 第一步:註冊熱鍵,熱鍵標識
        JIntellitype.getInstance().registerHotKey(GLOBAL_HOT_KEY_1,0, 0x1B);//esc
        JIntellitype.getInstance().registerHotKey(GLOBAL_HOT_KEY_2,JIntellitype.MOD_ALT , (int) 'Q');//Alt+Q
        JIntellitype.getInstance().registerHotKey(GLOBAL_HOT_KEY_3,JIntellitype.MOD_ALT , (int) 'S');//Alt+S
        //JIntellitype.getInstance().registerHotKey(GLOBAL_HOT_KEY_3,0 , 0x0D);//Enter

        // 添加熱鍵監聽器
        // 第二步:添加熱鍵監聽器
        JIntellitype.getInstance().addHotKeyListener(new HotkeyListener() {
            @Override
            public void onHotKey(int markCode) {
                switch (markCode) {
                    case GLOBAL_HOT_KEY_1:
                        log.debug("鍵盤按下了Esc:退出程序!");
                        System.exit(0);
                        break;
                    case GLOBAL_HOT_KEY_2:
                        log.debug(" 鍵盤按下了Alt+Q:開始截圖了");
                        image=ImageOps.snapshot(image);
                        setExtendedState(MAXIMIZED_BOTH);//最大化
                        break;
                    case GLOBAL_HOT_KEY_3:
                        log.debug("鍵盤按下了Alt+S");
                        fileName=ImageOps.saveToFile(pathStr,fileName,saveImage);
                        OcrClient.ocrOps(fileName, client);
                        ImageOps.deleteDir(fileName.substring(0, fileName.lastIndexOf("\\")+1));
                        setExtendedState(JFrame.ICONIFIED);//最小化
                        break;
                }
            }
        });

 4. 打包並運行jar

複製使用:

5使用方法

按下Alt+Q(使用了全局監聽) 開啓應用,然後選中要識別的文字,按Alt+S開始識別文字

改善後的 ocr02.jar包下載

進一步改善程序:

用exe4j把jar程序轉換爲exe,雙擊即可使用,.下一篇:

用exe4j轉換jar包爲exe文件,不用配置jdk jre環境變量可直接雙擊使用

 

下載使用 :ocr04_jar2exe

發佈了29 篇原創文章 · 獲贊 30 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章