ScreenCapture icon indicating copy to clipboard operation
ScreenCapture copied to clipboard

增加渲染 LaTeX 公式标注图像的功能

Open IuvenisSapiens opened this issue 7 months ago • 6 comments

我希望该工具能够实现一个新功能,即渲染 LaTeX 公式标注图像的功能。这样,用户在截图时可以方便地添加复杂的数学公式或科学符号,这对于需要在文档中标注数学公式的用户群体来说将会是一个非常有用的特性。

具体需求如下:

  1. 用户可以输入 LaTeX 公式。
  2. 在截图区域中渲染 LaTeX 公式为图像。
  3. 提供公式编辑的界面,方便调整位置和样式。
  4. 支持将渲染后的公式图像与其他截图元素一起保存或复制到剪贴板。

如果这个功能可以通过参数或界面进行配置,将更加理想。在集成时,希望能够保持现有的命令行参数功能,并且支持新的参数来启用和配置 LaTeX 公式渲染功能。

非常期待 ScreenCapture 能够在未来版本中支持这项功能,让它成为一个更加全面的屏幕截图工具。

IuvenisSapiens avatar May 04 '25 10:05 IuvenisSapiens

这个需求会不会有点小众?

xland avatar May 04 '25 10:05 xland

这个需求会不会有点小众?

这个需求对于需要在截图中标注数学公式或科学符号的用户群体来说是非常有价值的,尤其是在学术、教育和科研领域。虽然可能不是所有用户都会频繁使用,但对于特定的用户群体,如研究人员、教师和学生,这将显著提高他们的工作效率和文档的专业性。因此,这个功能可以被视为面向特定专业需求的小众功能,但对目标用户来说,它是非常重要的。

IuvenisSapiens avatar May 04 '25 11:05 IuvenisSapiens

有点太小众了,这也不是截图软件该干的事情吧,感觉你需要去找专业的工具……

Mikachu2333 avatar May 04 '25 16:05 Mikachu2333

给,你要的功能。示例图如下图所示,公式是随便找的,复杂度还可以。不建议让软件做本不属于他的工作……

Image

html文件源码如下:

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>LaTeX 渲染预览导出</title>
    <script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js"></script>
    <style>
        #latex-input {
            width: 100%;
            font-size: 12pt;
            min-height: 3em;
            resize: vertical;
            box-sizing: border-box;
        }

        #rendered-math {
            margin-top: 20px;
            min-height: 40px;
        }
    </style>
</head>

<body>
    <h2>输入 LaTeX 公式:</h2>
    <textarea id="latex-input" rows="2" placeholder="例如:x = \frac{-b \pm \sqrt{b^2-4ac}}{2a}"
        oninput="autoResize(this)"></textarea>
    <div style="margin: 16px 0;">
        <button onclick="renderLatex()">渲染公式</button>
        <button id="export-svg" onclick="exportSVG()" disabled>导出SVG</button>
        <button id="export-png" onclick="exportPNG()" disabled>导出PNG</button>
    </div>
    <div id="rendered-math"></div>
    <script>
        function renderLatex() {
            const input = document.getElementById('latex-input').value;
            const output = document.getElementById('rendered-math');
            output.innerHTML = '$$' + input + '$$';
            if (window.MathJax) {
                MathJax.typesetPromise([output]).then(() => {
                    // 渲染完成后启用导出按钮
                    document.getElementById('export-svg').disabled = false;
                    document.getElementById('export-png').disabled = false;
                });
            }
        }

        function exportSVG() {
            const svg = document.querySelector('#rendered-math svg');
            if (!svg) {
                alert('请先渲染公式');
                return;
            }
            const serializer = new XMLSerializer();
            let source = serializer.serializeToString(svg);
            // 添加命名空间
            if (!source.match(/^<svg[^>]+xmlns="http:\/\/www\.w3\.org\/2000\/svg"/)) {
                source = source.replace(/^<svg/, '<svg xmlns="http://www.w3.org/2000/svg"');
            }
            // 下载
            const url = "data:image/svg+xml;charset=utf-8," + encodeURIComponent(source);
            const a = document.createElement('a');
            a.href = url;
            a.download = 'formula.svg';
            document.body.appendChild(a);
            a.click();
            document.body.removeChild(a);
        }

        function exportPNG() {
            const svg = document.querySelector('#rendered-math svg');
            if (!svg) {
                alert('请先渲染公式');
                return;
            }
            const serializer = new XMLSerializer();
            let source = serializer.serializeToString(svg);
            // 添加命名空间
            if (!source.match(/^<svg[^>]+xmlns="http:\/\/www\.w3\.org\/2000\/svg"/)) {
                source = source.replace(/^<svg/, '<svg xmlns="http://www.w3.org/2000/svg"');
            }
            const img = new Image();
            const svg64 = btoa(unescape(encodeURIComponent(source)));
            const image64 = 'data:image/svg+xml;base64,' + svg64;
            img.onload = function () {
                // 计算缩放比例以达到300dpi(假设屏幕为96dpi)
                const scale = 300 / 96;
                const canvas = document.createElement('canvas');
                canvas.width = img.width * scale;
                canvas.height = img.height * scale;
                const ctx = canvas.getContext('2d');
                ctx.setTransform(scale, 0, 0, scale, 0, 0);
                ctx.drawImage(img, 0, 0);
                canvas.toBlob(function (blob) {
                    const a = document.createElement('a');
                    a.href = URL.createObjectURL(blob);
                    a.download = 'formula.png';
                    document.body.appendChild(a);
                    a.click();
                    document.body.removeChild(a);
                }, 'image/png');
            };
            img.src = image64;
        }

        function autoResize(textarea) {
            textarea.style.height = 'auto';
            textarea.style.height = textarea.scrollHeight + 'px';
        }
    </script>
</body>

</html>

压缩后可以纯本地运行的html见附件

latex.zip


25.9.13更新,换用了mathjax4.0,彻底全部调用本地资源,之前似乎还需要请求字体来着,现在也都本地化了,支持深色模式和双语切换

Latex渲染.zip

Mikachu2333 avatar May 04 '25 17:05 Mikachu2333

给,你要的功能。示例图如下图所示,公式是随便找的,复杂度还可以。不建议让软件做本不属于他的工作……

Image

html文件源码如下:

压缩后可以纯本地运行的html见附件

latex.zip

该HTML示例代码展示了一种渲染LaTeX公式的常见方法,但如何将此功能集成到ScreenCapture工具中,以及如何在截图界面上方便地嵌入和调整这些公式?

IuvenisSapiens avatar May 04 '25 22:05 IuvenisSapiens

该HTML示例代码展示了一种渲染LaTeX公式的常见方法,但如何将此功能集成到ScreenCapture工具中,以及如何在截图界面上方便地嵌入和调整这些公式?

用命令行pin了再编辑就可以了

反正我的意见就是,渲染latex公式绝对不是截图软件的本职工作……

Mikachu2333 avatar May 05 '25 02:05 Mikachu2333