From 04816e1fd0c9e0c42b6c03fbd9465ea0bb9d4696 Mon Sep 17 00:00:00 2001 From: hayu <1604366271@qq.com> Date: Wed, 30 Jul 2025 14:35:01 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8A=9F=E8=83=BD=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages.json | 11 + src/pages/devicesSearch/camera.vue | 646 +++++++++++++++++++++ src/pages/devicesSearch/ocrSearch.nvue | 751 ++++++++++--------------- src/services/utils/imageUtils.js | 197 +++++++ 4 files changed, 1143 insertions(+), 462 deletions(-) create mode 100644 src/pages/devicesSearch/camera.vue create mode 100644 src/services/utils/imageUtils.js diff --git a/src/pages.json b/src/pages.json index 12e6a5d..05d2808 100644 --- a/src/pages.json +++ b/src/pages.json @@ -580,6 +580,17 @@ "navigationBarTitleText": "OCR查询" } }, + { + "path": "pages/devicesSearch/camera", + "style": { + "navigationStyle": "custom", + "navigationBarTitleText": "相机识别", + "app-plus": { + "orientation": ["portrait-primary"], + "background": "#000000" + } + } + }, { "path": "pages/devicesSearch/codeSearch", "style": { diff --git a/src/pages/devicesSearch/camera.vue b/src/pages/devicesSearch/camera.vue new file mode 100644 index 0000000..8c2f834 --- /dev/null +++ b/src/pages/devicesSearch/camera.vue @@ -0,0 +1,646 @@ + + + + + diff --git a/src/pages/devicesSearch/ocrSearch.nvue b/src/pages/devicesSearch/ocrSearch.nvue index 8c4b80c..853af9f 100644 --- a/src/pages/devicesSearch/ocrSearch.nvue +++ b/src/pages/devicesSearch/ocrSearch.nvue @@ -1,491 +1,318 @@ diff --git a/src/services/utils/imageUtils.js b/src/services/utils/imageUtils.js new file mode 100644 index 0000000..5d71078 --- /dev/null +++ b/src/services/utils/imageUtils.js @@ -0,0 +1,197 @@ +// 图片处理工具类 +class ImageUtils { + /** + * 将图片转换为Base64字符串(相当于Android的bitmapToString) + * @param {string} imagePath 图片路径 + * @param {number} quality 压缩质量 0-100 + * @returns {Promise} Base64字符串 + */ + static async imageToBase64(imagePath, quality = 50) { + try { + // 如果已经是base64格式,直接返回数据部分 + if (imagePath.startsWith("data:image/")) { + return imagePath.split(",")[1] + } + + // 如果是纯base64字符串,直接返回 + if (!imagePath.includes("/") && !imagePath.includes("\\")) { + return imagePath + } + + // 压缩图片 + const compressResult = await new Promise((resolve, reject) => { + window.uni.compressImage({ + src: imagePath, + quality: quality, + success: resolve, + fail: reject, + }) + }) + + // 读取压缩后的文件并转换为base64 + const fileManager = window.uni.getFileSystemManager() + const base64Data = await new Promise((resolve, reject) => { + fileManager.readFile({ + filePath: compressResult.tempFilePath, + encoding: "base64", + success: (res) => resolve(res.data), + fail: reject, + }) + }) + + return base64Data + } catch (error) { + console.error("Image to base64 conversion failed:", error) + throw error + } + } + + /** + * 获取缩放后的图片(相当于Android的getSmallBitmap) + * @param {string} imagePath 图片路径 + * @param {number} maxWidth 最大宽度 + * @param {number} maxHeight 最大高度 + * @returns {Promise} 处理后的图片路径 + */ + static async getSmallImage(imagePath, maxWidth = 1024, maxHeight = 1024) { + try { + return await this.resizeImageWithCanvas(imagePath, maxWidth, maxHeight) + } catch (error) { + console.error("Get small image failed:", error) + // 如果canvas方法失败,尝试使用压缩API + return await this.fallbackCompress(imagePath, maxWidth, maxHeight) + } + } + + /** + * 使用Canvas调整图片尺寸 + * @param {string} imagePath 图片路径 + * @param {number} maxWidth 最大宽度 + * @param {number} maxHeight 最大高度 + * @returns {Promise} 处理后的图片路径 + */ + static async resizeImageWithCanvas(imagePath, maxWidth, maxHeight) { + return new Promise((resolve, reject) => { + // 获取图片信息 + window.uni.getImageInfo({ + src: imagePath, + success: (imageInfo) => { + const { width, height } = imageInfo + + // 计算缩放比例 + const scale = this.calculateScale(width, height, maxWidth, maxHeight) + const newWidth = Math.floor(width * scale) + const newHeight = Math.floor(height * scale) + + // 如果不需要缩放,直接返回原图 + if (scale >= 1) { + resolve(imagePath) + return + } + + // 创建canvas上下文 + const canvasId = "imageProcessCanvas_" + Date.now() + const ctx = window.uni.createCanvasContext(canvasId) + + // 绘制缩放后的图片 + ctx.drawImage(imagePath, 0, 0, newWidth, newHeight) + ctx.draw(false, () => { + // 导出canvas为临时文件 + window.uni.canvasToTempFilePath({ + canvasId: canvasId, + fileType: "jpg", + quality: 0.8, + success: (res) => { + resolve(res.tempFilePath) + }, + fail: reject, + }) + }) + }, + fail: reject, + }) + }) + } + + /** + * 备用压缩方法 + * @param {string} imagePath 图片路径 + * @param {number} maxWidth 最大宽度 + * @param {number} maxHeight 最大高度 + * @returns {Promise} 处理后的图片路径 + */ + static async fallbackCompress(imagePath, maxWidth, maxHeight) { + return new Promise((resolve, reject) => { + window.uni.compressImage({ + src: imagePath, + quality: 80, + compressedWidth: maxWidth, + compressedHeight: maxHeight, + success: (res) => resolve(res.tempFilePath), + fail: reject, + }) + }) + } + + /** + * 计算缩放比例(相当于Android的calculateInSampleSize) + * @param {number} originalWidth 原始宽度 + * @param {number} originalHeight 原始高度 + * @param {number} maxWidth 最大宽度 + * @param {number} maxHeight 最大高度 + * @returns {number} 缩放比例 + */ + static calculateScale(originalWidth, originalHeight, maxWidth, maxHeight) { + if (originalWidth <= maxWidth && originalHeight <= maxHeight) { + return 1 // 不需要缩放 + } + + const widthScale = maxWidth / originalWidth + const heightScale = maxHeight / originalHeight + + // 选择较小的缩放比例,确保图片完全适应限制尺寸 + return Math.min(widthScale, heightScale) + } + + /** + * 批量处理图片 + * @param {string} imagePath 图片路径 + * @param {object} options 处理选项 + * @returns {Promise} 处理后的Base64字符串 + */ + static async processImage(imagePath, options = {}) { + const { maxWidth = 1024, maxHeight = 1024, quality = 50, outputFormat = "base64" } = options + + try { + // 1. 先缩放图片 + const resizedImagePath = await this.getSmallImage(imagePath, maxWidth, maxHeight) + + // 2. 根据输出格式返回结果 + if (outputFormat === "base64") { + return await this.imageToBase64(resizedImagePath, quality) + } else { + return resizedImagePath + } + } catch (error) { + console.error("Process image failed:", error) + throw error + } + } + + /** + * 获取图片尺寸信息 + * @param {string} imagePath 图片路径 + * @returns {Promise} 图片信息 + */ + static async getImageInfo(imagePath) { + return new Promise((resolve, reject) => { + window.uni.getImageInfo({ + src: imagePath, + success: resolve, + fail: reject, + }) + }) + } +} + +export default ImageUtils