Display Image from Mysql directly to kivy window - python

I have checked out this answer but it does not seem to explain clearly what is happening in order to display images directly from mysql db to a kivy window directly, assuming we already have the blob data from mysql in a variable called loaded_Image.
How can we display loaded_Image into window? {Preferably using a dynamic Image Widget and not from .kv file}
Please help if you have accomplished this before.

I figured this out to the best of my understanding
First load an image in form of blob data using normal mysql python and store in a variable, my case called image, you convert it as below to data then add data to CoreImage
image = value[9]
data = io.BytesIO(image)
img = CoreImage(data, ext="png").texture
Make sure you use this for your import
from kivy.uix.image import Image, CoreImage
Next ensure you add a default image within your project folder and call it using widget as follows
widget = Image(source = 'a.jpg')
Set the texture of widget to img, then add it to your target widget or parent
widget.texture = img
target.add_widget(widget)
The full working code like below:
image = value[9] #Add your data
data = io.BytesIO(image)
img = CoreImage(data, ext="png").texture
widget = Image(source = 'a.jpg')
widget.texture = img
target.add_widget(widget)

Related

TypeError: 'PngImageFile' object is not callable

I am trying to put images into a scrollable frame. These images are stored locally which i am successful in retiring corresponding to their id. However the issue I am running into is that i cant work out how to resize them properly so they fit on the canvas. I am coding in Python 3.10 and using tkinter to create the GUI.
def open_image(location):
photo = Image.open('D:\ShopifyApp\designs\\'+ str(location))
resized = photo((10,5), Image.Resampling.LANCZOS)
image = ImageTk.PhotoImage(resized)
return image
This is the code that fetches the image, location is the name of the file, all the images are JPGs (I dont know if thats the issue).
for i in range(len(orderDF)):
Label(myframe, text = str(orderDF.loc[i]['orderID'])).pack()
prodImg = find_pic(orderDF.loc[i]['productID'])
img = open_image(prodImg)
Label(myframe,image=img).pack()
This is my loop which grabs the image location and sends it to open_image to later be put in label.

Use PNG files from a dictionary to display in a Image widget in PySimpleGUI (Python)

I have Python GUI using PySimpleGUI that needs to display multiple plots which I intend to navigate via a set of buttons. I know I can have all the plots saved as PNG in a given folder and simply load them in a Image object and use the Update method of the element to load a new image when a button is clicked.
Something like the below works well:
[sg.Image(filename=os.getcwd() + pngFileName, key='key1', size=(5, 6))]
where I need to pass a filename of the plot I want to read from my current directory and show in the Image widget.
But this means that I will have all the files saved in a folder while I would rather prefer to have all the PNGs in a dictionary and refer that dictionary when I need to pass a given filename to the sg.Image().
The advantage I see is that this way I don't have to occupy space on the hard drive to store the PNGs and also instead of having to write and then read from disk, I guess it will be faster to get the PNGs directly from the dictionary that is in memory at run time.
I am not able to achieve this as the code seems to expect a filename that has a specific path rather than passing a specific value of a dictionary containing PNGs.
How can I achieve this?
Question: Use PNG files from a dictionary to display in a Image widget in PySimpleGUI (Python)
The class Image is defined as:
class Image(Element):
def __init__(self, filename=None, data=None, ...):
"""
:param filename: (str) image filename if there is a button image.
GIFs and PNGs only.
:param data: Union[bytes, str] Raw or Base64 representation of the image
to put on button.
Choose either filename or data
You can do:
import PySimpleGUI as sg
import os
cwd = os.getcwd()
fname = 'image1.png'
with open('{}/{}'.format(cwd, fname)) as fh:
image1 = fh.read()
[sg.Image(data=image1, key='key1', size=(5, 6))]
Something like this should work (assuming two images:image1, image2):
import PySimpleGUI as sg
# All the stuff inside your window.
layout [
[sg.Image(data=image1, key='__IMAGE__', size=(5, 6))]
]
# Create the Window
window = sg.Window('Window Title', layout)
# Event Loop to process "events" and get the "values" of the inputs
while True:
event, values = window.read()
if event in (None, 'Cancel'): # if user closes window or clicks cancel
break
window.Element('_IMAGE_').Update(data=image2)
window.close()
One of the Demo Programs listed on the PySimpleGUI GitHub is Demo_Img_Viewer.py. In it you'll find a function that takes a filename and returns the data that you can pass to the update method of your Image element.
This function is part of that demo. It will render a file into the format that the update method expects.
from PIL import Image
def get_img_data(f, maxsize=(1200, 850)):
"""
Generate image data using PIL
"""
img = Image.open(f)
img.thumbnail(maxsize)
bio = io.BytesIO()
img.save(bio, format="PNG")
del img
return bio.getvalue()
You can loop through your files and "pre-render" them by calling this function and saving the results.
Then later you can update your image element with one of these pre-rendered images.
window['My Image Element Key'].update(data=rendered)

How to convert widget canvas (texture) to .png without saving it?

I want to be able to do this:
#Reference widget
my_widget = self.ids.my_widget_kv
#Extract texture or graphics
drawing = my_widget.texture (or something that works)
#TODO convert to drawing .png in binary
#TODO edit in PIL
TODO save or attach to email
At the moment I get my_widget.texture as None, and my_widget.canvas as canvas object.
I want to extract widgets looks as is and convert it to .png to attach to email or edit.
timestr = time.strftime("%Y%m%d_%H%M%S")
self.ids.export_to_png("IMG_{}.png".format(timestr))
This code saves drawing_zone looks to storage. I can't edit it in some in between steps.
If you just open and read the PNG file you'll get the bytes which you can then manipulate to your liking.
canvas_png = open("IMG.png","r+b").read()
canvas_data = (canvas_png.getvalue())
print(canvas_data)
You should see the 'binary' you need stored in this variable.

tkinter not displaying barcode image?

I'm using this python module called code128 that generates images of barcodes in code 128 barcode format.
The module works fine alone and produces the barcode desired. But now I'm trying to integrate it with tkinter and get tkinter to display it in a window but with no luck.
Tkinter just shows a black rectangle that would otherwise be the whole barcode. I'm not at all familiar with tkinter, but managed to borrow some functional code, but for some reason this barcode thing isn't working.
import tkinter as tk
from PIL import ImageTk, Image
import code128
#This creates the main window of an application
window = tk.Tk()
window.title("barcode test")
window.geometry("800x600")
#window.configure(background='grey')
#create a barcode image
barcode = code128.image('EL123456789US')
#barcode.show() #for testing purposes. the barcode is generated
#Creates a Tkinter-compatible photo image, which can be used everywhere Tkinter expects an image object.
img = ImageTk.PhotoImage(barcode)
#The Label widget is a standard Tkinter widget used to display a text or image on the screen.
label = tk.Label(window, image = img)
label.image = img #keep a reference!
#The Pack geometry manager packs widgets in rows or columns.
label.pack(side = "bottom", fill = "both", expand = "yes")
#Start the GUI
window.mainloop()
I could just save the barcode to disk and load it from disk (it does work as I've already tried it) but I'm trying to avoid that as I need to display many barcodes one after another. Saving and reading from disk would be too costly.
Any help would be greatly appreciated. Thank you.

Can you display an image inside of a python program (without using pygame)?

I want to do something like:
import image
image.display_image('http://upload.wikimedia.org/wikipedia/commons/8/84/Example.svg')
And it would come out as an image.
P.S. I want PNG or JPEG, not GIFs.
This question is somewhat old, but as info on how to do this easily isn't easy to find online, I'm posting this answer in hope it can be useful to others in the future.
To raster a SVG and put it into a ImageTk.PhotoImage object you can do this inside a class used for a tkinter gui:
def svgPhotoImage(self,file_path_name):
import Image,ImageTk,rsvg,cairo
"Returns a ImageTk.PhotoImage object represeting the svg file"
# Based on pygame.org/wiki/CairoPygame and http://bit.ly/1hnpYZY
svg = rsvg.Handle(file=file_path_name)
width, height = svg.get_dimension_data()[:2]
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, int(width), int(height))
context = cairo.Context(surface)
#context.set_antialias(cairo.ANTIALIAS_SUBPIXEL)
svg.render_cairo(context)
tk_image=ImageTk.PhotoImage('RGBA')
image=Image.frombuffer('RGBA',(width,height),surface.get_data(),'raw','BGRA',0,1)
tk_image.paste(image)
return(tk_image)
Then display the image on a Frame widget (e.g. mainFrame) this way:
tk_image=self.svgPhotoImage(filename)
mainFrame.configure(image=tk_image)
If you want to save the picture you can return image instead of tk_image and save it this way:
image.save(filename) # Image format is autodected via filename extension

Categories