I have a Gtk.Image object and I want to convert it's data to a base64 encoded string (for use with imgur). How would I achieve that?
Has to run it through a gdk.pixbuf, but this seems the easiest:
import cStringIO
import base64
pixBuf = gtkImage.get_pixbuf()
fH = cStringIO.StringIO()
pixBuf.save_to_callback(fH.write, "png")
encodedBuffer = base64.b64encode(fH.getvalue()) #base64 encoded png
Related
What is the way to get file type from base64 string?
I need a solution which will work on Windows and Linux(Centos7)
E.G.: This is string ; eHh4eHh4 which is = to a text file with xxxxxx inside.
If websites can do this, I guess it is possible to do it in python:
https://base64.guru/converter/decode/file
What I have tried:
using magic
using imghdr
You could write the base64 content into BytesIO:
import base64
import magic # https://pypi.org/project/python-magic/
import io
data = 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+P+/HgAFhAJ/wlseKgAAAABJRU5ErkJggg=='
bytesData = io.BytesIO()
bytesData.write(base64.b64decode(data))
bytesData.seek(0) # Jump to the beginning of the file-like interface to read all content!
print(magic.from_buffer(bytesData.read()))
Out:
PNG image data, 1 x 1, 8-bit/color RGBA, non-interlaced
I have an image buffer returned from a C SDK,
I can write to a local image and read it as base64 string but this requires an extra step.
How can I turn the byte array into a base64 string directly so that I can send it in a network request?
image = (ctypes.c_ubyte*s.dwDataLen)()
ctypes.memmove(image, s.pBuffer, s.dwDataLen)
I tried using base64.encodestring but got this error
TypeError: expected single byte elements, not '<B' from c_ubyte_Array_8716
you can use base64 module
import base64
with open("yourfile.ext", "rb") as image_file:
encoded_string = base64.b64encode(image_file.read())
the case is similar with Encoding an image file with base64
Try this:
import ctypes
import base64
image = (ctypes.c_ubyte * s.dwDataLen)()
ctypes.memmove(image, s.pBuffer, s.dwDataLen)
# Convert the image to an array of bytes
buffer = bytearray(image)
encoded = base64.encodebytes(buffer)
If you are using base64.b64encode, you should be able to pass image to it:
import ctypes
import base64
image = (ctypes.c_ubyte * s.dwDataLen)()
ctypes.memmove(image, s.pBuffer, s.dwDataLen)
encoded = base64.b64encode(image)
The main problem is that, from what I could find, there is no easy/documented way to load an image from base64 encoded image. I use the following code to encode the image to base64 (so that I wouldn't need to include all the images with the source, nor should I create temp files and delete them at exit). The image format I use is .png which is supported in Gtk3+. (from GdkPixbuf.Pixbuf.get_formats() i have ['png'] in the results. I am really confused on how to use Gtk3+ for this purpose.
import base64
image_name = 'image.png'
image_loc = 'd:\\Home\\' + image_name
with open(image_loc, 'rb') as image_file:
encoded_string = base64.b64encode(image_file.read())
print(encoded_string)
I want to use the output for example:
base64_data="""
iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAABsklEQVRYhe2XIVMCQRSAv2AwGAgEAuFmJBiMFmcMBH8AgUAgXHDMFww2gtFA
IBicsRgNBgLBcS7yE4gEIsFgIBDO8Pa8x7FwB7cnxTfzyr637327b+/dLiTSBIbAHIgydAGMgAscyUOOpDZdAu2iyZsq4BcwAHpb9NE1xFAl
P8s558klRFzzwQ5zejgsRxygVxBgbwiXAHtBuAaIIa7KBAgyACJgBlTKAqgBH8A0pWmIXKXYB2CbdFRM/xAA3qEBKipm8A9wCIAa8q/oUOJn
6FTKAqgA10gZWkD9rwAugRfWm1IEfCKlKQ2ghdwrstp0vwyAuiX5HGnRMwtE1zVAfLPS6hubZ7HNgaorgFPkppxOEvcBG0AE3LoCuGZ1Zb7R
hrGfqLGJ8h24ArhTcaYZvqHyDV0BtFWcGbLlHrJygCM1Nla+r5Cc0OcCAA3sNfaN3dtgDwDeSO5xzQIQthvRNoAlcA7yGFmowTFSmzz6jmwv
rL6wYp0Yv7HFttKMusC3xSmP3qs4/ZxzJiTn41c85N032mEHQqQBHacWs+mFvTSQa8ldSxW4Qb7zEDntAabmWn4A0clKl9nNvDwAAAAASUVO
RK5CYII
"""
And render the image from base64.
As a side note, on tkinter this was easily done with:
tkinter.PhotoImage(data=base64_data)
And then display the image where you needed it.
Getting back to Gtk3+, I didn't find a method of loading the image from base64. Even with GdkPixbuf.Pixbuf.new_from_data, I get a broken image. I have also tried with Gio.MemoryInputStream.new_from_bytes, but it says that the format of the image isn't supported.
Your data is base64 encoded, in order for Gtk3+ to use it, you must first decode it:
import base64
raw_data = base64.b64decode(data)
Then you were right with GdkPixbuf.Pixbuf.new_from_data:
(I cannot test, but I think this may work)
import base64
raw_data = base64.b64decode(data)
image = GdkPixbuf.Pixbuf.new_from_data(raw_data)
image_show_2.set_from_pixbuf(image)
Else you can do as you showed:
import base64
raw_data = base64.b64decode(data)
byting = GLib.Bytes(raw_data)
inputing = Gio.MemoryInputStream.new_from_bytes(byting)
image = GdkPixbuf.Pixbuf.new_from_data(inputing)
image_show_2.set_from_pixbuf(image)
Is it possible to generate a functional image tag in html from a BytesIO buffer? I'd like to do something along these lines:
import matplotlib
matplotlib.use('Agg')
import pylab
import Image
import io
temp_data = {'x':[1,2,3],'y':[2,4,5]}
pylab.plot(temp_data['x'], temp_data['y'])
img_buffer = io.BytesIO()
pylab.savefig(img_buffer, format = 'png')
img_buffer.seek(0)
img_tag = "<img src='data:image/png;base64,'" + img_buffer.getvalue() + "</img>"
May be necessary to re-format the value of the buffer in some way, or to change the content of the 'src' data. Thank you.
Python2
Towards the end of the code above, do this
import base64
img_tag = "<img src='data:image/png;base64," + base64.b64encode(img_buffer.getvalue()) + "'/>"
Python3
For this to work in python3 you will need to decode the bytes variable generated from base64.b64encode using str.decode method into a string as follows
import base64
str_equivalent_image = base64.b64encode(img_buffer.getvalue()).decode()
img_tag = "<img src='data:image/png;base64," + str_equivalent_image + "'/>"
If you are working with Flask, then you can return the UTF-8 format of the image and play with it.
figfile = BytesIO()
plt.savefig(figfile, format='png')
plt.clf() # this will clear the image
figfile.seek(0)
figdata_png = base64.b64encode(figfile.getvalue())
return figdata_png.decode('UTF-8')
Remember to mention it in <img/> tags. This is to implement in Flask.
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)
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",(0,255,0),font=font)
draw = ImageDraw.Draw(img)
with open(img,'rb') as in_file: #error on here invalid file:
hex_data = in_file.read()
# Unhexlify the data.
bin_data = binascii.unhexlify(bytes(hex_data))
print(bin_data)
Question
converting hex to image and draw a text on the image, after that convert image to binary hex,but having the problem at here with open(img,'rb') as in_file:, how to convert img to hex?
The img object needs to be saved again; write it to another BytesIO object:
output = io.BytesIO()
img.save(output, format='JPEG')
then get the written data with the .getvalue() method:
hex_data = output.getvalue()
The PIL-for-python-3 landscape is rather muddled at the moment. The Pillow fork looks to be the best, maintained version out there at the moment. It includes fixes that make saving to a BytesIO object work. If you run into a io.UnsupportedOperation: fileno exception using the above code, you have a version that was not yet fixed, in which case you'll have to resort to using a temporary file instead.