From 89376eb9f14fa7670bb72534f27096406da45bf9 Mon Sep 17 00:00:00 2001 From: SWHL Date: Thu, 21 Dec 2023 09:56:15 +0800 Subject: [PATCH] Update files --- .github/workflows/auto_push_pypi.yml | 17 +-- README.md | 44 +++++--- demo.py | 7 +- docs/doc_whl.md | 1 + latex_to_image/main.py | 26 ++++- latex_to_image/render_latex.py | 12 +-- requirements.txt | 2 +- res2.png | Bin 743 -> 0 bytes setup.py | 75 ++++++++++++++ t.py | 148 --------------------------- tests/test_latex2img.py | 23 ----- tests/test_render_two.py | 26 ----- tests/test_template.py | 5 - 13 files changed, 138 insertions(+), 248 deletions(-) create mode 100644 docs/doc_whl.md delete mode 100644 res2.png create mode 100644 setup.py delete mode 100644 t.py delete mode 100644 tests/test_latex2img.py delete mode 100644 tests/test_render_two.py delete mode 100644 tests/test_template.py diff --git a/.github/workflows/auto_push_pypi.yml b/.github/workflows/auto_push_pypi.yml index b85bd40..30c1690 100644 --- a/.github/workflows/auto_push_pypi.yml +++ b/.github/workflows/auto_push_pypi.yml @@ -24,17 +24,6 @@ jobs: - name: Display Python version run: python -c "import sys; print(sys.version)" - - name: Unit testings - run: | - pip install -r requirements.txt - pip install pytest - - wget https://github.com/RapidAI/TableStructureRec/releases/download/v0.0.0/lineless_table_rec_models.zip - unzip lineless_table_rec_models.zip - mv lineless_table_rec_models/*.onnx lineless_table_rec/models/ - - pytest tests/test_lore.py - GenerateWHL_PushPyPi: needs: UnitTesting runs-on: ubuntu-latest @@ -54,11 +43,7 @@ jobs: python -m pip install --upgrade pip pip install wheel get_pypi_latest_version - wget https://github.com/RapidAI/TableStructureRec/releases/download/v0.0.0/lineless_table_rec_models.zip - unzip lineless_table_rec_models.zip - mv lineless_table_rec_models/*.onnx lineless_table_rec/models/ - - python setup_lineless.py bdist_wheel ${{ github.event.head_commit.message }} + python setup.py bdist_wheel ${{ github.event.head_commit.message }} # - name: Publish distribution 📦 to Test PyPI # uses: pypa/gh-action-pypi-publish@v1.5.0 diff --git a/README.md b/README.md index 1357436..e54c4b9 100644 --- a/README.md +++ b/README.md @@ -14,26 +14,37 @@ 该仓库是用于将LaTeX的公式借助LaTeX工具转换为对应的图像。 -### 安装 -1. 安装texlive -- Ubuntu - ```bash - # Ubuntu - sudo apt-get install texlive-full - - # 确认是否安装成功 - $ pdflatex --help - Usage: pdftex [OPTION]... [TEXNAME[.tex]] [COMMANDS] - or: pdftex [OPTION]... \FIRST-LINE - or: pdftex [OPTION]... &FMT ARGS - Run pdfTeX on TEXNAME, usually creating TEXNAME.pdf. - ``` -- MacOS +### 安装LaTeX编译环境 +Ubuntu: +```bash +sudo apt-get install texlive-full + +# 确认是否安装成功 +$ xelatex --help +# Usage: pdftex [OPTION]... [TEXNAME[.tex]] [COMMANDS] +# or: pdftex [OPTION]... \FIRST-LINE +# or: pdftex [OPTION]... &FMT ARGS + # Run pdfTeX on TEXNAME, usually creating TEXNAME.pdf. +``` + +MacOS + 推荐安装[MacTex](https://tug.org/mactex/mactex-download.html) +验证是否安装成功: +```bash +$ xelatex --help -2. 安装运行环境 +# Usage: xetex [OPTION]... [TEXNAME[.tex]] [COMMANDS] +# or: xetex [OPTION]... \FIRST-LINE +# or: xetex [OPTION]... &FMT ARGS +# Run XeTeX on TEXNAME, usually creating TEXNAME.pdf. +``` +### 安装运行环境 +```bash +pip install latex_to_image +``` ### 使用 @@ -41,4 +52,3 @@ ### 参考代码 - [LaTeX-OCR](https://github.com/lukas-blecher/LaTeX-OCR/blob/main/pix2tex/dataset/latex2png.py) -- [latex2image](https://pypi.org/project/latex2image/#description) \ No newline at end of file diff --git a/demo.py b/demo.py index a7497b4..558d8b0 100644 --- a/demo.py +++ b/demo.py @@ -1,7 +1,7 @@ # -*- encoding: utf-8 -*- # @Author: SWHL # @Contact: liekkaskono@163.com -from PIL import Image +import cv2 from latex_to_image import LaTeXToImg @@ -9,7 +9,6 @@ formula = "x^2 + y ^2 = 1" -img_formula = render(formula) -img_formula = Image.fromarray(img_formula) -img_formula.save("res2.png") +img = render(formula) +cv2.imwrite("res.png", img) print("ok") diff --git a/docs/doc_whl.md b/docs/doc_whl.md new file mode 100644 index 0000000..0b59c23 --- /dev/null +++ b/docs/doc_whl.md @@ -0,0 +1 @@ +### See details for [latex_to_image](https://github.com/SWHL/latex_to_image) \ No newline at end of file diff --git a/latex_to_image/main.py b/latex_to_image/main.py index 86fddd1..4dc0cea 100644 --- a/latex_to_image/main.py +++ b/latex_to_image/main.py @@ -1,6 +1,10 @@ # -*- encoding: utf-8 -*- # @Author: SWHL # @Contact: liekkaskono@163.com +import argparse +from typing import Optional + +import cv2 import numpy as np from .crop_img import CropByProject @@ -14,9 +18,29 @@ def __init__( self.cropper = CropByProject() self.latex = RenderLaTeX() - def __call__(self, math: str) -> np.ndarray: + def __call__(self, math: Optional[str] = None) -> np.ndarray: + if len(math.strip()) <= 0 or math is None: + raise ValueError("The input of formula must have value.") + img = self.latex(math) img = self.cropper(img) return img +def main(): + parser = argparse.ArgumentParser() + parser.add_argument("math", type=str, default=None) + parser.add_argument("save_path", type=str, default="res.png") + args = parser.parse_args() + + render = LaTeXToImg() + img = render(args.math) + if img is not None: + cv2.imwrite(args.save_path, img) + print(f"The image has been saved in {args.save_path} .") + else: + print("The result of render formula is empty.") + + +if __name__ == "__main__": + main() diff --git a/latex_to_image/render_latex.py b/latex_to_image/render_latex.py index fb8fef5..ff4ff6b 100644 --- a/latex_to_image/render_latex.py +++ b/latex_to_image/render_latex.py @@ -1,7 +1,6 @@ # -*- encoding: utf-8 -*- # mostly taken from http://code.google.com/p/latexmath2png/ # install preview.sty -import io import os import re import shlex @@ -11,8 +10,7 @@ from pathlib import Path from typing import Union -import numpy as np -from PIL import Image +import cv2 class RenderLaTeX: @@ -52,15 +50,15 @@ def render_by_xelatex(self, work_dir, in_file) -> Path: ) if flag: return pdf_file - raise LatexError("xelatex meets error.") + raise LaTeXError("xelatex meets error.") def convert_pdf_to_png(self, pdf_file): png_file: Path = Path(pdf_file).with_suffix(".png") cmd = f"convert -background white -flatten -density {self.dpi} -colorspace gray {pdf_file} -quality 90 {png_file}" _, return_code = self.run_cmd(cmd) if return_code != 0: - raise LatexError(f"PDF to png error\n{cmd}\n{pdf_file}") - img = np.array(Image.open(png_file)) + raise LaTeXError(f"PDF to png error\n{cmd}\n{pdf_file}") + img = cv2.imread(str(png_file)) return img @staticmethod @@ -94,5 +92,5 @@ def clear_files(in_file: Union[str, Path]) -> None: file_path.unlink() -class LatexError(Exception): +class LaTeXError(Exception): pass diff --git a/requirements.txt b/requirements.txt index 9b70bf7..421081e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,2 @@ opencv_python_headless -Pillow +numpy \ No newline at end of file diff --git a/res2.png b/res2.png deleted file mode 100644 index 7cae05973bc839760cfcf7a33404ea8e943d56dd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 743 zcmV?P)`mC%&{5y@W!OhkKs*2ps0m znVE#0@c&~UxbLmcG9AyKgy&=S?od>o?oTm9vZvyaIha;Nq$ZnPU5`XOvqqluRYXKI zbrg9jp4oIe{|Uem8QIesx5#RM^G3n@>d;J=gN@*MhKNX> zUnN(Ui|M7L7m@tF+HWeHi|KDnOPc;Q&xXROvK-p3qSfaHYiJ(X*(Uj_)zH)c-lM}j zZf;wovV}5w@d-w|0VrO#idC>4cLw&fjcROpY%8T5QOO2QUx(b=V~Q#~ zSb*UR*a_Z~DHz=P-gd}>5w~EPN?)Um{DH? List: + if not isinstance(txt_path, str): + txt_path = str(txt_path) + + with open(txt_path, "r", encoding="utf-8") as f: + data = list(map(lambda x: x.rstrip("\n"), f)) + return data + + +def get_readme() -> str: + root_dir = Path(__file__).resolve().parent + readme_path = str(root_dir / "docs" / "doc_whl.md") + with open(readme_path, "r", encoding="utf-8") as f: + readme = f.read() + return readme + + +MODULE_NAME = "latex_to_image" + +obtainer = GetPyPiLatestVersion() +try: + latest_version = obtainer(MODULE_NAME) +except ValueError: + latest_version = "0.0.0" + +VERSION_NUM = obtainer.version_add_one(latest_version) + +if len(sys.argv) > 2: + match_str = " ".join(sys.argv[2:]) + matched_versions = obtainer.extract_version(match_str) + if matched_versions: + VERSION_NUM = matched_versions +sys.argv = sys.argv[:2] + +setuptools.setup( + name=MODULE_NAME, + version=VERSION_NUM, + platforms="Any", + description="Use LaTeX compilation tools to convert formulas in LaTeX format into corresponding images.", + long_description=get_readme(), + long_description_content_type="text/markdown", + author="SWHL", + author_email="liekkaskono@163.com", + url="https://github.com/SWHL/CutVideo", + license="MIT", + include_package_data=True, + install_requires=read_txt("requirements.txt"), + packages=[MODULE_NAME], + keywords=["moviepy,crop_video"], + classifiers=[ + "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + ], + python_requires=">=3.6,<3.12", + entry_points={ + "console_scripts": [ + f"latex_to_image={MODULE_NAME}.main:main", + ], + }, +) diff --git a/t.py b/t.py deleted file mode 100644 index 06b86ad..0000000 --- a/t.py +++ /dev/null @@ -1,148 +0,0 @@ -import os -import re -import shutil -import subprocess -import tempfile -from pathlib import Path - -import matplotlib as mpl -import matplotlib.pyplot as plt -from pdf2image import convert_from_path - - -def latex(tex, output_file, dpi=300, bgcolor="#FFFFFF", fgcolor="#000000"): - converter = LatexConverter( - tex, output_file, dpi=dpi, bgcolor=bgcolor, fgcolor=fgcolor - ) - converter.convert() - - -def latex_by_mpl(tex, output_file, dpi=300, bgcolor="white", fgcolor="black"): - tex = "$ " + tex + " $" - mpl.rcParams["text.usetex"] = True - mpl.rcParams["text.latex.preamble"] = r"\usepackage{{amsmath}}" - plt.rcParams.update({"mathtext.fontset": "cm"}) - fig = plt.figure(figsize=(10, 10), dpi=100) - - t = fig.text( - 0, 0, tex, horizontalalignment="left", verticalalignment="bottom", fontsize=30 - ) - - r = fig.canvas.get_renderer() - - bbox = t.get_tightbbox(r) - w, h = (bbox.width / r.dpi, bbox.height / r.dpi) - - fig = plt.figure(figsize=(1.1 * w, 1.1 * h), dpi=dpi) - t = fig.text( - 0, - 0, - tex, - fontsize=30, - verticalalignment="bottom", - horizontalalignment="left", - bbox={"facecolor": bgcolor, "edgecolor": bgcolor}, - color=fgcolor, - ) - - fig.savefig(output_file, transparent=False) - - -class LatexExpection(Exception): - pass - - -class CropException(Exception): - pass - - -class ConversionException(Exception): - pass - - -class LatexConverter: - def __init__(self, tex, output_file, bgcolor, fgcolor, dpi): - self.cwd = Path.cwd() - self.output = output_file - self.dpi = dpi - self.bgcolor = self._translate_color(bgcolor) - self.fgcolor = self._translate_color(fgcolor) - self.file_base, self.file_extension = os.path.splitext(output_file) - self.tex = tex - - def convert(self): - with tempfile.TemporaryDirectory() as tmp_dir: - os.chdir(tmp_dir) - self.write_latex_file() - self.tex_to_pdf() - self.pdf_to_image() - - def write_latex_file(self): - with open(self.file_base + ".tex", "w") as f: - f.write("\\documentclass{article}") - f.write("\\thispagestyle{empty}") - f.write("\\usepackage{amsmath,amssymb,amsfonts,amsthm}") - f.write("\\usepackage{xcolor}") - f.write("\\definecolor{fgcolor}{RGB}{%s, %s, %s}" % self.fgcolor) - f.write("\\definecolor{bgcolor}{RGB}{%s, %s, %s}" % self.bgcolor) - f.write("\\begin{document}") - f.write("\\color{fgcolor}") - f.write("\\pagecolor{bgcolor}") - f.write("\\begin{eqnarray*}") - f.write(self.tex) - f.write("\\end{eqnarray*}") - f.write("\\end{document}") - - def tex_to_pdf(self): - rc = subprocess.call( - ["pdflatex", "-halt-on-error", self.file_base + ".tex"], - stderr=subprocess.DEVNULL, - stdout=subprocess.DEVNULL, - ) - if rc != 0: - raise LatexExpection("Invalid Latex Expression") - - rc = subprocess.call( - ["pdfcrop", self.file_base + ".pdf"], - stderr=subprocess.DEVNULL, - stdout=subprocess.DEVNULL, - ) - if rc != 0: - raise CropException("Cannot crop pdf file") - - pdf = str(self.file_base) + ".pdf" - shutil.move(self.file_base + "-crop.pdf", Path.cwd() / pdf) - - def pdf_to_image(self): - pdf = str(self.file_base) + ".pdf" - try: - pages = convert_from_path(pdf, dpi=self.dpi) - pages[0].save( - self.file_base + self.file_extension, self.file_extension[1:].upper() - ) - shutil.move( - self.file_base + self.file_extension, - self.cwd / (str(self.file_base) + self.file_extension), - ) - shutil.move(pdf, self.cwd / (str(self.file_base) + ".pdf")) - except: - print( - 'Unable to convert image (is "poppler" installed?). Falling back on PDF instead.' - ) - shutil.move(pdf, self.cwd / (str(self.file_base) + ".pdf")) - - def _translate_color(self, color): - assert re.match("#[0-9A-Fa-f]{6}", color) - red, green, blue = int(color[1:3], 16), int(color[3:5], 16), int(color[5:], 16) - return red, green, blue - - -if __name__ == "__main__": - converter = LatexConverter( - r"\frac{\partial}{\partial z}", - "test.png", - dpi=100, - bgcolor="#ffffff", - fgcolor="#000000", - ) - converter.convert() diff --git a/tests/test_latex2img.py b/tests/test_latex2img.py deleted file mode 100644 index 23a0486..0000000 --- a/tests/test_latex2img.py +++ /dev/null @@ -1,23 +0,0 @@ -# -*- encoding: utf-8 -*- -# @Author: SWHL -# @Contact: liekkaskono@163.com -import sys -from pathlib import Path - -from PIL import Image - -cur_dir = Path(__file__).resolve().parent -root_dir = cur_dir.parent - -sys.path.append(str(root_dir)) - -from latex_to_image import GetRenderImg - -render = GetRenderImg() - - -def test_normal(): - formula = "x^2 + y ^2 = 1" - img_formula = render(formula) - - assert img_formula.shape == (34, 162) diff --git a/tests/test_render_two.py b/tests/test_render_two.py deleted file mode 100644 index 2806ff7..0000000 --- a/tests/test_render_two.py +++ /dev/null @@ -1,26 +0,0 @@ -# -*- encoding: utf-8 -*- -# @Author: SWHL -# @Contact: liekkaskono@163.com -import numpy as np -from PIL import Image, ImageChops - -from latex_to_image.main import LaTeX2Img - -render = LaTeX2Img() - -formula1 = r"=e^{-\lambda}\sum_{k=0}^{\infty}\frac{\left(-2\lambda\right)^{k}}{k!}" -formula2 = r"= e ^ { - \lambda } \sum _ { k = 0 } ^ { \infty } \frac { \left( - 2 \lambda \right) ^ { k } } { k ! }" - -img1, img2 = render(formula1, formula1) - -img1_np = Image.fromarray(img1) -img2_np = Image.fromarray(img2) - -diff = ImageChops.difference(img1_np, img2_np) - -diff.show() - -np.testing.assert_allclose(img1, img2, rtol=1e-3, atol=1e-5) -np.testing.assert_array_equal(img1, img2) - -print("ok") diff --git a/tests/test_template.py b/tests/test_template.py deleted file mode 100644 index b4d6577..0000000 --- a/tests/test_template.py +++ /dev/null @@ -1,5 +0,0 @@ -from string import Template - -s = Template("$who 在 $do") -ts = s.substitute(who="张三", do="赏花") -print(ts)