英文:
How to adjust the image to meet the minimum requirements and avoid receiving the Telegram API Bad Request error: PHOTO_INVALID_DIMENSIONS?
问题
以下是翻译好的部分:
"Summary: Telegram has requirements for images that are sent, and to avoid failures, I add huge white borders far above what would be the minimum necessary. I would like to know how I could create a method so that the image is adjusted at once but with the minimum borders required.
According to the documentation I couldn't understand exactly how I could reach that value, here it is sendPhoto
:
Photo to send. Pass a file_id as a String to send a photo that exists
on the Telegram servers (recommended), pass an HTTP URL as a String
for Telegram to get a photo from the Internet, or upload a new photo
using multipart/form-data. The photo must be at most 10 MB in size.
The photo's width and height must not exceed 10000 in total. Width and
height ratio must be at most 20.
My sample code creates this image that generates an error when sending it to Telegram because it does not meet the minimum requirements:
Currently, the code adds borders above and below a size that I know works, and it looks like this:
def create_image():
df = pd.DataFrame(columns=[f"column_letter_{chr(97 + i)}" for i in range(9)])
dfi.export(df, 'telegram_image.png', table_conversion='selenium', max_rows=-1)
def adjust_image():
fil_img = Image.open('telegram_image.png')
min_img = 600
difference = min_img - fil_img.size[1]
new_image = Image.new('RGB', (fil_img.size[0], min_img), (255, 255, 255))
new_image.paste(fil_img, (0, difference // 2))
new_image.save('telegram_image.png')
In this additional method I tried, the problem is that the image shrinks and thus the quality also decreases, I don't want the quality to decrease at all, I just want to adjust the edges so that it maintains the original size of the image but fits the minimum necessary proportion:
def adjust_image():
image = Image.open('telegram_image.png')
width, height = image.size
if width / height > 20 or height / width > 20:
new_width = min(width, height * 20)
new_height = min(height, width * 20)
image = image.resize((new_width, new_height), Image.ANTIALIAS)
image.save('telegram_image.png', quality=100, subsampling=0)
How would it be possible to create an image adjustment that is not fixed to a specific number of borders to add, and instead adds only the minimum amount necessary?"
完整的代码部分没有被提及,如果需要进一步翻译,请提供特定的代码段。
英文:
Summary: Telegram has requirements for images that are sent, and to avoid failures, I add huge white borders far above what would be the minimum necessary. I would like to know how I could create a method so that the image is adjusted at once but with the minimum borders required.
According to the documentation I couldn't understand exactly how I could reach that value, here it is sendPhoto
:
> Photo to send. Pass a file_id as a String to send a photo that exists
> on the Telegram servers (recommended), pass an HTTP URL as a String
> for Telegram to get a photo from the Internet, or upload a new photo
> using multipart/form-data. The photo must be at most 10 MB in size.
> The photo's width and height must not exceed 10000 in total. Width and
> height ratio must be at most 20.
My sample code creates this image that generates an error when sending it to Telegram because it does not meet the minimum requirements:
Currently, the code adds borders above and below a size that I know works, and it looks like this:
def create_image():
df = pd.DataFrame(columns=[f"column_letter_{chr(97 + i)}" for i in range(9)])
dfi.export(df, 'telegram_image.png', table_conversion="selenium", max_rows=-1)
def adjust_image():
fil_img = Image.open("telegram_image.png")
min_img = 600
difference = min_img - fil_img.size[1]
new_image = Image.new("RGB", (fil_img.size[0], min_img), (255, 255, 255))
new_image.paste(fil_img, (0, difference // 2))
new_image.save("telegram_image.png")
In this additional method I tried, the problem is that the image shrinks and thus the quality also decreases, I don't want the quality to decrease at all, I just want to adjust the edges so that it maintains the original size of the image but fits the minimum necessary proportion:
def adjust_image():
image = Image.open('telegram_image.png')
width, height = image.size
if width / height > 20 or height / width > 20:
new_width = min(width, height * 20)
new_height = min(height, width * 20)
image = image.resize((new_width, new_height), Image.ANTIALIAS)
image.save('telegram_image.png', quality=100, subsampling=0)
How would it be possible to create an image adjustment that is not fixed to a specific number of borders to add, and instead adds only the minimum amount necessary?
Complete Code:
import dataframe_image as dfi
from PIL import Image
import pandas as pd
import requests
import json
def send_image_telegram(ids_chat, bot_token, text_msg, file_photo, buttons=None, parse_mode=None):
if not isinstance(ids_chat, list):
ids_chat = [ids_chat]
list_for_return = []
for chat_id in ids_chat:
telegram_api_url = f'https://api.telegram.org/bot{bot_token}/sendPhoto'
message_data = {
"chat_id": chat_id,
"caption": text_msg
}
if parse_mode is not None:
message_data['parse_mode'] = parse_mode
if buttons is not None:
message_data['reply_markup'] = json.dumps({'inline_keyboard': buttons})
with open(file_photo, "rb") as imageFile:
response = requests.post(telegram_api_url, files={"photo": imageFile}, data=message_data)
list_for_return.append(json.loads(response.text))
return list_for_return
def create_image():
df = pd.DataFrame(columns=[f"column_letter_{chr(97 + i)}" for i in range(9)])
dfi.export(df, 'telegram_image.png', table_conversion="selenium", max_rows=-1)
def adjust_image():
fil_img = Image.open("telegram_image.png")
min_img = 600
difference = min_img - fil_img.size[1]
new_image = Image.new("RGB", (fil_img.size[0], min_img), (255, 255, 255))
new_image.paste(fil_img, (0, difference // 2))
new_image.save("telegram_image.png")
def to_telegram():
send = send_image_telegram('123456789','XXXXXXXXXX','test','telegram_image.png')
if not send[0]['ok'] and send[0]['description'] == 'Bad Request: PHOTO_INVALID_DIMENSIONS':
adjust_image()
send_image_telegram('123456789','XXXXXXXXXX','test','telegram_image.png')
def main():
create_image()
to_telegram()
if __name__ == '__main__':
main()
答案1
得分: 1
我理解你的请求。以下是代码部分的中文翻译:
我不使用Telegram,并且不确定我是否完全理解你的问题,但简而言之,似乎你想要使一个1157x23的图像满足一个小于20的宽高比。如果你通过调整大小来实现这一点,会使图像失真,所以我建议你通过填充来实现 - 我用品红色来示范我添加了什么:
#!/usr/bin/env python3
from math import ceil
from PIL import Image
# 打开原始图像并获取其大小
im = Image.open('7r8q3.png')
w, h = im.size
# 计算新大小以满足1:20的宽高比
newH = ceil(w/20)
# 创建新图像的背景
padded = Image.new('RGB', (w,newH), 'magenta')
# 将现有图像粘贴到新图像的垂直中点
padded.paste(im, (0,int((newH-h)/2)))
padded.save('result.jpg')
新图像的尺寸为1157x58,宽高比为19.95:1。一旦你理解了我的建议,显然你可以将品红色更改为你喜欢的任何其他颜色。
英文:
I don't use Telegram and am not 100% sure I understand your question, but in a nutshell it seems you want to make a 1157x23 image comply with having an aspect ratio less than 20. If you do that by resizing, you will distort the image, so I am suggesting you do it by padding instead - I'm doing it in magenta so you can see what I have added:
#!/usr/bin/env python3
from math import ceil
from PIL import Image
# Open original image and get its size
im = Image.open('7r8q3.png')
w, h = im.size
# Calculate new size to comply with a 1:20 aspect ratio
newH = ceil(w/20)
# Create background of new image
padded = Image.new('RGB', (w,newH), 'magenta')
# Paste existing image into new one at vertical midpoint
padded.paste(im, (0,int((newH-h)/2)))
padded.save('result.jpg')
The new image has size 1157x58, which is an aspect ratio of 19.95:1. Obviously you can change the magenta to any other colour you like once you have understood my suggestion.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论