// 图片处理工具类 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