如何通过GCS Filesystem成功读取JPG文件及问题排查
问题解答
1. 如何获取正确的文件?
你遇到的FileNotFoundError核心原因是字符串格式化未生效,导致代码尝试读取字面量{user_id}.jpg而非实际用户ID对应的文件,同时存在GCS文件读取方式的问题,修正步骤如下:
错误点拆解
text_detected函数中,你用单引号包裹路径:'img_platecapture/{user_id}.jpg',这种写法不会将{user_id}替换为传入的参数值,GCS会尝试查找名为{user_id}.jpg的文件(URL编码后显示为%7Buser_id%7D.jpg)。- PIL的
Image.open()无法直接读取GCS远程路径,必须先将文件内容读入内存再处理。
修正后的代码
from google.cloud import storage from google.cloud import vision from PIL import Image, ImageDraw, ImageFont import gcsfs from io import BytesIO # 新增:用于在内存中处理图片字节流 # 全局初始化客户端,避免重复创建浪费资源 fs = gcsfs.GCSFileSystem(project='My Project GoogleMap') vision_client = vision.ImageAnnotatorClient() storage_client = storage.Client() def text_detected(user_id): # 使用f-string格式化路径,替换为实际user_id file_path = f'img_platecapture/{user_id}.jpg' with fs.open(file_path, 'rb') as f: content = f.read() # 调用Google Vision API识别文本 image = vision.Image(content=content) response = vision_client.text_detection(image=image) if response.error.message: raise Exception( f'{response.error.message}\n参考官方错误文档了解详情' ) # 将字节流转为类文件对象,供PIL读取 img = Image.open(BytesIO(content)) # 后续图片处理逻辑... # 返回识别结果示例 return response.text_annotations[0].description if response.text_annotations else '未检测到文本' @handler.add(MessageEvent, message=ImageMessage) def handle_content_message(event): message_content = line_bot_api.get_message_content(event.message.id) user = line_bot_api.get_profile(event.source.user_id) data = b'' for chunk in message_content.iter_content(): data += chunk bucket_name = 'img_platecapture' bucket = storage_client.bucket(bucket_name) blob = bucket.blob(f'{user.user_id}.jpg') blob.upload_from_string(data) # 可选:上传后刷新blob状态,确保GCS同步完成 blob.reload() text_detected1 = text_detected(user.user_id) line_bot_api.reply_message( event.reply_token, TextSendMessage(text=text_detected1) )
2. 读取JPG文件与文本文件不同,代码中有什么需要特别注意的地方?
- 必须用二进制模式读取:读取图片时要指定
'rb'模式,不能用文本模式'r',否则会破坏二进制结构,导致图片无法识别。 - 远程文件需转内存流:像PIL这类本地图片处理库无法直接识别GCS远程路径,必须先将文件内容读取为字节流,再通过
BytesIO包装成类文件对象。 - 无需处理编码:图片是纯二进制数据,读取时不需要指定编码格式;而文本文件通常需要指定编码(如
utf-8)。 - 校验文件完整性:读取后可尝试用PIL打开验证,避免因文件上传不完整、损坏导致后续处理报错。
内容的提问来源于stack exchange,提问作者april
相关产品推荐
相关产品推荐

