Python: Alternate way to covert from base64 string to opencv - python

I'm trying to convert this string in base64 (http://pastebin.com/uz4ta0RL) to something usable by OpenCV.
Currently I am using this code (img_temp is the string) to use the OpenCV functions by converting it to a temp image(imagetosave.jpg) then loading the temp image with cv2.imread.
fh = open('imagetosave.jpg','wb')
fh.write(img_temp.decode('base64'))
fh.close()
img = cv2.imread('imagetosave.jpg',-1)
Though this method works, I would like to be able to use the OpenCV functions without using a temp image.
Help would be much appreciated, thanks!

To convert string from base64 to normal you can use
import base64
base64.b64decode("TGlrZSB0aGF0Cg==")
but it itsn't unclear if is what you need.

You can convert your decoded string to a list of integers, which you can then pass to the imdecode function:
img_array = map(int, img_temp.decode('base64'))
img = cv2.imdecode(img_array, -1)

Related

Cannot convert base64 string into image

Can someone help me turn this base64 data into image? I don't know if it's because the data was not decoded properly or anything else. Here is how I decoded the data:
import base64
c_data = { the data in the link (string type) }
c_decoded = base64.b64decode(c_data)
But it gave the error Incorrect Padding so I followed some tutorials and tried different ways to decode the data.
c_decoded = base64.b64decode(c_data + '=' * (-len(c_data) % 4))
c_decoded = base64.b64decode(c_data + '=' * ((4 - len(c_data) % 4) % 4)
Both ways decoded the data without giving the error Incorrect Padding but now I can't turn the decoded data into image.
I have tried creating an empty png then write the decoded data into it:
from PIL import Image
with open('c.png', 'wb') as f:
f.write(c_decoded)
image = Image.open('c.png')
image.show()
It didn't work and gave the error: cannot identify image file 'c.png'
I have tried using BytesIO:
from PIL import Image
import io
from io import BytesIO
image = Image.open(io.BytesIO(c_decoded))
image.show()
Now it gave the error: cannot identify image file <_io.BytesIO object at 0x0000024082B20270>
Please help me.
Not sure if you definitely need a Python solution, or you just want help decoding your image like the first line of your question says, and you thought Python might be needed.
If the latter, you can just use ImageMagick in the Terminal:
cat YOURFILE.TXT | magick inline:- result.png
Or equivalently and avoiding "Useless Use of cat":
magick inline:- result.png < YOURFILE.TXT
If the former, you can use something like this (untested):
from urllib import request
with request.urlopen('data:image/png;base64,iVBORw0...') as response:
im = response.read()
Now im contains a PNG-encoded [^1] image, so you can either save to disk as such:
with open('result.png','wb') as f:
f.write(im)
Or, you can wrap it in a BytesIO and open into a PIL Image:
from io import BytesIO
from PIL import Image
pilImage = Image.open(BytesIO(im))
[^1]: Note that I have blindly assumed it is a PNG, it may be JPEG, so you should ideally look at the start of the DataURI to determine a suitable extension for saving your file.
Credit to #jps for explaining why my code didn't work. Check out #Mark Setchell solution for the reliable way of decoding base64 data (his code fixes my mistake that #jps pointed out)
So basically remove the [data:image/png;base64,] at the beginning of the base64 string because it is just the format of the data.
Change this:
c = "data:image/png;base64,iVBORw0KGgoAAAANSUh..."
to this:
c = "iVBORw0KGgoAAAANSUh..."
and now we can use
c_decoded = base64.b64decode(c)

How to imencode (cv2 Python) a UIImage in Swift?

In python, you can convert a NumPy array image into a string using the following code:
image = cv2.imread("image.jpg")
encoded = cv2.imencode('.jpg', image)[1]
str_image = base64.b64encode(encoded).decode()
I need the swift version to be just like this because it is short and efficient.
So, in swift I have written this so far:
let image = UIImage(named: "image.jpg")!
let imageData = image.jpegData(compressionQuality: 1)!
let imageString = imageData.base64EncodedString()
In the end, both of them are base64 encoded correctly but for some reason, the swift version is always a lot larger.
My question is that is there a swift equivalent to the python code that turns an image into the exact same string?
If there is please provide the code, thank you.

What is the best way to open an image with the use of OpenCV imread function and both Unicode and ASCII path?

I've run into the problem that currently it is not possible to open Unicode path via OpenCV (4.1.1.26) in python 3.7. I'm trying to develop the best practice to do that.
When the path contains Unicode we should use something described here (u'D:\ö\handschuh.jpg' or '测试目录/test.jpg').
The first thing that I've tried to find is how to detect if a string contains Unicode. As I found here - all strings in python 3 are in Unicode.
For now, I'm using such workaround:
import numpy as np
import cv2
def read(impath, flag=-1):
try:
image = cv2.imread(impath, flag)
assert image is not None, ("Image is {im} check the path {path}".format (im=image, path=impath))
except :
image = cv2.imdecode(np.fromfile(impath, dtype=np.uint8), cv2.IMREAD_UNCHANGED)
assert image is not None, ("Image is {im} check the path {path}".format(im=image, path=impath))
return image
That is obviously not the best way to do that as you should never use try\except pattern.
What are the suggestions?

How to convert from numpy array to file byte object?

I read an image file as
with open('abc.jpg', 'rb') as f:
a = f.read()
On the other hand, I use cv2 to read the same file
b = cv2.imread('abc.jpg', -1)
How to convert b to a directly?
Thanks.
Answer to your question:
success, a_numpy = cv2.imencode('.jpg', b)
a = a_numpy.tostring()
Things you should know:
First, type(a) is a binary string, and type(b) is a numpy array. It's easy to convert between those types, since you can make np.array(binary_string) to go from string to numpy, and np_array.tostring() to go from numpy to binary string.
However, a and b represent different things. In the string a, you're reading the JPEG encoded version of the image, and in b you have the decoded image. You can check that len(b.tostring()) is massively larger than len(a). You need to know which one you want to use. Also, keep in mind that each time you encode a JPEG, you will loose some quality.
How to save an image to disk:
Your question looks like you want an encoded binary string. The only use I can imagine for that is dumping it to the disk (or sending it over http?).
To save the image on your disk, you can use
cv2.imwrite('my_file.jpg', b)

Using Python to convert and image in to a string?

An external application written in c++ requires me to pass in an image object it would understand i.e. with tostring() method, passing in a encoder and parameters.
How can I get the image and convert it to a string (without saving the image to file)?
image_url is the url to an actual image online i.e http://www.test.com/image1.jpg
This is what I have tried:
def pass_image(image_url):
import base64
str = base64.b64encode(image_url.read())
app = subprocess.Popen("externalApp",
in=subprocess.PIPE,
out=subprocess.PIPE)
app.in.write(str)
app.in.close()
I have also tried to open the image to convert it
image = Image.open(image_url)
but get the error
file() argument 1 must be encoded string without NULL bytes, not str
I think you can get a online image by using requests.get.
You code will be like this:
def pass_image(image_url):
import base64
import requests
str = base64.b64encode(requests.get(image_url).content)

Categories

Resources