diff --git a/features/patient/src/main/ets/components/AddAndEditRecordComp.ets b/features/patient/src/main/ets/components/AddAndEditRecordComp.ets index 4a8d83b..ece03f9 100644 --- a/features/patient/src/main/ets/components/AddAndEditRecordComp.ets +++ b/features/patient/src/main/ets/components/AddAndEditRecordComp.ets @@ -300,7 +300,7 @@ export struct AddAndEditRecordComp { } }) } - + // // async convertUrisOrUrlsToBase64(items: string[]): Promise { // const results: string[] = []; // @@ -378,177 +378,9 @@ export struct AddAndEditRecordComp { // throw new Error(`文件读取失败: ${JSON.stringify(err)}`); // } // } - // async convertUrisOrUrlsToBase64(items: string[]): Promise { - // const results: string[] = []; - // const MAX_SIZE_KB = 500; // 最大500KB - // - // for (const item of items) { - // try { - // let base64Str: string; - // - // // 处理本地文件URI - // if (item.startsWith('file://')) { - // base64Str = await this.processLocalImage(item, MAX_SIZE_KB); - // } - // // 处理网络URL - // else if (item.startsWith('http://') || item.startsWith('https://') || ChangeUtil.isImageFileByRegex(item)) { - // base64Str = await this.processNetworkImage(item, MAX_SIZE_KB); - // } - // // 处理其他类型资源 - // else { - // throw new Error(`不支持的URI格式: ${item}`); - // } - // - // results.push(base64Str); - // } catch (err) { - // console.error(`转换失败: ${JSON.stringify(err)}`); - // results.push(''); // 失败时返回空字符串 - // } - // } - // return results; - // } - // - // // 处理本地图片 - // private async processLocalImage(uri: string, maxSizeKB: number): Promise { - // try { - // // 创建图片源 - // const fileSource = await fileIo.open(uri, fileIo.OpenMode.READ_ONLY); - // const imageSource = image.createImageSource(fileSource.fd); - // - // // 获取原始图片信息 - // const pixelMap = await imageSource.createPixelMap(); - // const originalWidth = pixelMap.getPixelBytesNumber(); - // - // // 计算压缩比例,目标500KB以内 - // let quality = 0.9; - // let targetWidth = 800; // 初始目标宽度 - // - // // 如果原始图片太大,逐步压缩 - // if (originalWidth > maxSizeKB * 1024) { - // quality = Math.min(0.6, (maxSizeKB * 1024) / originalWidth); - // targetWidth = Math.min(800, Math.sqrt((maxSizeKB * 1024) / originalWidth) * 100); - // } - // - // // 压缩图片 - // const compressedImageInfo = await compressedImage(pixelMap, targetWidth); - // const compressedUri = compressedImageInfo.imageUri; - // - // // 读取压缩后的图片 - // const compressedBuffer = await this.readLocalFile(compressedUri); - // - // // 如果还是太大,进一步压缩 - // if (compressedBuffer.byteLength > maxSizeKB * 1024) { - // const imagePackerApi = image.createImagePacker(); - // const packOpts: image.PackingOption = { - // format: "image/jpeg", - // quality: Math.max(0.3, quality * 0.8) // 进一步降低质量 - // }; - // - // const finalBuffer = await imagePackerApi.packing(imageSource, packOpts); - // const finalBase64 = buffer.from(finalBuffer).toString('base64'); - // - // // 清理资源 - // imagePackerApi.release(); - // imageSource.release(); - // await fileIo.close(fileSource.fd); - // - // return finalBase64; - // } - // - // // 转换为Base64 - // const base64Str = buffer.from(compressedBuffer).toString('base64'); - // - // // 清理资源 - // imageSource.release(); - // await fileIo.close(fileSource.fd); - // - // return base64Str; - // - // } catch (err) { - // throw new Error(`本地图片处理失败: ${JSON.stringify(err)}`); - // } - // } - // - // // 处理网络图片 - // private async processNetworkImage(url: string, maxSizeKB: number): Promise { - // try { - // // 下载网络资源 - // const arrayBuffer = await ChangeUtil.downloadNetworkResource(url); - // - // // 如果下载的图片太大,进行压缩 - // if (arrayBuffer.byteLength > maxSizeKB * 1024) { - // // 创建临时文件来压缩 - // const tempUri = await this.saveToTempFile(arrayBuffer); - // const compressedBase64 = await this.processLocalImage(tempUri, maxSizeKB); - // - // // 清理临时文件 - // await this.deleteTempFile(tempUri); - // - // return compressedBase64; - // } - // - // // 直接转换为Base64 - // return buffer.from(arrayBuffer).toString('base64'); - // - // } catch (err) { - // throw new Error(`网络图片处理失败: ${JSON.stringify(err)}`); - // } - // } - // - // // 保存到临时文件 - // private async saveToTempFile(arrayBuffer: ArrayBuffer): Promise { - // try { - // // 使用应用缓存目录作为临时目录 - // const context = getContext(this); - // const tempDir = context.cacheDir; - // const tempFileName = `temp_${Date.now()}.jpg`; - // const tempPath = `${tempDir}/${tempFileName}`; - // - // const file = await fileIo.open(tempPath, fileIo.OpenMode.CREATE | fileIo.OpenMode.WRITE_ONLY); - // await fileIo.write(file.fd, arrayBuffer); - // await fileIo.close(file.fd); - // - // return tempPath; - // } catch (err) { - // throw new Error(`临时文件保存失败: ${JSON.stringify(err)}`); - // } - // } - // - // // 删除临时文件 - // private async deleteTempFile(uri: string): Promise { - // try { - // await fileIo.unlink(uri); - // } catch (err) { - // console.warn(`临时文件删除失败: ${JSON.stringify(err)}`); - // } - // } - // - // // 优化后的本地文件读取方法 - // async readLocalFile(uri: string): Promise { - // try { - // // 使用异步方式读取,避免阻塞 - // const file = await fileIo.open(uri, fileIo.OpenMode.READ_ONLY); - // const stat = await fileIo.stat(uri); - // const size = stat.size; - // - // // 限制文件大小,避免内存溢出 - // if (size > 10 * 1024 * 1024) { // 10MB限制 - // throw new Error('文件过大,超过10MB限制'); - // } - // - // const buffer = new ArrayBuffer(size); - // await fileIo.read(file.fd, buffer); - // await fileIo.close(file); - // - // return buffer; - // } catch (err) { - // throw new Error(`文件读取失败: ${JSON.stringify(err)}`); - // } - // } async convertUrisOrUrlsToBase64(items: string[]): Promise { const results: string[] = []; - const MAX_SIZE_KB = 100; // 最大100KB,确保服务器兼容性 - const MAX_DIMENSION = 800; // 最大尺寸800px,平衡质量和兼容性 + const MAX_SIZE_KB = 500; // 最大500KB for (const item of items) { try { @@ -556,23 +388,18 @@ export struct AddAndEditRecordComp { // 处理本地文件URI if (item.startsWith('file://')) { - base64Str = await this.processLocalImageCompatible(item, MAX_SIZE_KB, MAX_DIMENSION); + base64Str = await this.processLocalImage(item, MAX_SIZE_KB); } // 处理网络URL else if (item.startsWith('http://') || item.startsWith('https://') || ChangeUtil.isImageFileByRegex(item)) { - base64Str = await this.processNetworkImageCompatible(item, MAX_SIZE_KB, MAX_DIMENSION); + base64Str = await this.processNetworkImage(item, MAX_SIZE_KB); } // 处理其他类型资源 else { throw new Error(`不支持的URI格式: ${item}`); } - // 验证base64数据有效性 - if (base64Str && base64Str.length > 0) { - results.push(base64Str); - } else { - results.push(''); // 空字符串表示处理失败 - } + results.push(base64Str); } catch (err) { console.error(`转换失败: ${JSON.stringify(err)}`); results.push(''); // 失败时返回空字符串 @@ -581,86 +408,60 @@ export struct AddAndEditRecordComp { return results; } - // 兼容性本地图片处理 - private async processLocalImageCompatible(uri: string, maxSizeKB: number, maxDimension: number): Promise { + // 处理本地图片 + private async processLocalImage(uri: string, maxSizeKB: number): Promise { try { // 创建图片源 const fileSource = await fileIo.open(uri, fileIo.OpenMode.READ_ONLY); const imageSource = image.createImageSource(fileSource.fd); // 获取原始图片信息 - const imageInfo = await imageSource.getImageInfo(); - const originalWidth = imageInfo.size.width; - const originalHeight = imageInfo.size.height; - - // 计算目标尺寸,确保兼容性 - const targetDimensions = this.calculateCompatibleDimensions(originalWidth, originalHeight, maxDimension); - - // 创建PixelMap const pixelMap = await imageSource.createPixelMap(); + const originalWidth = pixelMap.getPixelBytesNumber(); - // 使用标准JPEG格式,确保兼容性 - const imagePackerApi = image.createImagePacker(); - const packOpts: image.PackingOption = { - format: "image/jpeg", - quality: 0.85 // 适中的质量,平衡大小和兼容性 - }; + // 计算压缩比例,目标500KB以内 + let quality = 0.9; + let targetWidth = 800; // 初始目标宽度 - let finalPixelMap = pixelMap; - let needsResize = false; - - // 检查是否需要调整尺寸 - if (targetDimensions.width < originalWidth || targetDimensions.height < originalHeight) { - needsResize = true; - // 使用compressedImage调整尺寸 - const compressedImageInfo = await compressedImage(pixelMap, targetDimensions.width); - const compressedUri = compressedImageInfo.imageUri; - - // 从压缩后的URI创建新的PixelMap - const compressedFileSource = await fileIo.open(compressedUri, fileIo.OpenMode.READ_ONLY); - const compressedImageSource = image.createImageSource(compressedFileSource.fd); - finalPixelMap = await compressedImageSource.createPixelMap(); - - // 清理临时资源 - compressedImageSource.release(); - await fileIo.close(compressedFileSource.fd); + // 如果原始图片太大,逐步压缩 + if (originalWidth > maxSizeKB * 1024) { + quality = Math.min(0.6, (maxSizeKB * 1024) / originalWidth); + targetWidth = Math.min(800, Math.sqrt((maxSizeKB * 1024) / originalWidth) * 100); } - // 打包为JPEG格式 - const finalBuffer = await imagePackerApi.packing(finalPixelMap, packOpts); + // 压缩图片 + const compressedImageInfo = await compressedImage(pixelMap, targetWidth); + const compressedUri = compressedImageInfo.imageUri; - // 验证buffer大小 - if (finalBuffer.byteLength > maxSizeKB * 1024) { - // 如果还是太大,进一步降低质量 - const fallbackOpts: image.PackingOption = { + // 读取压缩后的图片 + const compressedBuffer = await this.readLocalFile(compressedUri); + + // 如果还是太大,进一步压缩 + if (compressedBuffer.byteLength > maxSizeKB * 1024) { + const imagePackerApi = image.createImagePacker(); + const packOpts: image.PackingOption = { format: "image/jpeg", - quality: 0.7 + quality: Math.max(0.3, quality * 0.8) // 进一步降低质量 }; - const fallbackBuffer = await imagePackerApi.packing(finalPixelMap, fallbackOpts); + + const finalBuffer = await imagePackerApi.packing(imageSource, packOpts); + const finalBase64 = buffer.from(finalBuffer).toString('base64'); // 清理资源 imagePackerApi.release(); imageSource.release(); await fileIo.close(fileSource.fd); - if (needsResize && finalPixelMap !== pixelMap) { - finalPixelMap.release(); - } - - return buffer.from(fallbackBuffer).toString('base64'); + return finalBase64; } - const base64Str = buffer.from(finalBuffer).toString('base64'); + // 转换为Base64 + const base64Str = buffer.from(compressedBuffer).toString('base64'); // 清理资源 - imagePackerApi.release(); imageSource.release(); await fileIo.close(fileSource.fd); - if (needsResize && finalPixelMap !== pixelMap) { - finalPixelMap.release(); - } - return base64Str; } catch (err) { @@ -668,17 +469,17 @@ export struct AddAndEditRecordComp { } } - // 兼容性网络图片处理 - private async processNetworkImageCompatible(url: string, maxSizeKB: number, maxDimension: number): Promise { + // 处理网络图片 + private async processNetworkImage(url: string, maxSizeKB: number): Promise { try { // 下载网络资源 const arrayBuffer = await ChangeUtil.downloadNetworkResource(url); - // 检查下载的图片大小 + // 如果下载的图片太大,进行压缩 if (arrayBuffer.byteLength > maxSizeKB * 1024) { // 创建临时文件来压缩 const tempUri = await this.saveToTempFile(arrayBuffer); - const compressedBase64 = await this.processLocalImageCompatible(tempUri, maxSizeKB, maxDimension); + const compressedBase64 = await this.processLocalImage(tempUri, maxSizeKB); // 清理临时文件 await this.deleteTempFile(tempUri); @@ -694,39 +495,13 @@ export struct AddAndEditRecordComp { } } - // 计算兼容性尺寸 - private calculateCompatibleDimensions(originalWidth: number, originalHeight: number, maxDimension: number): GeneratedTypeLiteralInterface_2 { - let targetWidth = originalWidth; - let targetHeight = originalHeight; - - // 如果尺寸超过最大限制,按比例缩小 - if (originalWidth > maxDimension || originalHeight > maxDimension) { - if (originalWidth > originalHeight) { - targetWidth = maxDimension; - targetHeight = Math.round((originalHeight * maxDimension) / originalWidth); - } else { - targetHeight = maxDimension; - targetWidth = Math.round((originalWidth * maxDimension) / originalHeight); - } - } - - // 确保尺寸是偶数,提高兼容性 - targetWidth = Math.round(targetWidth / 2) * 2; - targetHeight = Math.round(targetHeight / 2) * 2; - - // 设置最小尺寸限制 - if (targetWidth < 100) targetWidth = 100; - if (targetHeight < 100) targetHeight = 100; - - return { width: targetWidth, height: targetHeight }; - } - // 保存到临时文件 private async saveToTempFile(arrayBuffer: ArrayBuffer): Promise { try { + // 使用应用缓存目录作为临时目录 const context = getContext(this); const tempDir = context.cacheDir; - const tempFileName = `temp_${Date.now()}_${Math.random().toString(36).substr(2, 9)}.jpg`; + const tempFileName = `temp_${Date.now()}.jpg`; const tempPath = `${tempDir}/${tempFileName}`; const file = await fileIo.open(tempPath, fileIo.OpenMode.CREATE | fileIo.OpenMode.WRITE_ONLY); @@ -748,16 +523,17 @@ export struct AddAndEditRecordComp { } } - // 兼容性本地文件读取方法 + // 优化后的本地文件读取方法 async readLocalFile(uri: string): Promise { try { + // 使用异步方式读取,避免阻塞 const file = await fileIo.open(uri, fileIo.OpenMode.READ_ONLY); const stat = await fileIo.stat(uri); const size = stat.size; - // 更保守的文件大小限制 - if (size > 3 * 1024 * 1024) { // 3MB限制 - throw new Error('文件过大,超过3MB限制'); + // 限制文件大小,避免内存溢出 + if (size > 10 * 1024 * 1024) { // 10MB限制 + throw new Error('文件过大,超过10MB限制'); } const buffer = new ArrayBuffer(size); @@ -769,6 +545,230 @@ export struct AddAndEditRecordComp { throw new Error(`文件读取失败: ${JSON.stringify(err)}`); } } + // async convertUrisOrUrlsToBase64(items: string[]): Promise { + // const results: string[] = []; + // const MAX_SIZE_KB = 100; // 最大100KB,确保服务器兼容性 + // const MAX_DIMENSION = 800; // 最大尺寸800px,平衡质量和兼容性 + // + // for (const item of items) { + // try { + // let base64Str: string; + // + // // 处理本地文件URI + // if (item.startsWith('file://')) { + // base64Str = await this.processLocalImageCompatible(item, MAX_SIZE_KB, MAX_DIMENSION); + // } + // // 处理网络URL + // else if (item.startsWith('http://') || item.startsWith('https://') || ChangeUtil.isImageFileByRegex(item)) { + // base64Str = await this.processNetworkImageCompatible(item, MAX_SIZE_KB, MAX_DIMENSION); + // } + // // 处理其他类型资源 + // else { + // throw new Error(`不支持的URI格式: ${item}`); + // } + // + // // 验证base64数据有效性 + // if (base64Str && base64Str.length > 0) { + // results.push(base64Str); + // } else { + // results.push(''); // 空字符串表示处理失败 + // } + // } catch (err) { + // console.error(`转换失败: ${JSON.stringify(err)}`); + // results.push(''); // 失败时返回空字符串 + // } + // } + // return results; + // } + // + // // 兼容性本地图片处理 + // private async processLocalImageCompatible(uri: string, maxSizeKB: number, maxDimension: number): Promise { + // try { + // // 创建图片源 + // const fileSource = await fileIo.open(uri, fileIo.OpenMode.READ_ONLY); + // const imageSource = image.createImageSource(fileSource.fd); + // + // // 获取原始图片信息 + // const imageInfo = await imageSource.getImageInfo(); + // const originalWidth = imageInfo.size.width; + // const originalHeight = imageInfo.size.height; + // + // // 计算目标尺寸,确保兼容性 + // const targetDimensions = this.calculateCompatibleDimensions(originalWidth, originalHeight, maxDimension); + // + // // 创建PixelMap + // const pixelMap = await imageSource.createPixelMap(); + // + // // 使用标准JPEG格式,确保兼容性 + // const imagePackerApi = image.createImagePacker(); + // const packOpts: image.PackingOption = { + // format: "image/jpeg", + // quality: 0.85 // 适中的质量,平衡大小和兼容性 + // }; + // + // let finalPixelMap = pixelMap; + // let needsResize = false; + // + // // 检查是否需要调整尺寸 + // if (targetDimensions.width < originalWidth || targetDimensions.height < originalHeight) { + // needsResize = true; + // // 使用compressedImage调整尺寸 + // const compressedImageInfo = await compressedImage(pixelMap, targetDimensions.width); + // const compressedUri = compressedImageInfo.imageUri; + // + // // 从压缩后的URI创建新的PixelMap + // const compressedFileSource = await fileIo.open(compressedUri, fileIo.OpenMode.READ_ONLY); + // const compressedImageSource = image.createImageSource(compressedFileSource.fd); + // finalPixelMap = await compressedImageSource.createPixelMap(); + // + // // 清理临时资源 + // compressedImageSource.release(); + // await fileIo.close(compressedFileSource.fd); + // } + // + // // 打包为JPEG格式 + // const finalBuffer = await imagePackerApi.packing(finalPixelMap, packOpts); + // + // // 验证buffer大小 + // if (finalBuffer.byteLength > maxSizeKB * 1024) { + // // 如果还是太大,进一步降低质量 + // const fallbackOpts: image.PackingOption = { + // format: "image/jpeg", + // quality: 0.7 + // }; + // const fallbackBuffer = await imagePackerApi.packing(finalPixelMap, fallbackOpts); + // + // // 清理资源 + // imagePackerApi.release(); + // imageSource.release(); + // await fileIo.close(fileSource.fd); + // + // if (needsResize && finalPixelMap !== pixelMap) { + // finalPixelMap.release(); + // } + // + // return buffer.from(fallbackBuffer).toString('base64'); + // } + // + // const base64Str = buffer.from(finalBuffer).toString('base64'); + // + // // 清理资源 + // imagePackerApi.release(); + // imageSource.release(); + // await fileIo.close(fileSource.fd); + // + // if (needsResize && finalPixelMap !== pixelMap) { + // finalPixelMap.release(); + // } + // + // return base64Str; + // + // } catch (err) { + // throw new Error(`本地图片处理失败: ${JSON.stringify(err)}`); + // } + // } + // + // // 兼容性网络图片处理 + // private async processNetworkImageCompatible(url: string, maxSizeKB: number, maxDimension: number): Promise { + // try { + // // 下载网络资源 + // const arrayBuffer = await ChangeUtil.downloadNetworkResource(url); + // + // // 检查下载的图片大小 + // if (arrayBuffer.byteLength > maxSizeKB * 1024) { + // // 创建临时文件来压缩 + // const tempUri = await this.saveToTempFile(arrayBuffer); + // const compressedBase64 = await this.processLocalImageCompatible(tempUri, maxSizeKB, maxDimension); + // + // // 清理临时文件 + // await this.deleteTempFile(tempUri); + // + // return compressedBase64; + // } + // + // // 直接转换为Base64 + // return buffer.from(arrayBuffer).toString('base64'); + // + // } catch (err) { + // throw new Error(`网络图片处理失败: ${JSON.stringify(err)}`); + // } + // } + // + // // 计算兼容性尺寸 + // private calculateCompatibleDimensions(originalWidth: number, originalHeight: number, maxDimension: number): GeneratedTypeLiteralInterface_2 { + // let targetWidth = originalWidth; + // let targetHeight = originalHeight; + // + // // 如果尺寸超过最大限制,按比例缩小 + // if (originalWidth > maxDimension || originalHeight > maxDimension) { + // if (originalWidth > originalHeight) { + // targetWidth = maxDimension; + // targetHeight = Math.round((originalHeight * maxDimension) / originalWidth); + // } else { + // targetHeight = maxDimension; + // targetWidth = Math.round((originalWidth * maxDimension) / originalHeight); + // } + // } + // + // // 确保尺寸是偶数,提高兼容性 + // targetWidth = Math.round(targetWidth / 2) * 2; + // targetHeight = Math.round(targetHeight / 2) * 2; + // + // // 设置最小尺寸限制 + // if (targetWidth < 100) targetWidth = 100; + // if (targetHeight < 100) targetHeight = 100; + // + // return { width: targetWidth, height: targetHeight }; + // } + // + // // 保存到临时文件 + // private async saveToTempFile(arrayBuffer: ArrayBuffer): Promise { + // try { + // const context = getContext(this); + // const tempDir = context.cacheDir; + // const tempFileName = `temp_${Date.now()}_${Math.random().toString(36).substr(2, 9)}.jpg`; + // const tempPath = `${tempDir}/${tempFileName}`; + // + // const file = await fileIo.open(tempPath, fileIo.OpenMode.CREATE | fileIo.OpenMode.WRITE_ONLY); + // await fileIo.write(file.fd, arrayBuffer); + // await fileIo.close(file.fd); + // + // return tempPath; + // } catch (err) { + // throw new Error(`临时文件保存失败: ${JSON.stringify(err)}`); + // } + // } + // + // // 删除临时文件 + // private async deleteTempFile(uri: string): Promise { + // try { + // await fileIo.unlink(uri); + // } catch (err) { + // console.warn(`临时文件删除失败: ${JSON.stringify(err)}`); + // } + // } + // + // // 兼容性本地文件读取方法 + // async readLocalFile(uri: string): Promise { + // try { + // const file = await fileIo.open(uri, fileIo.OpenMode.READ_ONLY); + // const stat = await fileIo.stat(uri); + // const size = stat.size; + // + // // 更保守的文件大小限制 + // if (size > 3 * 1024 * 1024) { // 3MB限制 + // throw new Error('文件过大,超过3MB限制'); + // } + // + // const buffer = new ArrayBuffer(size); + // await fileIo.read(file.fd, buffer); + // await fileIo.close(file); + // + // return buffer; + // } catch (err) { + // throw new Error(`文件读取失败: ${JSON.stringify(err)}`); + // } + // } } interface recordList {