如何调整图片满足Telegram API要求,避免PHOTO_INVALID_DIMENSIONS错误
解决Telegram sendPhoto接口的PHOTO_INVALID_DIMENSIONS错误:最小白边调整方案
需求回顾
需要优化图片调整逻辑,仅添加满足Telegram sendPhoto要求的最小白边,同时保证原图画质不压缩、不降低。Telegram的官方要求如下:
- 图片文件大小≤10MB
- 宽高像素总和≤10000
- 宽高比例≤20(即最长边不超过最短边的20倍)
现有方案的问题:
- 固定添加白边到600高度:产生冗余白边,增加不必要的文件体积
- 缩放图片:直接降低原图分辨率,损失画质
核心实现思路
- 先校验原图合规性:如果原图已经满足所有要求,直接输出原图
- 优先修正宽高比:计算让宽高比≤20所需的最小新增边长度,仅增加较短的边
- 修正宽高总和:如果调整比例后宽高总和仍超过10000,逐步增加最小的边,直到总和达标
- 无损合成新图:将原图居中粘贴到新画布,使用最高质量保存
Python示例代码(基于PIL库)
from PIL import Image import os def adjust_image(input_path, output_path, bg_color=(255, 255, 255)): # 先检查文件大小是否超过10MB file_size = os.path.getsize(input_path) if file_size > 10 * 1024 * 1024: raise ValueError("图片文件大小超过10MB,无法通过添加白边解决,请先压缩文件") with Image.open(input_path) as img: original_w, original_h = img.size target_w, target_h = original_w, original_h # 处理宽高比超过20的情况 max_dim = max(original_w, original_h) min_dim = min(original_w, original_h) if max_dim / min_dim > 20: if original_w > original_h: # 宽度过长,计算需要的最小高度 required_h = int(original_w / 20) target_h = max(required_h, original_h) else: # 高度过长,计算需要的最小宽度 required_w = int(original_h / 20) target_w = max(required_w, original_w) # 处理宽高总和超过10000的情况 while (target_w + target_h) > 10000: # 每次增加长度较小的边,保证新增白边最少 if target_w <= target_h: target_w += 1 else: target_h += 1 # 无需调整直接保存 if target_w == original_w and target_h == original_h: img.save(output_path, quality=100) return # 创建新画布,支持透明图(如果是RGBA模式) img_mode = img.mode new_img = Image.new(img_mode, (target_w, target_h), bg_color) # 计算居中粘贴位置 paste_x = (target_w - original_w) // 2 paste_y = (target_h - original_h) // 2 # 粘贴原图并保存 new_img.paste(img, (paste_x, paste_y)) new_img.save(output_path, quality=100)
关键细节说明
- 文件大小检查:开头先判断文件是否超过10MB,因为添加白边会增大体积,这种情况无法通过本方案解决,需提前提示
- 宽高比修正逻辑:只增加较短的边,避免不必要的白边,比如宽是高的25倍时,仅把高度增加到宽的1/20,而不是盲目扩大
- 总和修正逻辑:循环递增最小边,确保每次只加1像素,直到总和达标,保证新增白边最少
- 无损保存:使用
quality=100参数,确保保存后的图片画质与原图一致 - 透明图支持:自动适配原图的颜色模式,如果是PNG透明图,背景色可设为
(255,255,255,0)实现透明白边
内容的提问来源于stack exchange,提问作者Digital Farmer
相关产品推荐
相关产品推荐

