vue3解析數(shù)學(xué)公式圖片稻励,頁面展示并轉(zhuǎn)換為Word格式

有這樣一個需求:通過數(shù)學(xué)公式圖片望抽,識別書公式展示在頁面上煤篙,并支持下載word舰蟆,展示word版本的數(shù)學(xué)公式趣惠,可供復(fù)制使用。
之前是通過Pix2Text進行數(shù)學(xué)公式的識別身害,然后復(fù)制識別的內(nèi)容味悄,通過 LaTeX公式編輯器進行下載對應(yīng)的數(shù)學(xué)公式的Word 文檔。但是第一個網(wǎng)站Pix2Text不太穩(wěn)定塌鸯,經(jīng)常性的不可用侍瑟,所以想自己實現(xiàn)這2個功能。

一丙猬、圖片OCR解析公式

首先參考第一個的Pix2Textgithub
后端進行部署了相關(guān)的服務(wù)涨颜,可以進行OCR解析圖片,然后前端進行調(diào)用對應(yīng)的接口
這塊主要有一個是粘貼圖片進行上傳茧球,并顯示在頁面上

1庭瑰、首先需要監(jiān)聽全局paste事件

onMounted(() => {
  window.addEventListener('paste', handlePaste);
});
onUnmounted(() => {
  window.removeEventListener('paste', handlePaste);
});

2、然后再對應(yīng)的監(jiān)聽方法中就可以獲取到file文件

/** 全局頁面監(jiān)聽粘貼內(nèi)容 */
function handlePaste(event) {
  // console.log('全局頁面監(jiān)聽粘貼內(nèi)容000');
  const items = (event.clipboardData || window.clipboardData).items;
  let file = null;

  if (!items || items.length === 0) {
    console.log('當(dāng)前瀏覽器不支持本地');
    return;
  }
  // 搜索剪切板items
  for (let i = 0; i < items.length; i++) {
    if (items[i].type.indexOf('image') !== -1) {
      file = items[i].getAsFile();
      break;
    }
  }
  if (!file) {
    console.log('粘貼內(nèi)容非圖片');
    return;
  }
  // 此時file就是我們的剪切板中的圖片對象
  // console.log('file==', file);
  showImageToPage(file);
  uploadImage(file);
}

3揪垄、然后顯示這個圖片在頁面上捡鱼,div設(shè)置一個id

   <div id="preview" class="div_image">
            <span>將圖片按Ctrl+V粘貼至此頁面</span>
   </div>

4伟墙、把剛才獲取到的file文件渲染在div上

// 上傳的圖片顯示到頁面右側(cè)
function showImageToPage(file) {
  // 如果需要預(yù)覽,可以執(zhí)行下面代碼
  const reader = new FileReader();
  reader.onload = event => {
    preview.innerHTML = `<img src="${event.target.result}" style=' max-height: 200px;
    max-width: 100%;
    min-width: 200px;
    object-fit: contain;'>`;
  };
  // 把粘貼的圖片顯示在頁面上
  reader.readAsDataURL(file);
}

5、然后調(diào)用后臺的上傳圖片,OCR解析接口

// 上傳圖片到服務(wù)端進行OCR識別
function uploadImage(file) {
  let param = new FormData(); //創(chuàng)建form對象
  param.append('image', file); //為創(chuàng)建的form對象增加上傳的文件
  // param.append('session_id', ''); //如果需要上傳其他字段,在這里增加
  param.append('use_analyzer', 'true');
  param.append('resized_shape', '600');
  //修改請求頭
  let config = { headers: { 'Content-Type': 'multipart/form-data' } };
  // console.log('url ==', pix2textUrl);

  proxy.$modal.loading('正在解析念脯,請稍候庐橙!');
  // 上傳圖片
  axios.post(pix2textUrl, param, config).then(res => {
    // console.log('res====', res);
    proxy.$modal.closeLoading();

    if (!res.data || res.data.status_code != 200) {
      proxy.$modal.msgError('未成功識別,請稍后再試');
      return;
    }
    // console.log('res====', res);

    let textList = res.data.results;
    if (!textList || textList.length == 0) {
      proxy.$modal.msgError('未成功識別,請稍后再試');
      return;
    }

    let textStr = '';
    textList.forEach(element => {
      textStr += element.text;
      if (element.type == 'text') {
        textStr += '\n';
      }
    });
    // console.log('textStr====', textStr);

    textWords.value = textStr.replaceAll('$$', '');
    mathText.value = textStr;

    laTexToMath();
  });
}

二、頁面展示數(shù)學(xué)公式

接口會返回一些解析出來的文本和LaTeX 數(shù)學(xué)公式
但是接口返回的LaTeX 公式,是一些$$符號的一些標識测萎,具體符號參考見 LaTeX 公式篇 ,無法辨認出具體的公式,所以需要轉(zhuǎn)化顯示為可以識別的公式。

所以我們需要借助于 MathJax

mathjax是一個用于latex耳鸯、mathml和ascimath表示法的開源javascript顯示引擎煌集,可在所有現(xiàn)代瀏覽器中工作纲缓,并內(nèi)置了對諸如屏幕閱讀器等輔助技術(shù)的支持。

1、首先需要在 index.html中引入

  <script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>

2雷厂、在utils中新建MathJax.js

let isMathjaxConfig = false // ?于標識是否配置
const initMathjaxConfig = () => {
    if (!window.MathJax) {
        return
    }
    window.MathJax = {
        tex: {
            inlineMath: [
                ['$', '$'],
                ['\\(', '\\)']
            ], // ?內(nèi)公式選擇符
            displayMath: [
                ['$$', '$$'],
                ['\\[', '\\]']
            ] // 段內(nèi)公式選擇符
        },
        chtml: {
            scale: 1,//縮放比例
        },
        options: {
            skipHtmlTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code',
                'a'], // 避開某些標簽
            ignoreHtmlClass: 'tex2jax_ignore',
            processHtmlClass: 'tex2jax_process'
        }
    }
    isMathjaxConfig = true // 配置完成,改為true
}
const TypeSet = async function (elementId) {
    if (!window.MathJax) {
        return
    }
    window.MathJax.startup.promise = window.MathJax.startup.promise
        .then(() => {
            return window.MathJax.typesetPromise()
        })
        .catch((err) => console.log('Typeset failed: ' + err.message))
    return window.MathJax.startup.promise
}
export default {
    isMathjaxConfig,
    initMathjaxConfig,
    TypeSet
}

3烟零、在main.js中全局引入

import MathJax from './utils/MathJax'
app.config.globalProperties.MathJax = MathJax

4凉逛、在剛才上傳圖片接口书斜,之后調(diào)用這個接口,傳入接口返回的latex文本即可

 <!-- 展示數(shù)學(xué)公式 -->
<div class="input_box math_box" style="margin-left: 10px" id="math">
    <p style="font-size: 14px; white-space: pre-line">{{ mathText }}</p>
</div>
// 將Latex公式文本渲染為數(shù)學(xué)公式顯示在右側(cè)虛線框中
function laTexToMath() {
  // MathJax3.0版本
  if (proxy.MathJax.isMathjaxConfig) {
    // 判斷是否初始配置,若?則配置痪欲。
    proxy.MathJax.initMathjaxConfig();
  }
  proxy.MathJax.TypeSet();
}

效果如下圖所示


WX20230612-173535@2x.png

三、轉(zhuǎn)化下載Word格式的公式

上面的公式已經(jīng)可以完整的展示在頁面上知举,但是我們不是通過復(fù)制粘貼出來遮糖,所以需要把這個轉(zhuǎn)換為Word版本的,可以進行復(fù)制粘貼的格式惹苗。
參考 LaTeX公式編輯器洽瞬,通過這個里面的導(dǎo)出Word晦闰,有一個接口可以進行實現(xiàn),接口地址為https://reverse.latexlive.com:5002/api/Common/MathMlToWordBlod鄙皇,但是通過抓包發(fā)現(xiàn)這個接口的入?yún)⒏袷綖?MathML格式洲愤,入下圖所示

MathML格式

上面類似Html的格式,就是MathML格式,
所以我們需要將之前接口返回的laTex轉(zhuǎn)MathML格式严嗜,然后再調(diào)研下載Word的接口,
1、laTex轉(zhuǎn)MathML格式

// 需要先把laTex轉(zhuǎn)MathML格式癌椿,然后通過MathML格式進行下載Word
function exportWord() {
  // console.log('laTex轉(zhuǎn)MathML格式');
  if (!textWords.value) {
    proxy.$modal.msgError('請先粘貼圖片識別');
    return;
  }
  // 重置
  window.MathJax.texReset();
  // laTex轉(zhuǎn)MathML格式
  window.MathJax.tex2mmlPromise(textWords.value)
    .then(function (mml) {
      // 轉(zhuǎn)換結(jié)果
      // console.log('轉(zhuǎn)換結(jié)果mml=====', mml);
      downloadWordFile(mml);
    })
    .catch(function (err) {
      // 發(fā)生錯誤時
    })
    .then(function () {
      // 完成時
    });
}

2、下載Word文件

/ /下載Word文件-通過MathML格式進行下載Word
function downloadWordFile(mathml) {
  // console.log('下載word文件00');
  let param = {
    mathml: mathml
  };
  const config = {
    responseType: 'blob', //這個一定要設(shè)置菱阵,否則會出現(xiàn)文件下載后打不開的情況,
    'Content-Type': 'application/json'
  };
  axios.post(mathMlToWordBlodUrl, param, config).then(res => {
    // console.log('res====', res);
    // console.log('下載word文件11');
    let blob = new Blob([res.data], {
      //設(shè)置數(shù)據(jù)源
      type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' //設(shè)置文件格式
    });

    let objectUrl = URL.createObjectURL(blob); //創(chuàng)建下載的鏈接
    let a = document.createElement('a');
    a.href = objectUrl;

    let time = parseInt(new Date().getTime() / 1000) + '';
    a.download = `jwwh${time}`; //設(shè)置文件名
    //下面這個寫法兼容火狐
    a.dispatchEvent(
      new MouseEvent('click', { bubbles: true, cancelable: true, view: window })
    );
    window.URL.revokeObjectURL(blob); //釋放bolb對象
  });
}
Word格式展示

參考文檔:
vue中使用MathJax 3.0簡單步驟
mathjax
基于vue渲染Latex數(shù)學(xué)公式(simplemde-editor)
LatexToMathML
uniapp使用mathjax解析公式

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蛛倦,一起剝皮案震驚了整個濱河市茸塞,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌疟赊,老刑警劉巖驮审,帶你破解...
    沈念sama閱讀 216,692評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異吉执,居然都是意外死亡疯淫,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,482評論 3 392
  • 文/潘曉璐 我一進店門鼠证,熙熙樓的掌柜王于貴愁眉苦臉地迎上來峡竣,“玉大人,你說我怎么就攤上這事量九∈赎” “怎么了?”我有些...
    開封第一講書人閱讀 162,995評論 0 353
  • 文/不壞的土叔 我叫張陵荠列,是天一觀的道長类浪。 經(jīng)常有香客問我,道長肌似,這世上最難降的妖魔是什么费就? 我笑而不...
    開封第一講書人閱讀 58,223評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮川队,結(jié)果婚禮上力细,老公的妹妹穿的比我還像新娘。我一直安慰自己固额,他們只是感情好眠蚂,可當(dāng)我...
    茶點故事閱讀 67,245評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著斗躏,像睡著了一般逝慧。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,208評論 1 299
  • 那天笛臣,我揣著相機與錄音云稚,去河邊找鬼。 笑死沈堡,一個胖子當(dāng)著我的面吹牛静陈,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播踱蛀,決...
    沈念sama閱讀 40,091評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼窿给,長吁一口氣:“原來是場噩夢啊……” “哼贵白!你這毒婦竟也來了率拒?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,929評論 0 274
  • 序言:老撾萬榮一對情侶失蹤禁荒,失蹤者是張志新(化名)和其女友劉穎猬膨,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體呛伴,經(jīng)...
    沈念sama閱讀 45,346評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡勃痴,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,570評論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了热康。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片沛申。...
    茶點故事閱讀 39,739評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖姐军,靈堂內(nèi)的尸體忽然破棺而出铁材,到底是詐尸還是另有隱情,我是刑警寧澤奕锌,帶...
    沈念sama閱讀 35,437評論 5 344
  • 正文 年R本政府宣布著觉,位于F島的核電站,受9級特大地震影響惊暴,放射性物質(zhì)發(fā)生泄漏饼丘。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,037評論 3 326
  • 文/蒙蒙 一辽话、第九天 我趴在偏房一處隱蔽的房頂上張望肄鸽。 院中可真熱鬧,春花似錦油啤、人聲如沸典徘。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,677評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽烂斋。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間汛骂,已是汗流浹背罕模。 一陣腳步聲響...
    開封第一講書人閱讀 32,833評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留帘瞭,地道東北人淑掌。 一個月前我還...
    沈念sama閱讀 47,760評論 2 369
  • 正文 我出身青樓,卻偏偏與公主長得像蝶念,于是被迫代替她去往敵國和親抛腕。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,647評論 2 354