LaTeXr 开发记录

LaTeXr 开发记录

Mathpix Snip 是 Mathpix 公司开发的基于 AI 的跨平台公式识别软件,能够从照片、截屏或手写笔记中提取公式数据,并将其转化为 LaTeX、AsciiMath 或 MathML 等语法格式的文本,可直接粘贴至 Markdown、LaTeX、MS Word 等编辑器中,以实现公式的快速输入。借助它,人可以从繁杂的公式语法中解脱出来,而集中精力做更有意义的事。

Snip 识别迅速、准确率高,支持数学、物理学、化学等多学科的公式识别,尤以数学为佳。但对于免费账户,官方限制了 50 次/月的使用量。显然这个供给量对于理工科的人而言是远远不够的。好在 Mathpix 公司开放了其后台 AI 系统的 API, 同时针对 API 渠道,其慷慨地提供了 1000 次/月的使用量,于我足矣。基于此,我写了一个 macOS 平台下的菜单栏程序,并将其打包为了 Mac app,暂定名称为 LaTeXr。奈何时间有限,Windows 平台下的暂未予处理,请读者见谅。

申请 Mathpix API Keys

此步略过不述,只需按照 Mathpix 官网指引申请即可。成功后,记录你的 app_idapp_key

App 代码

关于代码的含义及相关注意事项,参见注释。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
import os
import json
import base64
import requests
from PIL import ImageGrab, Image
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *


# Replace '****' part with your own app_id and app_key
env = os.environ
default_headers = {
    'app_id': env.get('APP_ID', '****'),
    'app_key': env.get('APP_KEY', '****'),
    'Content-type': 'application/json'
}

service = 'https://api.mathpix.com/v3/latex'

# Create the application
app = QApplication([])
app.setQuitOnLastWindowClosed(False)

# Create the icon
icon = QIcon(r"../Resources/formula.png")

# Get the clipboard object in order to write the returned LaTeX text into it
clipboard = QApplication.clipboard()

# Read image file saved from clipboard
def image_uri(filename):
    image_data = open(filename, "rb").read()
    return "data:image/jpg;base64," + base64.b64encode(image_data).decode()

# Send requests to mathpix ocr service and return r.text from received json file 
def latex(args, headers=default_headers, timeout=30):
    r = requests.post(service, data=json.dumps(args), headers=headers, timeout=timeout)
    return json.loads(r.text)

# The main function
def convert():
    # Grab image from clipboard
    im = ImageGrab.grabclipboard()
    # Continue only if the content in clipboard is an image file
    if isinstance(im, Image.Image):
        # Save image from clipboard as local .png file
        im.save(r'../Resources/img/equa.png', 'PNG')
        # Call latex() and define in which format the service return the ocr result. You can set the format as 'text', 'latex_styled', 'latex_simplified', 'asciimath', 'mathml' or full of them.
        r = latex({
            'src':image_uri(r'../Resources/img/equa.png'),
            'formats': ['latex_styled']
            }
        )
        # Write the 'latex_styled' format text of the formula into clipboard
        clipboard.setText('$${}$$'.format(r['latex_styled']))
        # Call a notification with 'success' information and the 'confidence' value
        os.system("""osascript -e 'display notification "Finished with confidence {:.2f}%" with title "Formula"'""".format(r['latex_confidence']*100))
        # Remove the local .png file saved just now
        os.remove(r'../Resources/img/equa.png')

    else:
        # If there's no image found in clipboard, call a notification to let user know this issue
        os.system("""osascript -e 'display notification "No image found in clipboard !" with title "Formula"'""")

# Create the tray
tray = QSystemTrayIcon()
tray.setIcon(icon)
tray.setVisible(True)

# Create the menu
menu = QMenu()
action = QAction('Formula Recognize')
menu.addAction(action)
action.triggered.connect(lambda : convert())

# Add a Quit option to the menu.
quit = QAction("Quit")
quit.triggered.connect(app.quit)
menu.addAction(quit)

# Add the menu to the tray
tray.setContextMenu(menu)

app.exec_()

App 打包

请读者参考我的另一篇博文,Anaconda 环境下打包 Python 文件为 macOS app 本地运行 ,此处不予赘述。

使用效果

截取屏幕上的公式,将其存储于剪贴板内。随后使用 LaTeXr 进行识别,成功则弹出通知消息,并于后台将服务器返回的 LaTeX 文本写入剪贴板。如下所示:

Demo

随后直接在文本编辑器中粘贴,得到:

1
$$q _ { \max } \frac { 1 } { \tau } e ^ { - t / \tau } + \frac { 1 } { R C } q _ { \max } \left( 1 - e ^ { - t / \tau } \right) = \frac { V _ { \mathrm { emf } } } { R }$$

对其渲染后,得到:

\[q _ { \max } \frac { 1 } { \tau } e ^ { - t / \tau } + \frac { 1 } { R C } q _ { \max } \left( 1 - e ^ { - t / \tau } \right) = \frac { V _ { \mathrm { emf } } } { R }\]

总结

  • 虽然目前 LaTeXr 的功能比较单一,但已实现了其最核心的功能,小巧简洁,自用足矣。
  • 功能拓展方向:历史记录与查询、内置截图功能、手写功能、摄像头影像处理、云端同步功能、支持全局热键、支持开机启动、支持隐藏 Dock 图标、返回公式预览、多语法支持、支持音效等。
  • 如做商用,其背后的 AI 技术乃是核心。
坚持原创技术分享,您的支持将鼓励我继续创作!