目录
1 申请百度AI账号
2 创建AipOcr客户端client对象
3 创建图片操作对象
4 创建OcrServiceApplication对象
5 打jar包方便以后使用
不足之处:
最近在阅读PDF文档做笔记时,发现无法复制内容,手机QQ有功能(图片文字识别)可以但电脑上来回传输太麻烦.
需求分析:截图PDF==>文字识别OCR==>输出文字
三个步骤中其他功能好实现,只有OCR不好自己实现;如何解决实现文字识别呢?网上搜索了一下,最后决定使用百度提供的文字识别API。
1 申请百度AI账号
点链接,进去后点击控制台:
然后点击创建应用,信息随便填一填就好了,我这里已经创建好了:
\
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