使用python3.7.3,我希望有base64编码的照片,并调整它的大小,而不保存到文件到磁盘,并重新打开文件使用Image.open打开()

2024-04-24 19:17:14 发布

您现在位置:Python中文网/ 问答频道 /正文

很抱歉提前发了这么长的邮件。你知道吗

使用python3.7.3,我希望有base64编码的照片,并调整它的大小,而不保存到文件到磁盘,并重新打开文件使用Image.open打开(). 你知道吗

我从This answer开始研究PyPng,它似乎直接使用base64数据,但我不知道如何将其调整为PIL图像。我知道如何调整它的大小,一旦它是一个枕头图像,我需要弄清楚的是如何从base64直接到枕头图像。你知道吗

# import tkinter as tk, png
# from PIL import Image, ImageTk
# ... self.PIC_LABEL is a tk.Label() object.
def ShowImage(self, PhotoData=None):
    try:
        tempImg = png.Reader(bytes=PhotoData)
        img = Image.open(tempImg)
        # ... resizing code is working ...
        self.PIC_LABEL.IMG = tk.PhotoImage(img)
        self.PIC_LABEL.configure(image=self.PIC_LABEL.IMG)
    except Exception as e:
        logger.exception(e)

错误是:

FormatError: PNG file has invalid signature. 
Traceback (most recent call last):
    File "C:\Program Files\Python37\lib\site-packages\PIL\Image.py", line 2774, in open
        fp.seek(0) 
AttributeError: 'Reader' object has no attribute 'seek'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
   File "D:/test.py", line 911, in ShowImage    
       img = Image.open(tempImg)
   File "C:\Program Files\Python37\lib\site-packages\PIL\Image.py", line 2776, in open
       fp = io.BytesIO(fp.read())   
   File "C:\Program Files\Python37\lib\site-packages\png.py", line 1813, in read
       self.preamble(lenient=lenient)
   File "C:\Program Files\Python37\lib\site-packages\png.py", line 1609, in preamble
       self.validate_signature()
   File "C:\Program Files\Python37\lib\site-packages\png.py", line 1595, in validate_signature
       raise FormatError("PNG file has invalid signature.") 
png.FormatError: FormatError: PNG file has invalid signature.

我也试过Image.open(base64.decodebytes(PhotoByteDataDict[name])),但它给出了一个“无效的起始字节错误”。你知道吗

更新:我尝试了基于this answer的其他方法:

rawDefect = PhotoByteData['defect']
msg = base64.b64decode(rawDefect)  # base64.decodebytes(rawDefect) doesn't work either.
buf = io.BytesIO(msg)
tempImg = Image.open(buf)
size = tempImg.size
size = (size[0]*2, size[1]*2)
tempImg = tempImg.resize(size)
print(tempImg)
newImg = tk.PhotoImage(tempImg)
lbl.configure(image=newImg)

这使我能够成功地创建枕头图像和tk.PhotoImage公司但当您尝试显示它时崩溃:

Traceback (most recent call last):
  File "D:/OneDrive/WorkSpace/PyCharm WorkSpace/TruePad/DEV/DevTest.py", line 2907, in <module>
<PIL.Image.Image image mode=RGBA size=480x270 at 0x26DBB5DCDD8>
    lbl.configure(image=newImg)
  File "C:\Program Files\Python37\lib\tkinter\__init__.py", line 1485, in configure
    return self._configure('configure', cnf, kw)
  File "C:\Program Files\Python37\lib\tkinter\__init__.py", line 1476, in _configure
    self.tk.call(_flatten((self._w, cmd)) + self._options(cnf))
TypeError: __str__ returned non-string (type Image)

也累了之后,看了源代码tk.PhotoImage公司地址:

tkDefect = tk.PhotoImage(data=rawDefect)
newHeight = 480 / tkDefect.height()
newWidth = 800 / tkDefect.width()
newSize = (newWidth, newHeight)
newImg = tkDefect.zoom(int(newWidth * tkDefect.width()), int(newHeight * tkDefect.height()))
lbl.configure(image=newImg)

但在尝试显示时再次崩溃,出现不同的错误:

Traceback (most recent call last):
  File "Test.py", line 2919, in <module>
    newImg = tkDefect.zoom(int(newWidth * tkDefect.width()), int(newHeight * tkDefect.height()))
  File "C:\Program Files\Python37\lib\tkinter\__init__.py", line 3568, in zoom
    self.tk.call(destImage, 'copy', self.name, '-zoom',x,y)
_tkinter.TclError: not enough free memory for image buffer

有什么想法吗?


Tags: inpyimageselfconfigureliblinefiles
1条回答
网友
1楼 · 发布于 2024-04-24 19:17:14

找到答案要感谢这个Post,它让我找到了ImageTk.PhotoImage

msg = base64.b64decode(rawDefect)
with io.BytesIO(msg) as buf:
    with Image.open(buf) as tempImg:
        newWidth = 400 / tempImg.width  # change this to what ever width you need.
        newHeight = 240 / tempImg.height # change this to what ever height you need.
        newSize = (int(newWidth * tempImg.width), int(newHeight * tempImg.height))
        newImg1 = tempImg.resize(newSize)
        lbl1.IMG = ImageTk.PhotoImage(image=newImg1)
        lbl1.configure(image=lbl1.IMG)

        newWidth = 400 / tempImg.width  # change this to what ever width you need.
        newHeight = 240 / tempImg.height # change this to what ever height you need.
        newSize = (int(newWidth * tempImg.width), int(newHeight * tempImg.height))
        newImg2 = tempImg.resize(newSize)
        lbl2.IMG = ImageTk.PhotoImage(image=newImg2)
        lbl2.configure(image=lbl2.IMG)

相关问题 更多 >