gpt4 book ai didi

python - 如何将使用 PIL/pillow 创建的嵌入图像作为电子邮件发送 (Python 3)

转载 作者:行者123 更新时间:2023-11-28 22:44:10 24 4
gpt4 key购买 nike

我正在创建要嵌入到电子邮件中的图像。我无法弄清楚如何将图像创建为二进制文件并传递给 MIMEImage。下面是我的代码,当我尝试读取图像对象时出现错误 - 错误是“AttributeError:‘NoneType’对象没有属性‘read’”。

image=Image.new("RGBA",(300,400),(255,255,255))
image_base=ImageDraw.Draw(image)
emailed_password_pic=image_base.text((150,200),emailed_password,(0,0,0))
imgObj=emailed_password_pic.read()
msg=MIMEMultipart()
html="""<p>Please finish registration <br/><img src="cid:image.jpg"></p>"""
img_file='image.jpg'
msgText = MIMEText(html,'html')
msgImg=MIMEImage(imgObj)
msgImg.add_header('Content-ID',img_file)
msg.attach(msgImg)
msg.attach(msgText)

如果您查看第 4 行 - 我正在尝试读取图像,以便将其传递到 MIMEImage。显然,图像需要以二进制形式读取。但是,我不知道如何将它转换为二进制文件以便 .read() 可以处理它。

跟进我根据 jsbueno 的建议编辑了代码 - 非常感谢!!!:

  emailed_password=os.urandom(16)
image=Image.new("RGBA",(300,400),(255,255,255))
image_base=ImageDraw.Draw(image)
emailed_password_pic=image_base.text((150,200),emailed_password,(0,0,0))
stream_bytes=BytesIO()
image.save(stream_bytes,format='png')
stream_bytes.seek(0)
#in_memory_file=stream_bytes.getvalue()
#imgObj=in_memory_file.read()
imgObj=stream_bytes.read()
msg=MIMEMultipart()
sender='xxx@abc.com'
receiver='jjjj@gmail.com'
subject_header='Please use code provided in this e-mail to confirm your subscription.'
msg["To"]=receiver
msg["From"]=sender
msg["Subject"]=subject_header
html="""<p>Please finish registration by loging into your account and typing in code from this e-mail.<br/><img src="cid:image.png"></p>"""
img_file='image.png'
msgText=MIMEText(html,'html')
msgImg=MIMEImage(imgObj) #Is mistake here?
msgImg.add_header('Content-ID',img_file)
msg.attach(msgImg)
msg.attach(msgText)
smtpObj=smtplib.SMTP('smtp.mandrillapp.com', 587)
smtpObj.login(userName,userPassword)
smtpObj.sendmail(sender,receiver,msg.as_string())

我现在没有收到错误,但电子邮件中没有图像。我对图像在 html/电子邮件部分中的附加方式和相关方式感到困惑。感谢您的帮助!

更新:此代码确实有效 - 我只是在我的 PC 上的代码中出现了一些小错误。

最佳答案

这里存在一些概念性错误,无论是在使用 PIL 方面,还是在图像应该采用何种格式以便合并到电子邮件中。

在 PIL 中:ImageDraw 类就地操作,不像 Image 类调用,后者通常在每次操作后返回一个新图像。在您的代码中,这意味着对 image_base.text 的调用实际上是在更改位于您的 image 变量中的对象的像素数据。此调用实际上返回 None 并且上面的代码应该在下一行中引发类似“AttributeError:None object does not have attribute 'read'”的错误。

之后(也就是说,您应该从 image 变量中获取数据以将其附加到电子邮件中)是第二个问题:PIL,出于显而易见的原因,将图像放在未压缩的格式中, 内存中的原始像素数据格式。在电子邮件中附加图像时,我们通常希望将图像整齐地打包在文件中 - PNG 或 JPG 格式通常更好,具体取决于意图 - 让我们继续使用 .PNG。因此,您必须使用 PIL 创建文件数据,并附加文件数据(即构成 PNG 文件的数据,包括标题、元数据和压缩形式的实际像素数据)。否则你会在你的电子邮件中放入一堆(未压缩的)像素数据,接收方无法将这些数据组合回图像(即使他将数据视为像素,原始像素数据不包含图像形状如此-)

您有两个选择:要么在内存中生成文件字节,要么将它们写入磁盘中的实际文件,然后重新读取该文件以进行附加。第二种形式更容易理解。第一个既更有效率又是“正确的做法”——所以让我们保留它:

from io import BytesIO
# In Python 2.x:
# from StringIO import StringIO.StringIO as BytesIO

image=Image.new("RGBA",(300,400),(255,255,255))
image_base=ImageDraw.Draw(image)
# this actually modifies "image"
emailed_password_pic=image_base.text((150,200),emailed_password,(0,0,0))
stream = BytesIO()
image.save(stream, format="png")
stream.seek(0)
imgObj=stream.read()
...

(注意:我没有检查您的代码中处理邮件和 mime 的部分 - 如果您正确使用它,它现在应该可以工作)

关于python - 如何将使用 PIL/pillow 创建的嵌入图像作为电子邮件发送 (Python 3),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29886839/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com