Jelajahi Sumber

[web_demo] 代码组件化,方便组件复用,点击图片显示区域或者将文件拖拽至该区域实现文件上传,magic_color已适配

yanxin 1 tahun lalu
induk
melakukan
36c9f0697e

+ 0 - 1
src/App.vue

@@ -1,5 +1,4 @@
 <script setup lang="ts">
-import HelloWorld from './components/HelloWorld.vue'
 import MainView from "@/MainView.vue";
 </script>
 

+ 73 - 0
src/components/FileUpload.vue

@@ -0,0 +1,73 @@
+<template>
+    <div class="file-container">
+        <el-upload drag :before-upload="beforeUpload">
+            <div>
+                xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+                xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+                xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+                xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+                xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+                xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+                xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+                xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+                xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+                xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+                xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+                xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+                xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+                xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+                xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+                xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+                xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+                xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+                xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+                xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+                xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+                xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+                xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+                xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+                xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+                xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+                xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+                xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+                xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+            </div>
+        </el-upload>
+    </div>
+</template>
+
+<script setup lang="ts">
+import { useCanvasImgStore } from '../store/CanvasImg';
+import { usePdfProperty } from '../store/PdfProperty';
+import { storeToRefs } from 'pinia'
+
+const c_img = useCanvasImgStore();
+const { show_image, input_file } = storeToRefs(c_img);
+const pdf_property = usePdfProperty();
+const { is_pdf, pdf_source } = storeToRefs(pdf_property);
+
+const beforeUpload = (file: File): boolean | Promise<boolean> => {
+    const post_ = file.name.substring(file.name.lastIndexOf("."), file.name.length).toLowerCase();
+    if (post_ == ".pdf") {
+        is_pdf.value = true;
+        pdf_source.value = URL.createObjectURL(file);
+    } else
+        if (post_ == ".jpg" || post_ == ".png" || post_ == ".bmp" || post_ == ".jpeg") {
+            is_pdf.value = false
+            show_image.value.src = URL.createObjectURL(file);
+            input_file.value = file;
+        } else {
+            alert('不支持的文件格式!')
+        }
+    return true
+}
+</script>
+
+<style scoped>
+.file-container {
+    display: flex;
+    width: auto;
+    height: auto;
+    opacity: 0;
+}
+</style>

+ 0 - 38
src/components/HelloWorld.vue

@@ -1,38 +0,0 @@
-<script setup lang="ts">
-import { ref } from 'vue'
-
-defineProps<{ msg: string }>()
-
-const count = ref(0)
-</script>
-
-<template>
-  <h1>{{ msg }}</h1>
-
-  <div class="card">
-    <button type="button" @click="count++">count is {{ count }}</button>
-    <p>
-      Edit
-      <code>components/HelloWorld.vue</code> to test HMR
-    </p>
-  </div>
-
-  <p>
-    Check out
-    <a href="https://vuejs.org/guide/quick-start.html#local" target="_blank"
-      >create-vue</a
-    >, the official Vue + Vite starter
-  </p>
-  <p>
-    Install
-    <a href="https://github.com/johnsoncodehk/volar" target="_blank">Volar</a>
-    in your IDE for a better DX
-  </p>
-  <p class="read-the-docs">Click on the Vite and Vue logos to learn more</p>
-</template>
-
-<style scoped>
-.read-the-docs {
-  color: #888;
-}
-</style>

+ 139 - 160
src/components/PdfPreview.vue

@@ -1,189 +1,168 @@
-<!-- <template>
-  <div class="pdf-preview">
-        <div class="pdf-wrap">
-          <vue-pdf-embed :source="state.source" :style="scale" class="vue-pdf-embed" :page="state.pageNum" />
-        </div>
-        <div class="page-tool">
-          <div class="page-tool-item" @click="prePage">上一页</div>
-          <div class="page-tool-item" @click="nextPage">下一页</div>
-          <div class="page-tool-item">{{ state.pageNum }}/{{ state.numPages }}</div>
-          <div class="page-tool-item" @click="pageZoomOut">放大</div>
-          <div class="page-tool-item" @click="pageZoomIn">缩小</div>
-          <el-input type="number" v-model="pdf_page"></el-input>
-          <el-button type="primary" @click="SetPdfPage" plain>页面跳转</el-button>
-        </div>
-      </div>
+<template>
+    <div v-show="is_pdf">
+        <el-row>
+            <el-button-group>
+                <el-button type="primary" :icon="ArrowLeft" @click="prePage">上一页</el-button>
+                <el-button type="primary" @click="nextPage">
+                    下一页<el-icon class="el-icon--right">
+                        <ArrowRight />
+                    </el-icon>
+                </el-button>
+            </el-button-group>
+            <div class="page-tool-item">{{ state.pageNum }}/{{ state.numPages }}</div>
+            <el-container>
+                <el-input type="number" v-model="pdf_page"></el-input>
+                <el-button type="primary" @click="SetPdfPage" plain>页面跳转</el-button>
+            </el-container>
+        </el-row>
+    </div>
 </template>
 
-<script lang="ts" setup>
-import { reactive, ref, toRefs, computed } from 'vue'
-import { onMounted } from "vue";
-import VuePdfEmbed from "vue-pdf-embed";
-import { createLoadingTask } from "vue3-pdfjs/esm"; // 获得总页数
+<script setup lang="ts">
+import { reactive, ref, onMounted, watchEffect } from 'vue'
+import { createLoadingTask } from "vue3-pdfjs/esm";
+import { useCanvasImgStore } from '../store/CanvasImg';
+import { usePdfProperty } from '../store/PdfProperty';
+import { storeToRefs } from 'pinia'
 
-let loadingTask: any;
+import {
+    ArrowLeft,
+    ArrowRight
+} from '@element-plus/icons-vue'
 
-const pdf_page = ref(1);
+const c_img = useCanvasImgStore();
+const { show_image, show_canvas, hide_canvas, input_file } = storeToRefs(c_img);
+const pdf_property = usePdfProperty();
+const { is_pdf, pdf_source } = storeToRefs(pdf_property);
 
 const state = reactive({
-  source: "", //预览pdf文件地址
-  pageNum: 1, //当前页面
-  scale: 1, // 缩放比例
-  numPages: 0, // 总页数
+    source: "", //预览pdf文件地址
+    pageNum: 1, //当前页面
+    numPages: 0, // 总页数
 });
 
-const scale = computed(() => `transform:scale(${state.scale})`)
-
-function getPdfImage(index: number) {
-  // console.log(index, state.pageNum)
-  loadingTask.promise.then((pdf: any) => {
-    state.numPages = pdf.numPages;
-    pdf.getPage(index).then((page: any) => {
-      const viewport = page.getViewport({ scale: 1 })
-      canvas.value.height = viewport.height;
-      canvas.value.width = viewport.width;
-      // 画布的dom大小, 设置移动端,宽度设置铺满整个屏幕
-      // const clientWidth = document.body.clientWidth;
-      const destWidth = 398;
-      canvas.value.style.width = destWidth + 'px';
-      // 根据pdf每页的宽高比例设置canvas的高度
-      canvas.value.style.height = destWidth * (viewport.height / viewport.width) + 'px';
-      const ctx = canvas.value.getContext('2d');
-      page.render({
-        canvasContext: ctx,
-        viewport,
-      });
-      canvas.value.toBlob(function (blob) {
-        pdf_img.value = dataURLtoBlob(canvas.value.toDataURL())
-        // console.log(pdf_img.value);
-        console.log(canvas.value.toDataURL(), state.pageNum)
-      });
-    })
-  });
-}
+const pdf_page = ref(1);
+const pdf_img: any = ref("")
+let loadingTask: any;
 
-function SetPdfPage() {
-  if (pdf_page.value >= 1 && pdf_page.value <= state.numPages) {
-    console.log(pdf_page.value)
-    state.pageNum = Number(pdf_page.value);
-    getPdfImage(state.pageNum);
-  } else {
-    console.log(pdf_page.value)
-    alert('输入的pdf页面无效!')
-  }
-}
+onMounted(async () => {
+    show_image.value = document.getElementById("show_img") as HTMLImageElement;
+    show_canvas.value = document.getElementById("show_canvas") as HTMLCanvasElement;
+    hide_canvas.value = document.getElementById("hide_canvas") as HTMLCanvasElement;
+});
 
 function prePage() {
-  if (state.pageNum > 1) {
-    state.pageNum -= 1;
-    getPdfImage(state.pageNum);
-  }
+    if (state.pageNum > 1) {
+        state.pageNum -= 1;
+        getPdfImage(state.pageNum);
+    }
 }
 
 function nextPage() {
-  if (state.pageNum < state.numPages) {
-    state.pageNum += 1;
-    getPdfImage(state.pageNum);
-  }
-}
-function pageZoomOut() {
-  if (state.scale < 2) {
-    state.scale += 0.1;
-  }
-}
-function pageZoomIn() {
-  if (state.scale > 1) {
-    state.scale -= 0.1;
-  }
-}
-
-function dataURLtoBlob(dataURL: any) {
-  var arr = dataURL.split(','),
-      mime = arr[0].match(/:(.*?);/)[1],
-      bstr = atob(arr[1]),
-      n = bstr.length,
-      u8arr = new Uint8Array(n);
-  while (n--) {
-    u8arr[n] = bstr.charCodeAt(n);
-  }
-  return new Blob([u8arr], {type:mime});
+    if (state.pageNum < state.numPages) {
+        state.pageNum += 1;
+        getPdfImage(state.pageNum);
+    }
 }
 
-async function convertCanvasToFile(canvas: HTMLCanvasElement, fileName: any) {
-  // 将 Canvas 转为 Blob 对象
-  const blob = await new Promise(resolve => canvas.toBlob(blob => {
-            resolve(blob);
-        }, pdf_img.value.type, 1.0));
-  // 手动构造 File 对象
-  let file = null;
-  try {
-    file = new File([pdf_img.value], fileName, { type: pdf_img.value.type });
-  } catch (e) {
-    // Safari 浏览器不支持直接通过 new File() 创建文件对象,需要手动构造
-    const rawFile = blobToFile(blob, fileName);
-    file = Object.assign(rawFile, { lastModifiedDate: new Date(), name: fileName });
-  }
-  return file;
+function SetPdfPage() {
+    if (pdf_page.value >= 1 && pdf_page.value <= state.numPages) {
+        state.pageNum = Number(pdf_page.value);
+        getPdfImage(state.pageNum);
+    } else {
+        alert('输入的pdf页面无效!')
+    }
 }
 
-</script>
-
-<style scoped>
-.pdf-preview {
-  position: relative;
-  height: 100vh;
-  padding: 20px 0;
-  box-sizing: border-box;
-  background: rgb(66, 66, 66);
+function blobToFile(blob: any, fileName: any) {
+    blob.lastModifiedDate = new Date();
+    blob.name = fileName;
+    return blob;
 }
 
-.vue-pdf-embed {
-  text-align: center;
-  width: 515px;
-  border: 1px solid #e5e5e5;
-  margin: 0 auto;
-  box-sizing: border-box;
+async function convertCanvasToFile(canvas: HTMLCanvasElement, fileName: any) {
+    // 将 Canvas 转为 Blob 对象
+    const blob = await new Promise(resolve => canvas.toBlob(blob => {
+        resolve(blob);
+    }, pdf_img.value.type, 1.0));
+    // 手动构造 File 对象
+    let file = null;
+    try {
+        file = new File([pdf_img.value], fileName, { type: pdf_img.value.type });
+    } catch (e) {
+        // Safari 浏览器不支持直接通过 new File() 创建文件对象,需要手动构造
+        const rawFile = blobToFile(blob, fileName);
+        file = Object.assign(rawFile, { lastModifiedDate: new Date(), name: fileName });
+    }
+    return file;
 }
 
-.pdf-preview {
-  position: relative;
-  height: 100vh;
-  padding: 20px 0;
-  box-sizing: border-box;
-  background-color: e9e9e9;
+function getPdfImage(index: number) {
+    loadingTask.promise.then((pdf: any) => {
+        state.numPages = pdf.numPages;
+        // console.log(state)
+        pdf.getPage(index).then((page: any) => {
+            const viewport = page.getViewport({ scale: 2.0 })
+            hide_canvas.value.height = viewport.height;
+            hide_canvas.value.width = viewport.width;
+            show_canvas.value.height = viewport.height;
+            show_canvas.value.width = viewport.width;
+            const destWidth = 398;
+            hide_canvas.value.style.width = destWidth + 'px';
+
+            hide_canvas.value.style.height = destWidth * (viewport.height / viewport.width) + 'px';
+            show_canvas.value.style.width = destWidth + 'px';
+
+            show_canvas.value.style.height = destWidth * (viewport.height / viewport.width) + 'px';
+            const ctx = hide_canvas.value.getContext('2d');
+            page.render({
+                canvasContext: ctx,
+                viewport,
+            });
+            hide_canvas.value.toBlob(function (blob) {
+                pdf_img.value = dataURLtoBlob(hide_canvas.value.toDataURL('images/png', 1.0))
+                show_image.value.src = hide_canvas.value.toDataURL('images/png', 1.0);
+                show_image.value.onload = () => {
+                    show_canvas.value.width = show_image.value.width;
+                    show_canvas.value.height = show_image.value.height;
+                    convertCanvasToFile(hide_canvas.value, "pdf.png").then(result => {
+                        if (is_pdf.value == true) {
+                            input_file.value = result;
+                        }
+                    });
+                }
+            });
+        })
+    });
 }
 
-.pdf-wrap {
-  overflow-y: auto;
+function dataURLtoBlob(dataURL: any) {
+    var arr = dataURL.split(','),
+        mime = arr[0].match(/:(.*?);/)[1],
+        bstr = atob(arr[1]),
+        n = bstr.length,
+        u8arr = new Uint8Array(n);
+    while (n--) {
+        u8arr[n] = bstr.charCodeAt(n);
+    }
+    return new Blob([u8arr], { type: mime });
 }
 
-.vue-pdf-embed {
-  text-align: center;
-  width: 515px;
-  border: 1px solid #e5e5e5;
-  margin: 0 auto;
-  box-sizing: border-box;
+function initPdf(source: any) {
+    state.pageNum = 1;
+    state.source = source;
+    loadingTask = createLoadingTask(state.source);
+    getPdfImage(state.pageNum);
 }
 
-.page-tool {
-  position: absolute;
-  /* bottom: 35px; */
-  /* padding-left: 15px; */
-  /* padding-right: 15px; */
-  display: flex;
-  align-items: center;
-  background: rgb(66, 66, 66);
-  color: white;
-  border-radius: 19px;
-  z-index: 100;
-  cursor: pointer;
-  margin-left: 50%;
-  transform: translateX(-50%);
-}
+let pdf_file = ref("")
 
-.page-tool-item {
-  padding: 8px 15px;
-  padding-left: 10px;
-  cursor: pointer;
-}
-</style> -->
+watchEffect(() => {
+    // console.log('pdf-test')
+    if (pdf_file.value != pdf_source.value) {
+        pdf_file.value = pdf_source.value;
+        state.source = pdf_source.value; // 更新 source 变量
+        initPdf(pdf_source.value); // 调用 initPdf 方法重新加载 PDF 文件
+    }
+});
+</script>

+ 45 - 0
src/components/ShowImage.vue

@@ -0,0 +1,45 @@
+<template>
+    <div class="image-container">
+        <img id="show_img" class="image" v-if="showSrcImage">
+        <img id="res_img" class="image" v-else>
+        <canvas id="show_canvas" style="display: none;"></canvas>
+        <canvas id="hide_canvas" style="display: none;"></canvas>
+    </div>
+</template>
+
+<script lang="ts" setup>
+
+import { ref, onMounted } from 'vue'
+import { useCanvasImgStore } from '../store/CanvasImg';
+import { storeToRefs } from 'pinia'
+
+const c_img = useCanvasImgStore();
+const { show_image, res_image, show_canvas, hide_canvas } = storeToRefs(c_img);
+
+onMounted(async () => {
+    show_image.value = document.getElementById("show_img") as HTMLImageElement;
+    res_image.value = document.getElementById("res_img") as HTMLImageElement;
+    show_canvas.value = document.getElementById("show_canvas") as HTMLCanvasElement;
+    hide_canvas.value = document.getElementById("hide_canvas") as HTMLCanvasElement;
+});
+
+defineProps<{
+  showSrcImage?: boolean
+}>()
+</script>
+
+<style>
+.image-container {
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    width: auto;
+    height: 700px;
+    background-color: gainsboro;
+}
+
+.image {
+    max-width: 100%;
+    max-height: 100%;
+}
+</style>

File diff ditekan karena terlalu besar
+ 1 - 1
src/dist/assets/index-9585a3a9.css


File diff ditekan karena terlalu besar
+ 107 - 107
src/dist/assets/index-42269111.js


+ 2 - 2
src/dist/index.html

@@ -4,8 +4,8 @@
     <meta charset="UTF-8" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
     <title>DocumentAI Web Demo</title>
-    <script type="module" crossorigin src="./assets/index-42269111.js"></script>
-    <link rel="stylesheet" href="./assets/index-9585a3a9.css">
+    <script type="module" crossorigin src="./assets/index-f2214fae.js"></script>
+    <link rel="stylesheet" href="./assets/index-02a8aea1.css">
   </head>
   <body>
     <div id="app"></div>

+ 37 - 227
src/pages/main/views/ImageProcess/magicColor.vue

@@ -7,268 +7,84 @@
       <el-row style="color: gray; font-size: small;">
         <p>V1 主要针对文档图片,去阴影效果较好</p>
       </el-row>
-      <el-row style="color: gray; font-size: small;">
-        <h4>支持jpg, png, bmp, pdf等文件格式</h4>
-      </el-row>
-      <div class="common-layout">
-        <el-upload class="upload-demo" drag :before-upload="beforeUpload" multiple>
-          <el-icon class="el-icon--upload"><upload-filled /></el-icon>
-          <div class="el-upload__text">
-            Drop file here or <em>click to upload</em>
-          </div>
-          <template #tip>
-            <div class="el-upload__tip">
-              {{ fileName }}
-            </div>
-          </template>
-        </el-upload>
-        <el-button type="primary" @click="predict" :loading="loading">Predict</el-button>
-      </div>
-      <div v-show="is_pdf">
-        <el-row>
-          <el-button-group>
-            <el-button type="primary" :icon="ArrowLeft" @click="prePage">上一页</el-button>
-            <el-button type="primary" @click="nextPage">
-              下一页<el-icon class="el-icon--right">
-                <ArrowRight />
-              </el-icon>
-            </el-button>
-          </el-button-group>
-          <div class="page-tool-item">{{ state.pageNum }}/{{ state.numPages }}</div>
-          <el-container>
-            <el-input type="number" v-model="pdf_page"></el-input>
-            <el-button type="primary" @click="SetPdfPage" plain>页面跳转</el-button>
-          </el-container>
-        </el-row>
+      <div style="position:relative;">
+        <div style="position:absolute;top:0;left:0;z-index:1;width: 100%;height: 100%;">
+          <FileUpload />
+        </div>
+        <div style="position:relative;z-index:0;">
+          <ShowImage :show-src-image=true />
+        </div>
       </div>
-      <el-row>
-        <img id="show-img" class="show-area" />
+      <el-row style="color: gray; font-size: small;">
+        <h4>支持jpg, png, bmp, pdf等文件格式,点击灰色区域或者直接拖拽文件至灰色区域上传文件</h4>
       </el-row>
-      <canvas id="canvas" style="display: none;"></canvas>
+      <PdfPreview />
+      <el-button type="primary" @click="predict" :loading="loading">Predict</el-button>
     </el-col>
     <el-col :span="12" class="place">
       <el-row class="small-title">
         <h2 style="margin-right: 100;">推理结果展示</h2>
         <el-button type="danger" @click="submitBug" disabled>提交bug</el-button>
       </el-row>
-      <el-row style="color: gray; font-size: small;">
-        <p></p>
-      </el-row>
-      <el-row style="color: gray; font-size: small;">
-        <h4></h4>
-      </el-row>
-      <div>
-        <h4></h4>
-        <h4></h4>
+      <div style="margin-top: 43px;">
+        <ShowImage :show-src-image=false />
       </div>
-      <el-row class="small-title">
-        <h4></h4>
-        <h4></h4>
-      </el-row>
-      <el-row>
-        <img id="res-img" class="show-area" />
-        <section> 耗时:{{ predictTime }} ms</section>
-      </el-row>
+      <section> 耗时:{{ predictTime }} ms</section>
     </el-col>
   </el-row>
 </template>
 
 <script lang="ts" setup>
 import { IMMagicColor, SubmitBug } from '../../../../api/api'
-import { reactive, ref } from 'vue'
-import { onMounted } from "vue";
-import {
-  ArrowLeft,
-  ArrowRight,
-  UploadFilled
-} from '@element-plus/icons-vue'
-import { createLoadingTask } from "vue3-pdfjs/esm"; // 获得总页数
+import { ref, onMounted } from 'vue'
+
+import FileUpload from '../../../../components/FileUpload.vue'
+import ShowImage from '../../../../components/ShowImage.vue'
+import PdfPreview from '../../../../components/PdfPreview.vue'
 
 import { storeToRefs } from 'pinia'
 import { useServerIpStore } from '../../../../store/ServerIp';
 import { useServerPortStore } from '../../../../store/ServerPort';
+import { usePdfProperty } from '../../../../store/PdfProperty';
+import { useCanvasImgStore } from '../../../../store/CanvasImg';
 
 const si = useServerIpStore();
 const { server_ip } = storeToRefs(si);
 const sp = useServerPortStore();
 const { server_port } = storeToRefs(sp);
+const pdf_property = usePdfProperty();
+const { is_pdf } = storeToRefs(pdf_property);
+const my_canvas = useCanvasImgStore();
+const { input_file, res_image } = storeToRefs(my_canvas);
 
 const api = "/v1/image_process/magic_color";
 
-let loadingTask: any;
-const pdf_page = ref(1);
-const pdf_img: any = ref("")
-
-const state = reactive({
-  source: "", //预览pdf文件地址
-  pageNum: 1, //当前页面
-  numPages: 0, // 总页数
-});
-
-function dataURLtoBlob(dataURL: any) {
-  var arr = dataURL.split(','),
-    mime = arr[0].match(/:(.*?);/)[1],
-    bstr = atob(arr[1]),
-    n = bstr.length,
-    u8arr = new Uint8Array(n);
-  while (n--) {
-    u8arr[n] = bstr.charCodeAt(n);
-  }
-  return new Blob([u8arr], { type: mime });
-}
-
-function getPdfImage(index: number) {
-  loadingTask.promise.then((pdf: any) => {
-    state.numPages = pdf.numPages;
-    pdf.getPage(index).then((page: any) => {
-      const viewport = page.getViewport({ scale: 2.0 })
-      canvas.value.height = viewport.height;
-      canvas.value.width = viewport.width;
-      const destWidth = 398;
-      canvas.value.style.width = destWidth + 'px';
-      canvas.value.style.height = destWidth * (viewport.height / viewport.width) + 'px';
-      const ctx = canvas.value.getContext('2d');
-      page.render({
-        canvasContext: ctx,
-        viewport,
-      });
-      canvas.value.toBlob(function (blob) {
-        pdf_img.value = dataURLtoBlob(canvas.value.toDataURL('images/png', 1.0))
-        const showImg = document.getElementById("show-img") as HTMLImageElement;
-        showImg.src = canvas.value.toDataURL('images/png', 1.0);
-        showImg.onload = () => {
-          console.log(canvas.value.toDataURL('images/png', 1.0))
-        }
-      });
-    })
-  });
-}
-
-function SetPdfPage() {
-  if (pdf_page.value >= 1 && pdf_page.value <= state.numPages) {
-    console.log(pdf_page.value)
-    state.pageNum = Number(pdf_page.value);
-    getPdfImage(state.pageNum);
-  } else {
-    console.log(pdf_page.value)
-    alert('输入的pdf页面无效!')
-  }
-}
-
-function prePage() {
-  if (state.pageNum > 1) {
-    state.pageNum -= 1;
-    getPdfImage(state.pageNum);
-  }
-}
-
-function nextPage() {
-  if (state.pageNum < state.numPages) {
-    state.pageNum += 1;
-    getPdfImage(state.pageNum);
-  }
-}
-
-// 构建 File 对象
-function blobToFile(blob: any, fileName: any) {
-  blob.lastModifiedDate = new Date();
-  blob.name = fileName;
-  return blob;
-}
-
-async function convertCanvasToFile(canvas: HTMLCanvasElement, fileName: any) {
-  // 将 Canvas 转为 Blob 对象
-  const blob = await new Promise(resolve => canvas.toBlob(blob => {
-    resolve(blob);
-  }, pdf_img.value.type, 1.0));
-  // 手动构造 File 对象
-  let file = null;
-  try {
-    file = new File([pdf_img.value], fileName, { type: pdf_img.value.type });
-  } catch (e) {
-    // Safari 浏览器不支持直接通过 new File() 创建文件对象,需要手动构造
-    const rawFile = blobToFile(blob, fileName);
-    file = Object.assign(rawFile, { lastModifiedDate: new Date(), name: fileName });
-  }
-  return file;
-}
-
 let loading = ref(false)
 const fileName = ref(null as unknown as string);
 let bugId = ref("");
 let predictTime = ref(0)
-const is_pdf = ref(false);
-const canvas = ref(null as unknown as HTMLCanvasElement);
-const res_image: any = ref();
-
-const input_file = ref(null as unknown as File)
-
-onMounted(async () => {
-  canvas.value = document.getElementById("canvas") as HTMLCanvasElement;
-  res_image.value = document.getElementById("res-img") as HTMLImageElement;
-});
-
-const beforeUpload = (file: File): boolean | Promise<boolean> => {
-  const showImg = document.getElementById("show-img") as HTMLImageElement;
-
-  const post_ = file.name.substring(file.name.lastIndexOf("."), file.name.length).toLowerCase();
-  if (post_ == ".pdf") {
-    state.pageNum = 1;
-    state.source = URL.createObjectURL(file);
-    is_pdf.value = true
-    loadingTask = createLoadingTask(state.source);
-    getPdfImage(state.pageNum);
-  } else
-    if (post_ == ".jpg" || post_ == ".png" || post_ == ".bmp" || post_ == ".jpeg") {
-      showImg.src = URL.createObjectURL(file);
-      input_file.value = file;
-      is_pdf.value = false
-    } else {
-      alert('不支持的文件格式!')
-      fileName.value = ''
-    }
-  fileName.value = file.name
-  return true
-}
 
 const predict = () => {
+  fileName.value = input_file.value.name
   if (fileName.value == undefined || fileName.value == '') {
     alert('请上传图片!')
     return;
   }
-
   loading.value = !loading.value
   var data = new FormData();
 
-  if (is_pdf.value) {
-    const file: any = convertCanvasToFile(canvas.value, "pdf.png").then(result => {
-      console.log(result)
-      data.append('image', result);
-      IMMagicColor(api, data).then(res => {
-        res_image.value.src = res.data.image
-        predictTime.value = res.data.cost
-        bugId.value = res.response_id;
-        loading.value = !loading.value
-      }).catch(function (err) {
-        loading.value = !loading.value;
-        bugId.value = ""
-        predictTime.value = 0
-      });
-    })
-  } else {
-    data.append('image', input_file.value);
+  data.append('image', input_file.value);
 
-    IMMagicColor(api, data).then(res => {
-      res_image.value.src = res.data.image
-      predictTime.value = res.data.cost
-      bugId.value = res.response_id;
-      loading.value = !loading.value
-    }).catch(function (err) {
-      loading.value = !loading.value;
-      bugId.value = ""
-      predictTime.value = 0
-    });
-  }
+  IMMagicColor(api, data).then(res => {
+    res_image.value.src = res.data.image
+    predictTime.value = res.data.cost
+    bugId.value = res.response_id;
+    loading.value = !loading.value
+  }).catch(function (err) {
+    loading.value = !loading.value;
+    bugId.value = ""
+    predictTime.value = 0
+  });
 }
 
 const submitBug = async () => {
@@ -300,10 +116,4 @@ const submitBug = async () => {
   justify-content: space-between;
   align-items: center;
 }
-
-.page-tool-item {
-  padding: 8px 15px;
-  padding-left: 10px;
-  cursor: pointer;
-}
 </style>

+ 7 - 3
src/store/CanvasImg.ts

@@ -1,8 +1,12 @@
 import { defineStore } from 'pinia';
-import { ref } from 'vue'
+import { ref, reactive } from 'vue'
 
 export const useCanvasImgStore = defineStore('canvas_img', () => {
-  const canvas_img = ref(HTMLCanvasElement)
+  const show_image = ref(null as unknown as HTMLImageElement);
+  const res_image = ref(null as unknown as HTMLImageElement);
+  const show_canvas = ref(null as unknown as HTMLCanvasElement);
+  const hide_canvas = ref(null as unknown as HTMLCanvasElement);
+  const input_file = ref(null as unknown as File)
 
-  return { canvas_img }
+  return { show_image, res_image, show_canvas, hide_canvas, input_file }
 })

+ 9 - 0
src/store/PdfProperty.ts

@@ -0,0 +1,9 @@
+import { defineStore } from 'pinia';
+import { ref } from 'vue'
+
+export const usePdfProperty = defineStore('PdfProperty', () => {
+  const is_pdf = ref(false)
+  const pdf_source = ref("")
+
+  return { is_pdf, pdf_source }
+})