How to read Images from sqlite3 and show via opencv, PIL or Matplot lib ?
(1) By firaki on 2021-10-02 10:49:07
Hi, so i can read the images fine ( In bytes mode), but how can i display them ? How to convert the bytes.? Now one approach is i read the BLOB data and then write the file to hard drive and then load the file and then display it, which can be A lot of overheads. Any other way to do this ? My code: import sqlite3 from PIL import Image import matplotlib.pyplot as plt import cv2 import numpy conn = sqlite3.connect("Sneakers.db") cur = conn.cursor() m = cur.execute(""" SELECT * FROM PRODS """) for x in m: s = cv2.imread(x) plt.imshow(s) plt.show() Error: TypeError: Can't convert object of type 'bytes' to 'str' for 'filename' and When i use PIL to read the SQL query Data, i get the following error ValueError: embedded null byte
(2) By Ryan Smith (cuz) on 2021-10-02 15:07:20 in reply to 1 [link]
I'm afraid SQLite's domain ends at "storing the bytes and giving it back to you". How you use those bytes, to display images, write them to file or supply them as codes to nuclear missiles aimed at the moon, is completely up to you. It's irrelevant to SQLite, quite off-topic here, and most importantly, we have very little thoughts on that and may not be much help. Someone here may even have some valuable input, but your chances of getting good help will be much higher on some programming forum.
(3) By RandomCoder on 2021-10-02 16:37:02 in reply to 1 [link]
As mentioned by Ryan Smith, this is a question that's outside the domain of SQLite. You asked SQLite for bytes, and it gave you bytes back, what you do with those bytes to display them is very much not something SQLite handles. That said, the issue is because you're passing the bytes to a function that expects a filename. If you insist on using OpenCV to decode the image, you need to follow an explicit decode path: ``` for x in m: # Convert the image to a numpy array image = numpy.asarray(bytearray(x), dtype="uint8") # Decode the image to a cv2 image s = cv2.imdecode(image, cv2.IMREAD_COLOR) # Convert the image from cv2's BGR to RGB that matplotlib expects s = cv2.cvtColor(s, cv2.COLOR_BGR2RGB) # s = mpimg.imread(io.BytesIO(x)) plt.imshow(s) plt.show() ``` If the goal is actually to just display the image, it's much easier to just use matplotlib directly instead of taking a detour into OpenCV: ``` import matplotlib.image as mpimg import io for x in m: # Just use matplotlib to decode the image plt.imshow(mpimg.imread(io.BytesIO(x))) plt.show() ```
(4) By Keith Medcalf (kmedcalf) on 2021-10-02 21:35:28 in reply to 1 [link]
The error messages are perfectly explicit about the error **YOU** are committing. In the first case "Can't convert object of type 'bytes' to 'str' for 'filename'" is saying that the parameter you passed which is supposed to contain the 'filename' in text (unicode string) does contain data in the format required. The parameter you passed has type 'bytes' and it must be type 'str', and the 'bytes' that you provided cannot be 'magically converted' into a valid 'str'. In the second case, "ValueError: embedded null byte", means that you passed an argument which must be a string 'str' and therefore cannot contain a null byte (0). However the value you passed was not a valid 'str' because it contained a null (0) byte. THe likely cause is that the API you are calling requires you to present to it "Purple Giraffes" and you have instead presented "Fushia Tigers", although the internal conversion mechanism cannot convert "Fushia Tigers" into "Purple Giraffes". THe proper course of action would be for **you** to read the documentation and find the API which accepts "Fushcia Tigers" and, if that API does what you want, then use it. If there is no API that accepts "Fushia Tigers" and all you have are "Fushia Tigers" then you either need to figure out how to do the conversion yourself, on just give up trying and go have a nice bottle of wine. Your presentation of an incorrect data type is not an SQLite3 issue