pil open imagedraw convert python image binary python-imaging-library drawtext

open - Python PIL bytes a la imagen



pillow import image (2)

Como otros dicen, Python 3 usa mejor 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)

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")

Estoy intentando convertir el binario en una imagen y luego dibujar el texto. Pero me aparece el error con:

img = Image.frombuffer(''RGB'', (320,240), hex_data) raise ValueError("not enough image data") ValueError: not enough image data

He subido la cadena de bytes aquí http://pastebin.ca/raw/2311595
y el tamaño de la imagen puedo estar seguro de que es 320x240

ADICIONAL

Esto es lo que puedo asegurar de que la cadena de bytes de la imagen sea de 320x240, simplemente ejecute el código para crear una imagen de la cadena de bytes

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)

RESUELTO, ESTE ES EL CÓDIGO ACTUALIZADO

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")


Esa imagen no está formada por bytes en bruto, sino que es un archivo JPEG codificado. Además, no está analizando la representación HEX de ascii de la secuencia en bytes adecuados: es decir, una secuencia "ff" en ese archivo se pasa a PIL como dos letras c "f" en lugar de un byte con el número 255.

Entonces, primero, decodifica la cadena a una secuencia de bytes adecuada, perdón por la convolución, es probable que haya una mejor manera de hacerlo, pero estoy en un día lento:

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, CY publicó en su comentario, de esta manera:

>>> import binascii >>> b_data = binascii.unhexlify(data)

Y ahora, lo importas a PIL como una imagen JPEG:

>>> from PIL import Image >>> import cStringIO as StringIO >>> stream = StringIO.StringIO(b_data) >>> img = Image.open(stream) >>> img.size (320, 240)