1. 什么错误
在使用百度OCR识别时遇到了错误error_code: 216205。
参照文档【百度OCR文字识别 - API文档 - 错误码】中的描述,是我的图片转base64后大于10M
测试两张图片:923k图片的Base64 大于
10M;2M图片的Base64 小于
10M。
# 电脑上看的图片大小为
923 KB
# 代码计算的图片大小如下:
img_pil大小(MB): 26.162841796875
img_base64大小(MB): 11.161312103271484
# 电脑上看的图片大小为
2.35 MB
# 代码计算的图片大小如下:
img_pil大小(MB): 4.660074234008789
img_base64大小(MB): 2.640827178955078
这种差异通常是由于图像在存储和显示时采用的压缩方式不同而导致的。
- 在计算机上查看图片时,常见的图像格式(如JPEG、PNG等)会对图像进行有损或无损的压缩,以减小文件大小并提高传输和存储效率。
- 代码中计算的图片大小是根据图像的原始数据(像素数量和颜色通道数)计算的,不考虑压缩。
具体来说,
- 计算机上查看图片的大小通常是根据图像文件的实际字节数(包括文件头和元数据)以及压缩后的图像数据来计算的。
- 而代码中计算的图片大小则是根据图像的原始数据(像素数量和颜色通道数)直接计算的,并不考虑压缩。
- 因此,这两种大小之间可能存在较大的差异。
另外,计算机上查看图片的大小也可能受到操作系统、查看软件以及显示器分辨率等因素的影响。
因此,即使是相同的图像文件,在不同的环境中查看可能会显示不同的大小。
2. 解决方案
源代码
def pillow_to_base64(image):
"""PIL图像转base64编码"""
img_buffer = BytesIO()
image.save(img_buffer, format='PNG')
byte_data = img_buffer.getvalue()
base64_str = base64.b64encode(byte_data).decode('utf-8')
return base64_str
# 将上传的图像转换为PIL Image对象
img_pil = Image.fromarray(img)
img_base64 = pillow_to_base64(img_pil)
# 后续代码 #
修改代码
def pillow_to_base64(image):
"""PIL图像转base64编码"""
img_buffer = BytesIO()
image.save(img_buffer, format='PNG')
byte_data = img_buffer.getvalue()
base64_str = base64.b64encode(byte_data).decode('utf-8')
return base64_str
def compute_size_MB(img):
print('===计算图像大小===')
img_size = img.width * img.height * 3 / (1024 * 1024) # 假设RGB颜色模式,每个像素3个字节
return img_size
def resize_and_compress_image(img_pil):
img_pil_compressed = img_pil
img_pil_size = compute_size_MB(img_pil) # 计算初始图像大小
compression_count = 0 # 压缩次数计数器
while img_pil_size > 20: # 如果图像大小超过20MB,则进行压缩处理
img_pil_compressed = img_pil_compressed.resize((img_pil_compressed.width // 2, img_pil_compressed.height // 2))
img_pil_size = compute_size_MB(img_pil_compressed) # 重新计算压缩后图像的大小
compression_count += 1 # 每次压缩增加计数器
print("第 {} 次压缩后图像大小(MB): {}".format(compression_count, img_pil_size))
return img_pil_compressed, compression_count
def process_and_convert_to_base64(img_pil):
img_pil_compressed, compression_count = resize_and_compress_image(img_pil)
img_base64 = pillow_to_base64(img_pil_compressed)
img_pil_size = compute_size_MB(img_pil_compressed)
print("总共压缩了 {} 次".format(compression_count))
return img_base64, img_pil_compressed,img_pil_size
# 将上传的图像转换为PIL Image对象
img_pil = Image.fromarray(img)
img_pil_compressed = img_pil.copy()
img_base64 = pillow_to_base64(img_pil)
# 计算img_pil的大小,添加压缩处理
img_pil_size = compute_size_MB(img_pil)
if img_pil_size > 20:
img_base64,img_pil_compressed,img_pil_size = process_and_convert_to_base64(img_pil)
# 计算img_base64的大小
img_base64_size = len(img_base64) / (1024 * 1024)
print("img_pil大小(MB):", img_pil_size)
print("img_base64大小(MB):", img_base64_size)
# 后续代码 #
输出
===计算图像大小===
===计算图像大小===
第 1 次压缩后图像大小(MB): 6.54071044921875
===计算图像大小===
总共压缩了 1 次
img_pil大小(MB): 6.54071044921875
img_base64大小(MB): 3.7413558959960938
3. 有什么疑问
- 图片转Base64编码后为什么会变大?图片不到1M,转base64后会超过10M吗?
ChatGPT:在绝大多数情况下,
转换成Base64编码后的图片大小会比原始图片的大小增加约1/3左右
。这是因为Base64编码是一种将二进制数据转换为文本数据的方式,而文本数据通常会比二进制数据占用更多的空间。因此,如果原始图片的大小已经接近1MB,那么转换成Base64编码后,其大小可能会超过1MB。
具体来说,如果原始图片大小接近1MB,那么转换成Base64编码后的大小可能会接近1.3MB左右。因此,如果您担心图片大小超过10MB的限制,建议先检查原始图片的大小,以便估算转换后的Base64编码大小。
- 为什么这个大小和电脑上看到的大小不一样?
ChatGPT:计算出来的图像大小是基于图像数据本身的像素数量和颜色通道数的简单估算,并不考虑图像压缩等因素。而在电脑上查看图像时,通常会考虑到图像的压缩方式以及显示器的分辨率等因素,因此会和计算出来的大小有所不同。
电脑上查看图像的大小通常是按照图像的实际分辨率和压缩方式来显示的,而不是以图像文件的字节大小为准。例如,在电脑上查看JPEG格式的图像时,会根据JPEG压缩的质量参数以及显示器的分辨率等因素来调整图像的显示大小,这可能和图像文件的字节大小并不完全一致。
因此,图像在计算机上显示的大小和图像文件的字节大小可能会有所差异,这取决于多种因素,包括图像文件的压缩方式、显示器的分辨率、查看图像的软件等。
- 为什么代码中img_pil大于20M再压缩?
因为观察到img_pil大小 是Base64编码大小 的2倍,Base64编码大小限制为10M,所以在img_pil是20M左右时进行压缩处理。一次压缩把尺寸缩小一半,循环处理,还是大于20M,再缩一次,直到小于20M,才能符合百度OCR的识别条件。
4. 参考文档
【文档参照】百度OCR文字识别 - API文档 - 错误码