I've got a wxPython app that uses the following line before creating a wx.BitmapButton:
imagePlus = wx.Image('wxPlus.png', wx.BITMAP_TYPE_PNG).ConvertToBitmap()
Is there a way to include the image's data in the image, and so something more like this?
plusData = '...√#,›o~ño\Ķ˚fly™Ω.…Õo)Ú∞L∂W_≤Ï~˛⁄...'
imagePlus = wx.Image(plusData, wx.BITMAP_TYPE_PNG).ConvertToBitmap()
By using the module StringIO you can create a 'file-like object' that you can pass to wx.ImageFromStream.
import StringIO
stream = StringIO.StringIO()
stream.write('...√#,›o~ño\Ķ˚fly™Ω.…Õo)Ú∞L∂W_≤Ï~˛⁄...')
image = wx.ImageFromStream(stream)
If you're using wxPython, I think img2py would be worth a look.
Related
I use the PPTX library to automate the creation of a deck of slides on a weekly basis.
It was working really well until the last update of the library. As you can see below, I keep getting the following when updating the "image part" of the slides:
AttributeError: 'SlidePart' object has no attribute 'related_parts'
Here is my function for the image replacement:
def replace_img_slide(prs, slide_nbr, shape_nbr, img_path):
slide = prs.slides[slide_nbr]
img = slide.shapes[shape_nbr]
try:
imgPic = img._pic
except AttributeError:
raise AttributeError(
f"Error for slide: {slide_nbr}, shape: {shape_nbr}, path: {img_path}")
imgRID = imgPic.xpath('./p:blipFill/a:blip/#r:embed')[0]
imgPart = slide.part.related_parts[imgRID]
with open(img_path, 'rb') as f:
rImgBlob = f.read()
# replace
imgPart._blob = rImgBlob
return prs
I found some related subject and I understood that the "related_parts" is now obsolete in the new version of the library but I did not find how to solve it. Do you think you can help me with that please ?
Many thanks in advance for your help !
Just use part.related_part(imgRID) where you used to use part.related_parts[imgRID].
The latest version exposes that method (internally) rather than expose a dict-like object just to do that one job.
This is the code i'm trying to run on an virtual environment in python3.6. I use ubuntu newest version 17.10, I run the code as python3 gather_annotations.py
import numpy as np
import cv2
import argparse
from imutils.paths import list_images
from selectors import BoxSelector
#parse arguments
ap = argparse.ArgumentParser()
ap.add_argument("-d","--dataset",required=True,help="path to images dataset...")
ap.add_argument("-a","--annotations",required=True,help="path to save annotations...")
ap.add_argument("-i","--images",required=True,help="path to save images")
args = vars(ap.parse_args())
#annotations and image paths
annotations = []
imPaths = []
#loop through each image and collect annotations
for imagePath in list_images(args["dataset"]):
#load image and create a BoxSelector instance
image = cv2.imread(imagePath)
bs = BoxSelector(image,"Image")
cv2.imshow("Image",image)
cv2.waitKey(0)
#order the points suitable for the Object detector
pt1,pt2 = bs.roiPts
(x,y,xb,yb) = [pt1[0],pt1[1],pt2[0],pt2[1]]
annotations.append([int(x),int(y),int(xb),int(yb)])
imPaths.append(imagePath)
#save annotations and image paths to disk
annotations = np.array(annotations)
imPaths = np.array(imPaths,dtype="unicode")
np.save(args["annotations"],annotations)
np.save(args["images"],imPaths)
And I get the following errors
I have this Folder named '2' where I have all the scripts and other folder named selectors where there is 2 scripts init and box_selector
2(folder)
----selectors/
------------_ init _.py
------------box_selector.py
----detector.py
----gather_annotations.py
----test.py
----train.py
How can I fix that, in the post where I got the code from says something about 'relative imports' but i couln't fix it, thank you.
You need to use . notation to access a file inside a folder..
so
from folder.python_file import ClassOrMethod
in your case
from selectors.box_selector import BoxSelector
Having__init__.py in the selectors folder is crucial to making this work.
You can as many folders as you like and can access as follows but each folder has to contain an __init__.py to work
from folder.folder1.folder2.python_file import ClassOrMethod
One possible area of confusion is that there is a different python library called "selectors" which is DIFFERENT from the selectors of this code example.
https://docs.python.org/3/library/selectors.html
I ended up rename "selectors" (including the directory) of this example to "boxselectors"
This example is from http://www.hackevolve.com/create-your-own-object-detector/
I have an .obj file in which, previously, I transformed an image to base64 and saved with pickle.
The problem is when I try to load the .obj file with pickle, convert the code into image from base64, and load it with pygame.
The function that loads the image:
def mainDisplay_load(self):
main_folder = path.dirname(__file__)
img_main_folder = path.join(main_folder, "sd_graphics")
# loadImg
self.mainTerminal = pg.image.load(path.join(img_main_folder, self.main_uncode("tr.obj"))).convert_alpha()
The function that decodes the file:
def main_uncode(self, object):
openFile = open(object, "rb")
str = pickle.load(openFile)
openFile.close()
fileData = base64.b64decode(str)
return fileData
The error I get when the code is run:
str = pickle.load(openFile)
EOFError: Ran out of input
How can I fix it?
Python version: 3.6.2
Pygame version: 1.9.3
Update 1
This is the code I used to create the .obj file:
import base64, pickle
with open("terminal.png", "rb") as imageFile:
str = base64.b64encode(imageFile.read())
print(str)
file_pi = open("tr.obj","wb")
pickle.dump(str,file_pi)
file_pi.close()
file_pi2 = open("tr.obj","rb")
str2 = pickle.load(file_pi2)
file_pi2.close()
imgdata = base64.b64decode(str2)
filename = 'some_image.jpg' # I assume you have a way of picking unique filenames
with open(filename, 'wb') as f:
f.write(imgdata)
Once the file is created, it is loaded and a second image is created. This is to check if the image is the same or there are errors in the conversion.
As you can see, I used part of the code to load the image, but instead of saving it, it is loaded into pygame. And that's where the mistake occurs.
Update 2
I finally managed to solve it.
In the main code:
def mainDisplay_load(self):
self.all_graphics = pg.sprite.Group()
self.graphics_menu = pg.sprite.Group()
# loadImg
self.img_mainTerminal = mainGraphics(self, 0, 0, "sd_graphics/tr.obj")
In the library containing graphics classes:
import pygame as pg
import base64 as bs
import pickle as pk
from io import BytesIO as by
from lib.setting import *
class mainGraphics(pg.sprite.Sprite):
def __init__(self, game, x, y, object):
self.groups = game.all_graphics, game.graphics_menu
pg.sprite.Sprite.__init__(self, self.groups)
self.game = game
self.object = object
self.outputGraphics = by()
self.x = x
self.y = y
self.eventType()
self.rect = self.image.get_rect()
self.rect.x = self.x * tilesizeDefault
self.rect.y = self.y * tilesizeDefault
def eventType(self):
openFile = open(self.object, "rb")
str = pk.load(openFile)
openFile.close()
self.outputGraphics.write(bs.b64decode(str))
self.outputGraphics.seek(0)
self.image = pg.image.load(self.outputGraphics).convert_alpha()
For the question of why I should do such a thing, it is simple:
any attacker with sufficient motivation can still get to it easily
Python is free and open.
On the one hand, we have a person who intentionally goes and modify and recover the hidden data. But if Python is an open language, as with even more complicated and protected languages, the most motivated are able to crack the game or program and retrieve the same data.
On the other hand, we have a person who knows only the basics, or not even that. A person who cannot access the files without knowing more about the language, or decoding the files.
So you can understand that decoding files, from my point of view, does not need to be protected from a motivated person. Because even with a more complex and protected language, that motivated person will be able to get what he wants. The protection is used against people who have no knowledge of the language.
So, if the error you get is indeed "pickle: run out of input", that propably means you messed your directories in the code above, and are trying to read an empty file with the same name as your obj file is.
Actually, as it is, this line in your code:
self.mainTerminal=pg.image.load(path.join(img_main_folder,self.main_uncode
("tr.obj"))).convert_alpha()
Is completly messed up. Just read it and you can see the problem: you are passing to the main_uncode method just the file name, without directory information. And then, if it would by chance have worked, as I have poitned in the comments a while ago, you would try to use the unserialized image data as a filename from where to read your image. (You or someone else had probably thought that main_uncode should write a temporary image file and writ the image data to that, so that Pygame could read it, but as it is, it is just returning the raw image data in a string).
Threfore, by fixing the above call and passing an actual path to main_uncode, and further modifying it to write the temporary data to a file and return its path would fix the snippets of code above.
Second thing is I can't figure out why do you need this ".obj" file at all. If it is just for "security through obscurity" hopping people get your bundled file can't open the images, that is a thing far from a recommended practice. To sum up just one thing: it will delay legitimate uses of your file (like, you yourself does not seem to be able to use it ), while any attacker with sufficient motivation can still get to it easily. By opening an image, base-64 encoding and pickling it, and doing the reverse process you are doing essentially a no-operation. Even more, a pickle file can serialize and write to disk complex Python objects - but a base64 serialization of an image could be written directly to a file, with no need for pickle.
Third thing: just use with to open all the files, not just the ones you read with the imaging library, Take your time to learn a little bit more about Python.
I have an image of ImageFieldFile type in Django. If I do print type(image), I get <class 'django.db.models.fields.files.ImageFieldFile'>
Next, I opened this using PIL's Image.open(image), resized it via image.resize((20,20)) and closed it image.close().
After closing it, I notice image's type has changed to <class 'PIL.Image.Image'>.
How do I change it back to <class 'django.db.models.fields.files.ImageFieldFile'>? I thought .close() would suffice.
The way I got around this was to save it to a BytesIO object then stuff that into an InMemoryUploadedFile. So something like this:
from io import BytesIO
from PIL import Image
from django.core.files.uploadedfile import InMemoryUploadedFile
# Where image is your ImageFieldFile
pil_image = Image.open(image)
pil_image.resize((20, 20))
image_bytes = BytesIO()
pil_image.save(image_bytes)
new_image = InMemoryUploadedFile(
image_bytes, None, image.name, image.type, None, None, None
)
image_bytes.close()
Not terribly graceful, but it got the job done. This was done in Python 3. Not sure of Python 2 compatibility.
EDIT:
Actually, in hindsight, I like this answer better. Wish it existed when I was trying to solve this issue. :-\
Hope this helps. Cheers!
I am new to python or more specifically ipython. I have been running through the steps to run what should be a very simple Dicom Conversion in a statistical package called SPM for an MRI image file as described by NiPype. I can't get it to run and was wondering what I was doing wrong. I am not getting an error message, instead, there is no file change or output. It just hangs. Does anyone have any idea what I might be doing wrong? It's likely that I am missing something very simple here (sorry :(
import os
from pylab import *
from glob import glob
from nipype.interfaces.matlab import MatlabCommand as mlab
mlab.set_default_paths('/home/orkney_01/s1252042/matlab/spm8')
from nipype.interfaces.spm.utils import DicomImport as di
os.chdir('/sdata/images/projects/ASD_MM/1/datafiles/restingstate_files')
filename = "reststate_directories.txt"
restingstate_files_list = [line.strip() for line in open(filename)]
for x in restingstate_files_list:
os.chdir( x )
y = glob('*.dcm')
conversion = di(in_files = y))
print(res.outputs)
You are creating a DicomImport interface, but you are not actually running it. You should have res = di.run().
Also, you are best to tell the interface where to run using di.base_dir = '/some/path' before running.
Finally, you may also want to print the contents of restingstate_files_list to check you are finding the DICOM directories correctly.