Python PIL 字节到图像
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14759637/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Python PIL bytes to Image
提问by
import PIL
from PIL import Image
from PIL import ImageDraw
from PIL import ImageFont
import urllib.request
with urllib.request.urlopen('http://pastebin.ca/raw/2311595') as in_file:
hex_data = in_file.read()
print(hex_data)
img = Image.frombuffer('RGB', (320,240), hex_data) #i have tried fromstring
draw = ImageDraw.Draw(img)
font = ImageFont.truetype("arial.ttf",14)
draw.text((0, 220),"This is a test11",(255,255,0),font=font)
draw = ImageDraw.Draw(img)
img.save("a_test.jpg")
i m trying to convert binary to image,and then draw the text.but i get the error with:
我试图将二进制转换为图像,然后绘制文本。但我收到以下错误:
img = Image.frombuffer('RGB', (320,240), hex_data)
raise ValueError("not enough image data")
ValueError: not enough image data
i have uploaded the bytes string at here http://pastebin.ca/raw/2311595
and the picture size i can sure that is 320x240
我已经在http://pastebin.ca/raw/2311595上传了字节字符串,
我可以确定图片大小是 320x240
ADDITIONAL
额外的
here is what i can sure the picture bytes string are from 320x240,just run the code will create a image from the bytes string
这是我可以确定图片字节字符串来自 320x240,只需运行代码即可从字节字符串创建图像
import urllib.request
import binascii
import struct
# Download the data.
with urllib.request.urlopen('http://pastebin.ca/raw/2311595') as in_file:
hex_data = in_file.read()
# Unhexlify the data.
bin_data = binascii.unhexlify(hex_data)
print(bin_data)
# Remove the embedded lengths.
jpeg_data = bin_data
# Write out the JPEG.
with open('out.jpg', 'wb') as out_file:
out_file.write(jpeg_data)
SOLVED, THIS IS THE CODE UPDATED
已解决,这是更新的代码
from PIL import Image
from PIL import ImageDraw
from PIL import ImageFont
import urllib.request
import io
import binascii
data = urllib.request.urlopen('http://pastebin.ca/raw/2311595').read()
r_data = binascii.unhexlify(data)
#r_data = "".unhexlify(chr(int(b_data[i:i+2],16)) for i in range(0, len(b_data),2))
stream = io.BytesIO(r_data)
img = Image.open(stream)
draw = ImageDraw.Draw(img)
font = ImageFont.truetype("arial.ttf",14)
draw.text((0, 220),"This is a test11",(255,255,0),font=font)
draw = ImageDraw.Draw(img)
img.save("a_test.png")
采纳答案by jsbueno
That image is not formed of raw bytes - rather it is an encoded JPEG file. Moreover, you are not parsing the ascii HEX representation of the stream into proper bytes: that is, an "ff" sequence in that file is being passed to PIL as two c letters "f" instead of a byte with the number 255.
该图像不是由原始字节形成的——而是一个编码的 JPEG 文件。此外,您没有将流的 ascii HEX 表示解析为正确的字节:也就是说,该文件中的“ff”序列作为两个 c 字母“f”而不是数字 255 的字节传递给 PIL。
So, first, you decode the string to a proper byte sequence - sorry for the convolution - it is likely there is a better way to do that, but I am on a slow day:
因此,首先,您将字符串解码为正确的字节序列 - 抱歉卷积 - 很可能有更好的方法来做到这一点,但我今天很慢:
data = urllib.urlopen("http://pastebin.ca/raw/2311595").read()
r_data = "".join(chr(int(data[i:i+2],16)) for i in range(0, len(data),2))
Ah, C.Y. posted on hte comment - this way:
啊,CY 发表在 hte 评论上 - 这样:
>>> import binascii
>>> b_data = binascii.unhexlify(data)
And now, you import it to PIL as a JPEG image:
现在,您将其作为 JPEG 图像导入 PIL:
>>> from PIL import Image
>>> import cStringIO as StringIO
>>> stream = StringIO.StringIO(b_data)
>>> img = Image.open(stream)
>>> img.size
(320, 240)
回答by crifan
as other say, Python 3 better use io.BytesIO
换句话说,Python 3 更好用 io.BytesIO
import io
from PIL import Image
imageFileObj = open(imageFilename, "rb")
imageBinaryBytes = imageFileObj.read()
imageStream = io.BytesIO(imageBinaryBytes)
imageFile = Image.open(imageStream)
print("imageFile.size=%s" % imageFile.size)

