App Inventor接入Google OCR图片识别响应缓慢 批量作业效率不足求优化
现有OCR方案性能问题优化指南
核心瓶颈分析
- 冗余创建原始图片临时文件:原逻辑先将解码后的Blob存为Drive临时文件,再重新读取该Blob传给OCR接口,完全是多余的IO操作
- 单图串行链路冗余:每张图都要走「上传Base64→存临时Drive文件→重复读取已解码的Blob→调用OCR生成临时文档→提取文本→单独删除2个临时文件」的完整流程,多次Drive API IO的叠加延迟就占了7-10秒中的80%
- 无批量处理能力:当前逻辑只支持单图单请求,100张图需要发起100次独立网络请求,每次都要完成握手、鉴权的固定开销,延迟线性累加
- 上传数据冗余:未对原图做预压缩,150-1000kB的原图转Base64后体积膨胀33%,拖慢上传速度
- OCR配置冗余:未指定OCR识别语言,自动检测语言的额外计算量进一步增加处理时长
- 文本提取方式低效:使用
DocumentApp.openById读取文本,相比直接读取Drive文件内容开销高30%以上
可直接落地的优化方案
App Inventor端调整
- 上传前预压缩图片:使用
ImageUtilities组件将图片长边限制为1280px、质量设置为80%,压缩后体积可降至100-300kB,Base64编码后的上传体积同步缩小60%以上 - 批量合并请求:将最多10张图的Base64数据打包为JSON数组,单次POST请求发送,相比单图单独发请求可减少90%的网络握手开销
- 取消逐张删除临时文件的逻辑:所有清理操作交由GAS端批量执行
GAS端代码替换
调整前需先在Google Drive新建专属临时文件夹,将文件夹ID填入下方配置项,并在GAS的「服务」菜单中开启Drive API
// 全局配置项 const CONFIG = { TEMP_FOLDER_ID: '替换为你的临时文件夹ID', OCR_LANG: 'zh', // 按实际识别语言修改,如英文改为'en' MAX_BATCH_COUNT: 10 // 单次最多处理的图片数量,避免触发GAS执行时长限制 }; function doPost(e) { try { // 解析批量传入的图片数据 const requestData = JSON.parse(e.postData.contents); const imgList = requestData.images; if (!imgList || imgList.length === 0) { return ContentService.createTextOutput(JSON.stringify({ status: "error", message: "未传入有效图片数据" })); } if (imgList.length > CONFIG.MAX_BATCH_COUNT) { return ContentService.createTextOutput(JSON.stringify({ status: "error", message: `单次最多支持${CONFIG.MAX_BATCH_COUNT}张图片` })); } const tempDocIds = []; const ocrResults = []; // 批量处理每张图片 for (const img of imgList) { try { // 直接使用Base64解码后的Blob生成OCR输入,省去重复读取Drive文件的步骤 const imgBlob = Utilities.newBlob( Utilities.base64Decode(img.data), img.mimetype, img.filename ); // 指定OCR语言,减少自动检测的额外开销 const ocrOptions = { ocr: true, ocrLanguage: CONFIG.OCR_LANG }; // 直接调用Drive OCR生成临时文档,无需预先存储原始图片 const docFile = Drive.Files.insert( { title: img.filename, mimeType: imgBlob.getContentType() }, imgBlob, ocrOptions ); tempDocIds.push(docFile.id); // 直接读取Drive文件内容提取文本,替代效率更低的DocumentApp调用 const ocrText = Drive.Files.get(docFile.id, { fields: 'content' }).content.replace(/\n/g, ''); ocrResults.push({ filename: img.filename, text: ocrText, status: "success" }); } catch (imgErr) { ocrResults.push({ filename: img.filename, status: "error", message: imgErr.toString() }); } } // 批量删除所有临时文档,仅需1次API调用,替代逐张删除的多次开销 if (tempDocIds.length > 0) { Drive.Files.batchDelete({ ids: tempDocIds }); } return ContentService.createTextOutput(JSON.stringify({ status: "success", results: ocrResults })); } catch (err) { return ContentService.createTextOutput(JSON.stringify({ status: "error", message: err.toString() })); } }
优化后预期性能
- 单张图片处理时长降至1-2秒,较原方案提升75%以上
- 100张图片分为10批处理,总耗时可控制在30秒以内,满足现场批量作业需求
- 临时文件API调用次数减少90%,不会触发Google Drive的调用配额限制
内容的提问来源于stack exchange,提问作者Gilbert Tse Kit Lam
相关产品推荐
相关产品推荐

