Is it possible to code images into a python script? - python

Instead of using directories to reference an image, is it possible to code an image into the program directly?

You can use the base64 module to embed data into your programs. From the base64 documentation:
>>> import base64
>>> encoded = base64.b64encode('data to be encoded')
>>> encoded
'ZGF0YSB0byBiZSBlbmNvZGVk'
>>> data = base64.b64decode(encoded)
>>> data
'data to be encoded'
Using this ability you can base64 encode an image and embed the resulting string in your program. To get the original image data you would pass that string to base64.b64decode.

Try img2py script. It's included as part of wxpython (google to see if you can dl seperately).
img2py.py -- Convert an image to PNG format and embed it in a Python
module with appropriate code so it can be loaded into a program at runtime. The benefit is that since it is Python source code it can be delivered as a .pyc or 'compiled' into the program using freeze, py2exe, etc.
Usage:
img2py.py [options] image_file python_file

There is no need to base64 encode the string, just paste it's repr into the code

If you mean, storing the bytes that represent the image in the program code itself, you could do it by base64 encoding the image file, and setting a variable to that string.
You could also declare a byte array, where the contents of the array are the bytes that represent the image.
In both cases, if you want to operate on the image, you may need to decode the value that you have included in your source code.
Warning: you may be treading on a performance minefield here.
A better way might be to store the image/s in the directory structure of your module, and the loading it on demand (even caching it). You could write a generalized method/function that loads the right image based on some identifier which maps to the particular image file name that is part and parcel of your module.

Related

get the decode value of QR code using Appium and postman

I have created a session and located the QR code element ID using endpoint mentioned in Appium documentation.
This is the value of text I'm getting from QR code; I expect the actual decode of QR code which can be further used in applications for automation. I was wondering if other application needs to be used or it is possible in postman itself.
The issue was solved by using python's cv2 library
filename = "img.png"
# read the QRCODE image
image = cv2.imread(filename)
# initialize the cv2 QRCode detector
detector = cv2.QRCodeDetector()
# detect and decode
data, vertices_array, binary_qrcode = detector.detectAndDecode(image)
if vertices_array is not None:
print("QRCode data:")
print(data)
else:
print("There was some error")
Well, in fact, there are several questions here, is the QR code value static or dynamic, that is, does the QR code change during each test or can you use the same QR for all tests
If the value does not change(static), you can create a file, say .yaml, in the resources or test data directory, where your value will be stored in an encoded form, then you read this value from the file, decode it and pass it to the test script
If the QR code changes(dynamic value) for each test, you can create an API call, for python you can use the requests library or Java RestAssured, you take the encoded value from the response, decode it and pass it to the test script
the implementation depends on the above, but the whole process must be implemented within your framework
So you don't need to use additional tools like Postman etc to get value and decode it, if you want to automate your case properly combine API and UI
To decode value in Python I use Fernet, Java bouncycastle

Download an image from google using direct path (not link)

Google images have this weird path element, which when typed into a browser will directly bring you to the image (i.e.
data:image/png;base64,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
brings you to a picture of the Apple company logo). Is there any way to download an image given this link?
Requests and requests_html cannot access this type of path.
this is the base64 encoding of the image. If you just take that as a string and save to disk after decoding base64, it will save correctly as a png.
from this answer:
# your string is
img_data = 'iVBORw0KGgoAAAANSUhEUgAAAM4AAAD1CAMAAAAvfDqYAAAAflB'...
# For both Python 2.7 and Python 3.x
import base64
with open("imageToSave.png", "wb") as fh:
fh.write(base64.decodebytes(img_data))
Convert string in base64 to image and save on filesystem in Python
Those letters and number ARE the image. Literally. It's just base64 encoded.
So one thing you could do is import the base64 library to convert that string into an image which you could then save to disk.
See https://stackoverflow.com/a/37767000/1831109

How to send embedded image created using PIL/pillow as email (Python 3)

I am creating image that I would like to embed in the e-mail. I cannot figure out how to create image as binary and pass into MIMEImage. Below is the code I have and I have error when I try to read image object - the error is "AttributeError: 'NoneType' object has no attribute 'read'".
image=Image.new("RGBA",(300,400),(255,255,255))
image_base=ImageDraw.Draw(image)
emailed_password_pic=image_base.text((150,200),emailed_password,(0,0,0))
imgObj=emailed_password_pic.read()
msg=MIMEMultipart()
html="""<p>Please finish registration <br/><img src="cid:image.jpg"></p>"""
img_file='image.jpg'
msgText = MIMEText(html,'html')
msgImg=MIMEImage(imgObj)
msgImg.add_header('Content-ID',img_file)
msg.attach(msgImg)
msg.attach(msgText)
If you look at line 4 - I am trying to read image so that I can pass it into MIMEImage. Apparently, image needs to be read as binary. However, I don't know how to convert it to binary so that .read() can process it.
FOLLOW-UP
I edited code per suggestions from jsbueno - thank you very much!!!:
emailed_password=os.urandom(16)
image=Image.new("RGBA",(300,400),(255,255,255))
image_base=ImageDraw.Draw(image)
emailed_password_pic=image_base.text((150,200),emailed_password,(0,0,0))
stream_bytes=BytesIO()
image.save(stream_bytes,format='png')
stream_bytes.seek(0)
#in_memory_file=stream_bytes.getvalue()
#imgObj=in_memory_file.read()
imgObj=stream_bytes.read()
msg=MIMEMultipart()
sender='xxx#abc.com'
receiver='jjjj#gmail.com'
subject_header='Please use code provided in this e-mail to confirm your subscription.'
msg["To"]=receiver
msg["From"]=sender
msg["Subject"]=subject_header
html="""<p>Please finish registration by loging into your account and typing in code from this e-mail.<br/><img src="cid:image.png"></p>"""
img_file='image.png'
msgText=MIMEText(html,'html')
msgImg=MIMEImage(imgObj) #Is mistake here?
msgImg.add_header('Content-ID',img_file)
msg.attach(msgImg)
msg.attach(msgText)
smtpObj=smtplib.SMTP('smtp.mandrillapp.com', 587)
smtpObj.login(userName,userPassword)
smtpObj.sendmail(sender,receiver,msg.as_string())
I am not getting errors now but e-mail does not have image in it. I am confused about the way image gets attached and related to in html/email part. Any help is appreciated!
UPDATE:
This code actually works - I just had minor typo in the code on my PC.
There are a couple of conceptual errors there, both in using PIL and on what format an image should be in order to be incorporated into an e-mail.
In PIL: the ImageDraw class operates inplace, not like the Image class calls, which usually return a new image after each operation. In your code, it means that the call to image_base.text is actually changing the pixel data of the object that lies in your image variable. This call actually returns None and the code above should raise an error like "AttributeError: None object does not have attribute 'read'" on the following line.
Past that (that is, you should fetch the data from your image variable to attach it to the e-mail) comes the second issue: PIL, for obvious reasons, have images in an uncompressed, raw pixel data format in memory. When attaching images in e-mails we usually want images neatly packaged inside a file - PNG or JPG formats are usually better depending on the intent - let's just stay with .PNG. So, you have to create the file data using PIL, and them attach the file data (i.e. the data comprising a PNG file, including headers, metadata, and the actual pixel data in a compressed form). Otherwise you'd be putting in your e-mail a bunch of (uncompressed) pixel data that the receiving party would have no way to assemble back into an image (even if he would treat the data as pixels, raw pixel data does not contain the image shape so-)
You have two options: either generate the file-bytes in memory, or write them to an actual file in disk, and re-read that file for attaching. The second form is easier to follow. The first is both more efficient and "the right thing to do" - so let's keep it:
from io import BytesIO
# In Python 2.x:
# from StringIO import StringIO.StringIO as BytesIO
image=Image.new("RGBA",(300,400),(255,255,255))
image_base=ImageDraw.Draw(image)
# this actually modifies "image"
emailed_password_pic=image_base.text((150,200),emailed_password,(0,0,0))
stream = BytesIO()
image.save(stream, format="png")
stream.seek(0)
imgObj=stream.read()
...
(NB: I have not checked the part dealing with mail and mime proper in your code - if you are using it correctly, it should work now)

What is the best way to save image metadata alongside a tif?

In my work as a grad student, I capture microscope images and use python to save them as raw tif's. I would like to add metadata such as the name of the microscope I am using, the magnification level, and the imaging laser wavelength. These details are all important for how I post-process the images.
I should be able to do this with a tif, right? Since it has a header?
I was able to add to the info in a PIL image:
im.info['microscope'] = 'george'
but when I save and load that image, the info I added is gone.
I'm open to all suggestions. If I have too, I'll just save a separate .txt file with the metadata, but it would be really nice to have it embedded in the image.
Tifffile is one option for saving microscopy images with lots of metadata in python.
It doesn't have a lot of external documentation, but the docstings are great so you can get a lot of info just by typing help(tifffile) in python, or go look at the source code.
You can look at the TiffWriter.save function in the source code (line 750) for the different keyword arguments you can use to write metadata.
One is to use description, which accepts a string. It will show up as the tag "ImageDescription" when you read your image.
Another is to use the extratags argument, which accepts a list of tuples. That allows you to write any tag name that exist in TIFF.TAGS(). One of the easiest way is to write them as strings because then you don't have to specify length.
You can also write ImageJ metadata with ijmetadata, for which the acceptable types are listed in the source code here.
As an example, if you write the following:
import json
import numpy as np
import tifffile
im = np.random.randint(0, 255, size=(150, 100), dtype=np.uint8)
# Description
description = "This is my description"
# Extratags
metadata_tag = json.dumps({"ChannelIndex": 1, "Slice": 5})
extra_tags = [("MicroManagerMetadata", 's', 0, metadata_tag, True),
("ProcessingSoftware", 's', 0, "my_spaghetti_code", True)]
# ImageJ metadata. 'Info' tag needs to be a string
ijinfo = {"InitialPositionList": [{"Label": "Pos1"}, {"Label": "Pos3"}]}
ijmetadata = {"Info": json.dumps(ijinfo)}
# Write file
tifffile.imsave(
save_name,
im,
ijmetadata=ijmetadata,
description=description,
extratags=extra_tags,
)
You can see the following tags when you read the image:
frames = tifffile.TiffFile(save_name)
page = frames.pages[0]
print(page.tags["ImageDescription"].value)
Out: 'this is my description'
print(page.tags["MicroManagerMetadata"].value)
Out: {'ChannelIndex': 1, 'Slice': 5}
print(page.tags["ProcessingSoftware"].value)
Out: my_spaghetti_code
For internal use, try saving the metadata as JSON in the TIFF ImageDescription tag, e.g.
from __future__ import print_function, unicode_literals
import json
import numpy
import tifffile # http://www.lfd.uci.edu/~gohlke/code/tifffile.py.html
data = numpy.arange(256).reshape((16, 16)).astype('u1')
metadata = dict(microscope='george', shape=data.shape, dtype=data.dtype.str)
print(data.shape, data.dtype, metadata['microscope'])
metadata = json.dumps(metadata)
tifffile.imsave('microscope.tif', data, description=metadata)
with tifffile.TiffFile('microscope.tif') as tif:
data = tif.asarray()
metadata = tif[0].image_description
metadata = json.loads(metadata.decode('utf-8'))
print(data.shape, data.dtype, metadata['microscope'])
Note that JSON uses unicode strings.
To be compatible with other microscopy software, consider saving OME-TIFF files, which store defined metadata as XML in the ImageDescription tag.
I should be able to do this with a tif, right? Since it has a header?
No.
First, your premise is wrong, but that's a red herring. TIFF does have a header, but it doesn't allow you to store arbitrary metadata in it.
But TIFF is a tagged file format, a series of chunks of different types, so the header isn't important here. And you can always create your own private chunk (any ID > 32767) and store anything you want there.
The problem is, nothing but your own code will have any idea what you stored there. So, what you probably want is to store EXIF or XMP or some other standardized format for extending TIFF with metadata. But even there, EXIF or whatever you choose isn't going to have a tag for "microscope", so ultimately you're going to end up having to store something like "microscope=george\nspam=eggs\n" in some string field, and then parse it back yourself.
But the real problem is that PIL/Pillow doesn't give you an easy way to store EXIF or XMP or anything else like that.
First, Image.info isn't for arbitrary extra data. At save time, it's generally ignored.
If you look at the PIL docs for TIFF, you'll see that it reads additional data into a special attribute, Image.tag, and can save data by passing a tiffinfo keyword argument to the Image.save method. But that additional data is a mapping from TIFF tag IDs to binary hunks of data. You can get the Exif tag IDs from the undocumented PIL.ExifTags.TAGS dict (or by looking them up online yourself), but that's as much support as PIL is going to give you.
Also, note that accessing tag and using tiffinfo in the first place requires a reasonably up-to-date version of Pillow; older versions, and classic PIL, didn't support it. (Ironically, they did have partial EXIF support for JPG files, which was never finished and has been stripped out…) Also, although it doesn't seem to be documented, if you built Pillow without libtiff it seems to ignore tiffinfo.
So ultimately, what you're probably going to want to do is:
Pick a metadata format you want.
Use a different library than PIL/Pillow to read and write that metadata. (For example, you can use GExiv2 or pyexif for EXIF.)
You could try setting tags in the tag property of a TIFF image. This is an ImageFileDirectory object. See TiffImagePlugin.py.
Or, if you have libtiff installed, you can use the subprocess module to call the tiffset command to set a field in the header after you have saved the file. There are online references of available tags.
According to this page:
If one needs more than 10 private tags or so, the TIFF specification suggests that, rather then using a large amount of private tags, one should instead allocate a single private tag, define it as datatype IFD, and use it to point to a socalled 'private IFD'. In that private IFD, one can next use whatever tags one wants. These private IFD tags do not need to be properly registered with Adobe, they live in a namespace of their own, private to the particular type of IFD.
Not sure if PIL supports this, though.

md5 from pil object

how i can get md5 of the pil object without saving to file ?
imq.save('out.png')
hash = hashlib.md5(open('out.png','rb').read()).hexdigest()
Actually there is simpler solution:
hashlib.md5(img.tostring()).hexdigest()
Turning #Ignacio's answer into code, using this answer to help:
import StringIO, hashlib
output = StringIO.StringIO()
img.save(output)
hash = hashlib.md5(output.getvalue()).hexdigest()
As the referenced other answer notes, this might lead to a KeyError if PIL tries to automatically detect the output format. To avoid this problem you can specify the format manually:
img.save(output, format='GIF')
(Note: I've used "img" as the variable, rather than your "imq" which I assumed was a typo.)
You could write it to a StringIO instead, and then take the hash of that.
You could use the following PIL Image class method to get the raw image data to feed to md5().
im.getdata() => sequence
Returns the contents of an image as a
sequence object containing pixel
values. The sequence object is
flattened, so that values for line one
follow directly after the values of
line zero, and so on.
Note that the resulting MD5 hash of using this won't be the same as your sample code because it is (at least partially) independent of the particular image file format used to save the image. It could be useful if you wanted to compare actual images independent of the particular image file format they may be saved in.
To use it you would need to store the MD5 hash of the image data somewhere independent of any image file where it could be retrieved when needed -- as opposed to generating it by reading the entire file into memory as binary data like the code in your question does. Instead you would need to always load the image into PIL and then use the getdata() method on it to compute hashes.

Categories

Resources