Python笔记(四)——使用MathpixOCR API进行LaTeX公式识别
前言
本文介绍编写MathpixOCR API的Python包装器和简单的Automator workflow, 模拟Mathpix Snip Tool的公式识别体验.
用LaTeX准备文献报告时一个比较头疼的问题是输入文献中包含复杂符号的长公式. Mathpix Snip Tool (MST)提供了方便的光学字符识别功能, 可以将包含公式的截图转化为LaTeX代码. 今年MST从完全免费的1.0版本升级到了2.0, 自此个人用户每月只能免费识别50次, 这对于苦逼PhD显然是不够用的.
好在作为MST底层的MathpixOCR服务, API每月可免费调用1000次, 所得结果和MST相同, 只是没有MST方便的截图和GUI功能. 归根结底, 我们想实现的无非是识别剪贴板中的公式图片, 转化图片到LaTeX代码并复制到剪贴板而已. 这可以通过将OCR与OS命令包装在一起来实现. 官方提供了简单的例子供我们学习OCR API的使用, 而OS API可以通过Python包和CLI命令调用. 这篇文章是学习包装器编写的记录.
最终脚本已上传到GitHub仓库, 欢迎下载使用.
API包装
获取API密钥
首先需要在Mathpix上注册用户并填写信用卡信息, 注册后获得app_key
和app_id
作为API密钥.
脚本采用了两种从外部获取密钥的方式, 一种是环境变量, 另一种是从同路径下JSON读取.
从系统剪贴板获取图片
使用pillow包中的ImageGrab.grabclipboard
获取剪贴版中的图片, 并产生Image
对象.
注意, 此后剪贴板中的临时文件会被删除, 无法再直接通过路径获得.
1 | from PIL import ImageGrab |
因此需要先把图片保存下来才能在后续继续使用.
1 | im = ImageGrab.grabclipboard() |
base64编码
OCR需要把图片编码转化为base64编码格式. 官方例子如下
1 | import base64 |
b64encode
使用Base64规则将一串类字节字符串进行编码, decode
方法返回编码后的普通字符串.
1 | b"abcdefg") ec = base64.b64encode( |
前部附加的字符串是API额外要求的. 我还不太明白jpg
的作用, 因为当fn
是一个png图片时OCR一样可以正确解析.
调用API
通过requests
包与OCR API进行通信. 通信数据要求为JSON, 它至少需要包含src
和format
两个键. src
值就是base64编码后的图片字符串, format
值为一个列表, 成员为所想要转换的格式, 支持的转化格式包括下面几种.
format 值 |
转化格式 |
---|---|
text |
普通文本 |
wolfram |
Mathematica |
latex_simplified |
简化的latex代码, 括号不包含left或right |
latex_styled |
left/right控制的latex代码 |
利用json
包处理JSON文件
1 | data = json.dump({"src": img_base64, "format": ["latex_simplified",]}) |
通信得到的r.text
是一个JSON字符串. 如果OCR识别成功, 则它包含latex_simplified
键, 对应值为识别号的简化LaTeX代码.
如果识别失败, 则包含error
键, 给出具体错误信息. 更复杂的API调用参考官方文档.
拷贝转化好的LaTeX到系统剪贴板
参考了这个GIST, 使用macOS上的pbcopy
将字符串拷贝到系统剪贴板.
另一种办法是直接打印到标准输出, 然后用Automator服务中的功能拷贝到剪贴板.
附加功能
比如每月API调用统计以及历史记录, 都保存在JSON文件中. 实现说起来比较琐碎, 就不赘述了.
Automator服务
把写好的包装器放到~/bin
下, 编写简单的工作流Mathpix Snip OCR API
然后在系统设置-键盘-快捷键设置服务的快捷键
如此一来, cmd+shift+4
将公式截屏到剪贴板后cmd+shift+M
, 等待片刻即可从剪贴板黏贴转换好的公式. 大功告成!
参考资料
使用pillow包来获取剪贴板图片: Mathpix收费了?快使用API吧,一个月免费识别1000次!