How to reduce gif quality using wand? - python

I have the following code
from wand.image import Image
def saveSizes(f, filename):
scaled_width = 400
scaled_hight = 400
with Image() as finalImage:
with Image(filename=f) as img:
for frame in img.sequence:
#frame.transform(resize="%dx%d" % (scaled_width, scaled_hight))
frame.compression_quality = 75
finalImage.sequence.append(frame)
filename += '.gif'
finalImage.save(filename = filename)
saveSizes('source_file.gif', 'dest_file')
But the size of 'source_file.gif' is same as that of 'dest_file.gif'. Why is the "compression_quality" attribute not working?
Is there a better way to reduce the size of gif using wand or some other python lib.?
Also I am getting the following log in the console for every frame in the gif.
Exception ignored in: <bound method Resource.__del__ of <wand.sequence.SingleImage: 901eb12 (200x150)>>
Traceback (most recent call last):
File "/usr/local/lib/python3.5/site-packages/wand/resource.py", line 232, in __del__
self.destroy()
File "/usr/local/lib/python3.5/site-packages/wand/sequence.py", line 331, in destroy
self.container.sequence[self.index] = self
File "/usr/local/lib/python3.5/site-packages/wand/sequence.py", line 304, in index
assert image
AssertionError:

compression_quality works fine with the source (whole file).
my working example with pdfs:
def ConvertFewPagePdfToPngs(pdf):
with wand.image.Image(filename = pdf, resolution = 200) as source:
source.compression_quality = 99
imagess = source.sequence
for i in range(len(imagess)):
imagess[i].format = 'png'
destFileName = r'path' # depends on i
wand.image.Image(imagess[i]).save(filename=destFileName)
When i tried apply compression_quality to one page i got same error as you show

Related

Why do I get a MemoryError in 64bit python when doing a replace within a 8MB file? (Bytes)

I have a mitmproxy flow that contains multiple image files. The flow itself is in bytes. I am trying to dump the old images to files, then replace them within the flow with my own images.
However, I hit a Memory Error in Python and I don't understand why. The flow file itself is 8mb, the pictures I am trying to replace the old ones with are small, less then 100kb. There should be plenty of memory for that?
startList = list(re.finditer(b'\xff\xd8',flowContent))
x = 1
for a in startList:
end = flowContent.find(b'\xff\xd9',a.start())
fileContent = flowContent[a.start():end]
fileName = 'image'+str(x)+".jpg"
dumpfile = open('dump/'+fileName,'wb')
dumpfile.write(fileContent)
dumpfile.close()
replace = open('replace/replace'+str(x)+'.jpg','rb')
myImage = Image(replace)
replace.close()
nowTime = datetime.now()
myImage.datetime = nowTime.strftime(DATETIME_STR_FORMAT)
myImage.datetime_digitized = nowTime.strftime(DATETIME_STR_FORMAT)
myImage.datetime_original = nowTime.strftime(DATETIME_STR_FORMAT)
newImage = open('replace/replace'+str(x)+'U.jpg',"wb")
newImage.write(myImage.get_file())
newImage.close()
replaceF = open('replace/replace'+str(x)+'U.jpg','rb')
replaceContent = replaceF.read()
replaceF.close()
flowContent = flowContent.replace(fileContent,replaceContent)
#flowContent = re.sub(fileContent,myImage.get_file(),flowContent)
x = x+1
The error is on this line:
Traceback (most recent call last):
File "E:\SpecialK\flow.py", line 41, in <module>
flowContent = flowContent.replace(fileContent,replaceContent)
MemoryError

Using SVG image files to train a model

I am trying to use SVG image files to train a model in Python. When I run the below code in Jupyter notebook, I am getting below error. Also Image.open() does not work here. Is there a way to get this code working for .svg image files?
from PIL import Image
drawing = svg2rlg("/content/America_Online_logo.svg")
base_url = "https://upload.wikimedia.org/wikipedia/commons/0/09/America_Online_logo.svg"
base_image_path = tf.keras.utils.get_file(fname = "America_Online_logo.svg", origin =
base_url,)
Image.open(base_image_path)
a = plt.imread(base_image_path)
from keras.optimizers import gradient_descent_v2
width, height = keras.preprocessing.image.load_img(base_image_path).size
Getting following error:
UnidentifiedImageError Traceback (most recent call last)
`<ipython-input-39-a31080608fad> in <module>()`
from keras.optimizers import gradient_descent_v2
width, height = keras.preprocessing.image.load_img(base_image_path).size
img_nrows = 400
img_ncols = int(width * img_nrows / height)
2 frames
/usr/local/lib/python3.7/dist-packages/PIL/Image.py in open(fp, mode)
warnings.warn(message)
raise UnidentifiedImageError( "cannot identify image file %r" % (filename if filename else
fp))

Python applying logical_xor function on two gif images returns the error ValueError: image has wrong mode

I have two gif images and I need to do logical_xor on them from PIL library
This is my code:
from PIL import Image
image = Image.open("image.gif")
key = Image.open("key.gif")
test = image.mode == key.mode
print(test)
def logical_xor(image1, image2):
"""Logical XOR between two images.
.. code-block:: python
out = ((bool(image1) != bool(image2)) % MAX)
:rtype: :py:class:~PIL.Image.Image
"""
image1.load()
image2.load()
return image1._new(image1.im.chop_xor(image2.im))
secret = logical_xor(image, key)
I am getting this error:
True
Traceback (most recent call last):
File "C:/Users/negut_000/OneDrive/Scoala/Crypto/Image Encrypt Decrypt OTP/Encrypt.py", line 24, in <module>
secret = logical_xor(image, key)
File "C:/Users/negut_000/OneDrive/Scoala/Crypto/Image Encrypt Decrypt OTP/Encrypt.py", line 21, in logical_xor
return image1._new(image1.im.chop_xor(image2.im))
ValueError: image has wrong mode
Process finished with exit code 1
It seems that the images have the same mode so I don't understand the problem.
Please help!
Using instead of
image = Image.open("image.gif")
key = Image.open("key.gif")
This code
image = Image.open("image.gif", mode='r').convert("1")
key = Image.open("key.gif", mode='r').convert("1")

AttributeError: 'PhotoImage' object has no attribute '_PhotoImage__photo'

I am working on Yolo3-4-PY to implement it with tkinter.
I've looked up everywhere but not able to resolve the issue.
When I run the program the canvas is displayed but when I click on Start Video(btton) I get the following error:
Loading weights from weights/yolov3.weights...Done!
/usr/local/lib/python3.5/dist-packages/PIL/ImageTk.py:119: FutureWarning: elementwise comparison failed; returning scalar instead, but in the future will perform elementwise comparison
if mode not in ["1", "L", "RGB", "RGBA"]:
Exception in Tkinter callback
Traceback (most recent call last):
File "/usr/lib/python3.5/tkinter/__init__.py", line 1553, in __call__
return self.func(*args)
File "webcam_demo.py", line 13, in start_video
show_frame()
File "webcam_demo.py", line 39, in show_frame
imgtk = ImageTk.PhotoImage(image=cv2image)
File "/usr/local/lib/python3.5/dist-packages/PIL/ImageTk.py", line 120, in
__init__
mode = Image.getmodebase(mode)
File "/usr/local/lib/python3.5/dist-packages/PIL/Image.py", line 313, in
getmodebase
return ImageMode.getmode(mode).basemode
File "/usr/local/lib/python3.5/dist-packages/PIL/ImageMode.py", line 55, in
getmode
return _modes[mode]
TypeError: unhashable type: 'numpy.ndarray'
Exception ignored in: <bound method PhotoImage.__del__ of
<PIL.ImageTk.PhotoImage object at 0x7f4b73f455c0>>
Traceback (most recent call last):
File "/usr/local/lib/python3.5/dist-packages/PIL/ImageTk.py", line 130, in
__del__ name = self.__photo.name
AttributeError: 'PhotoImage' object has no attribute '_PhotoImage__photo'
in my case , correct with just simply add this line
root = tkinter.Tk()
complete code :
root = tkinter.Tk()
image = PIL.Image.open(r"C:\Users\Hamid\Desktop\asdasd\2.jpeg")
img = ImageTk.PhotoImage(image)
l = Label(image=img)
l.pack()
Issue
In the line imgtk = ImageTk.PhotoImage(image=cv2image), you are passing a numpy array (cv2image) as input to ImageTk.PhotoImage. But the source code of PIL.ImageTk mentions that it requires a PIL image.
This is what source code of PIL.ImageTk mentions for init() of PhotoImage.
class PhotoImage(object):
.....
:param image: Either a PIL image, or a mode string. If a mode string is
used, a size must also be given.
Solution
So basically, you will have to convert the numpy array to a PIL Image and then pass it to ImageTk.PhotoImage().
So, can you replace the line imgtk = ImageTk.PhotoImage(image=cv2image) with imgtk = ImageTk.PhotoImage(image=PIL.Image.fromarray(cv2image))?
This would convert the numpy array to a PIL Image and it would be passed into the method.
References
I extracted the code for converting a numpy array to PIL Image from this source.
when you place the image variable in the label , you must initiate the image variable to "image".
Eg: (CORRECT APPROACH)
photo = PhotoImage(file = "C://Users//Carl//Downloads//download.png")
label1 = Label(image = photo)
label1.pack()
Eg : (WRONG APPROACH)
photo = PhotoImage(file = "C://Users//Carl//Downloads//download.png")
label1 = Label(photo)
label1.pack()
Interesting.... there's apparently a nasty side-effect in Tkinter which can cause this.
Note (from hamidjahandideh's answer ) that it matters that you create your root window BEFORE cresting the ImageTk.
ie. this fails with AttributeError: 'PhotoImage' object has no attribute '_PhotoImage__photo'
im_numpy = cv2.imread(ResourcePhotos.BLUE_PERSON_TRAIL_PHOTO)[:, :, ::-1].copy() # Load BGR Image
im_pil = Image.fromarray(im_numpy)
imagetk = ImageTk.PhotoImage(im_pil)
window = tk.Tk() # This line must come BEFORE crearting ImageTk
tk.Label(window, image=imagetk).pack()
window.mainloop()
But this works:
im_numpy = cv2.imread(ResourcePhotos.BLUE_PERSON_TRAIL_PHOTO)[:, :, ::-1].copy() # Load BGR Image
im_pil = Image.fromarray(im_numpy)
window = tk.Tk() # This line must come BEFORE creating ImageTk
imagetk = ImageTk.PhotoImage(im_pil)
tk.Label(window, image=imagetk).pack()
window.mainloop()

Error When I Merge .tif into RGB band by python's PIL

from PIL import Image
band2 = Image.open('band2.tif')
band3 = Image.open('band3.tif')
band4 = Image.open('band4.tif')
img = Image.merge("RGB",(band4,band3,band2))
the band2.tif,band3.tif,band4.tif are downloaded in USGS(https://earthexplorer.usgs.gov/).
they may have some differents compared to the normal .TIF
the error information is
/usr/bin/python3.5 /home/lixingang/workspace/20170405/main.py
Traceback (most recent call last):
File "/home/lixingang/workspace/20170405/main.py", line 5, in <module>
img = Image.merge("RGB",(band4,band3,band2))
File "/usr/lib/python3/dist-packages/PIL/Image.py", line 2388, in merge
raise ValueError("mode mismatch")
ValueError: mode mismatch
Process finished with exit code 1
You need to convert each channel into a luminosity channel. So instead of this:
band2 = Image.open('band2.tif')
You need do this:
band2 = Image.open('band2.tif').convert('L')
The same as other channels, for merge the order should also be considered.

Categories

Resources