Frames of transparent gif overlapping with each other - python-3.x

I'm trying to create a transparent gif through pillow in python through this code
frames[0].save(path+'/final.gif', format='GIF', append_images=frames[1:], save_all=True, duration=33, loop=0,transparency=0)
where frame is a list of PIL.Image files. The end result is that you can see the image in the previous frame
This hasn't happened before and I was able to create this gif without any problems

I solved this problem by setting disposal = 2 , you can edit your code as:
frames[0].save(path+'/final.gif', format='GIF', append_images=frames[1:], save_all=True, duration=33, loop=0,transparency=0, disposal = 2)

Related

Creating a gif from pngs: looping through images seems too fast and only works in debug mode

I'm trying to create a gif image from several (in this case only 5) png files. I can create the gif if I debug the code at the point the looping through the images occurs. Otherwise the execution appears to be too fast. Here is my code:
img, *imgs = [Image.open(f) for f in sorted(glob.glob(png_in))]
So I flattened the list comprehension and added and played around with the time.sleep(x):
ImageFile.LOAD_TRUNCATED_IMAGES = True
imgs = []
for f in sorted(glob.glob(png_in)):
i = Image.open(f)
time.sleep(1)
imgs.append(i)
Then instead of using the PIL module, I switched to the imageio module:
images = []
png_list = sorted(glob.glob(png_in))
for filename in png_list:
print(f"fn: {filename}")
images.append(imageio.imread(filename))
time.sleep(1)
imageio.mimsave(gif_file, images)
Any ideas where I may be going wrong? The error message I get, for example, is:
unknown element "blank"
i = Image.open(f)
Thanks to Mark Setchell....the problem I found was that the png's were not all there at the point the for loop was executed. I'm using openscad to create png files, and it's here I need to implement a time.sleep. In debug mode, because it's slower, openscad had time to create the png's and so you don't see this problem.

cv2.cvtColor(img,cv2.COLOR_BGR2RGB) not working

I am trying to create a screen recorder using mss and Opencv in python, the video I am capturing has a very different colours than original computer screen. I tried to find the solution online, Everyone saying it should be fixed using cvtColor() but I already have it in my code.
import cv2
from PIL import Image
import numpy as np
from mss import mss
import threading
from datetime import datetime
`
def thread_recording():
fourcc=cv2.VideoWriter_fourcc(*'mp4v')
#fourcc=cv2.VideoWriter_fourcc(*'XVID')
out=cv2.VideoWriter(vid_file,fourcc,50,(width,height))
mon = {"top": 0, "left": 0, "width":width, "height":height}
sct = mss()
thread1=threading.Thread(target=record,args=(mon,out,sct))
thread1.start()
def record(mon,out,sct):
global recording
recording=True
while recording:
frame= np.array(sct.grab(mon))
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
out.write(frame)
out.release()
the vid_file variable contains a string of output file name with mp4 extension
Screenshot of my screen
Screenshot from recorded video
So, I looked around some more and found that apparently this is a bug in opencv for versions 3.x on wards.then I tried PIL for getting rgb image and removed cvtColor(),but it produced an empty video.I removed both cvtColor() as well as PIL Image as suggested by #ZdaR it again wrote empty video Hence I had to put it back and boom. even if cvtColor() seems like doing nothing, for some unknown reason it has to be there.when you use PIL Image along with cvtColor() it writes the video as expected
from PIL import Image
def record(mon,out,sct):
global recording
recording=True
while recording:
frame=sct.grab(mon)
frame = Image.frombytes('RGB', frame.size, frame.rgb)
frame = cv2.cvtColor(np.array(frame), cv2.COLOR_BGR2RGB)
out.write(np.array(frame))
out.release()
as I am very new to programming, I would really appreciate your help if I missed or overlooked something important
You can do
frameRGB = cv2.cvtColor(frame,cv2.COLOR_RGB2BGR)
Frame is in BGR, and it will work the same as you are only changing R with B where frameRGB is in RGB now. This command will transfer R to B and works to transfer frames from RGB and BGR as well as BGR to RGB. BGR2RGB might be a bug, I have it as well but the command I mentioned works perfectly. That's what I do.
MSS store raw BGRA pixels. Does it work if you change to:
# Grab it
img = np.array(sct.grab(mon))
# Convert from BGRA to RGB
frame = cv2.cvtColor(img, cv2.COLOR_BGRA2RGB)
you should run this command in cmd
pip install opencv-python

Python extract part of SVG to PNG

I have been doing a ton of searching but cant quite find the answer to this one.
I have a series of relatively simple SVG images. I have drawn SVG rectangles over key areas of the images that I am interested in and would now like to extract those areas as PNG images. I have no idea the best way to approach this problem.
Idea 1) Convert the whole SVG to PNG then use say PIL to crop the image down after somehow converting the SVG rect coordinates to PNG coordinates. I am starting to work towards this method now, but I am hoping there is a better, and/or easier way to do this!
I am using Python 3.7 for this.
Edit 1:
This is a screen shot of what I am looking at. The original image is SVG, I would like to extract the areas under the green rectangles as PNG images.
Edit 2:
Working from Idea 1, I have the following code that basically sets the viewBox on the SVG image to one of the green rectangles, then sets the width and height of it. From there I am using CairoSVG to export the SVG as PNG.
import cairosvg
import xml.etree.ElementTree as ET
...
with gzip.open(fileObj.filePath,'rb') as file:
svg=file.read()
svg=svg.decode('utf-8')
svgRoot=ET.fromstring(svg)
ET.register_namespace("","http://www.w3.org/2000/svg")
ET.register_namespace('xlink', "http://www.w3.org/1999/xlink")
annots = meta['annots']
for a in annots:
r = ET.fromstring(a['g'])
vb=" ".join([r.get('x'),r.get('y'),r.get('width'),r.get('height')])
svgRoot.set("viewBox",vb)
svgRoot.set("width",'128px')
svgRoot.set("height",'128px')
svg = ET.tostring(svgRoot, encoding="unicode")
cairosvg.svg2png(svg,write_to="/home/test.png")
Unfortunately it is EXTREMELY slow! On the order of more than a minute to extract two PNGs. The SVG files are quite large (2 - 3 mb zipped) and very detailed. I am not certain how CairoSVG works, but does it render everything in the SVG even if it isnt visible before saving the visible part to PNG?
Any advise on optimising or speeding this up would be a huge help.
This worked for me in the end, though it is quite slow on larger SVG images:
import gzip
import cairosvg
import xml.etree.ElementTree as ET
...
with gzip.open(fileObj.filePath,'rb') as file:
svg=file.read()
svg=svg.decode('utf-8')
svgRoot=ET.fromstring(svg)
ET.register_namespace("","http://www.w3.org/2000/svg")
ET.register_namespace('xlink', "http://www.w3.org/1999/xlink")
annots = meta['annots']
for a in annots:
r = ET.fromstring(a['g'])
vb=" ".join([r.get('x'),r.get('y'),r.get('width'),r.get('height')])
svgRoot.set("viewBox",vb)
svgRoot.set("width",'128px')
svgRoot.set("height",'128px')
svg = ET.tostring(svgRoot, encoding="unicode")
cairosvg.svg2png(svg,write_to="/home/test.png")

Image not Displaying even after following effbot [duplicate]

This question already has an answer here:
PhotoImage not showing up the image associated with it
(1 answer)
Closed 3 years ago.
I'm trying to add in an image to a screen and its not displaying.
Followed other Stack overflow solutions and the Effbot solution and neither worked. Ive moved the image around and it still isnt displaying so its not where its displaying. Not getting any Error messages either.
image = PhotoImage("newspaper-extra-computer-icons-breaking-newsnewspaper.jpg")
image_label = Label(news_aggregator,image = image)
image_label.image = image
image_label.place(x=400,y = 200)
Just expecting the image to be displayed.
The main problem is you are missing file= in PhotoImage().
Try this:
PhotoImage(file='path_to_image.gif')
That said tkinter only supports a hand full of formats.
The PhotoImage class can read GIF and PGM/PPM images from files
For working with other formats you will need PIL.
If you need to work with other file formats, the Python Imaging Library (PIL) contains classes that lets you load images in over 30 formats, and convert them to Tkinter-compatible image objects:
You can see all there here on the documentation.
For your file try this:
import tkinter as tk
from PIL import ImageTk
root = tk.Tk()
image = ImageTk.PhotoImage(file="newspaper-extra-computer-icons-breaking-newsnewspaper.jpg")
image_label = tk.Label(root, image=image)
image_label.image = image
image_label.place(x=400, y=200)
root.mainloop()
Keep in mind due to you using place() the above code will not be showing the image as it is off frame. You will need to expand the window.

Both rasterio open and skimage.io.read return a NaN array for the TIFF I am trying to open

I'm trying to open a SAR image from sentinel-1. I can view the tiff file in QGIS, so I know the data is there, but when I go to open and view/show it in python, all of the modules I could use to open the data produce a NaN area, basically insinuating that there is no data in the image. Visualizing the image produces a completely black image, however the shape is correct.
Here is the code where I read in the image:
img = skimage.io.imread('NewData.tif', as_gray = True, plugin = 'tifffile')
with rio.open(r'NewData.tif') as src:
img2 = src.read()
imgMeta = src.profile
print(img)
skimage.io.imshow(img)
Any help would be appreciated.
thank you
The problem is not on the way rasterio or skimage is importing the image, but on the way it is displayed. I am assumign you are working with Calibrated SAR images that ARE NOT converted to the decibel dB scale. Here is the problem, the dynamic range of your data.
The issue here is that by default, the color ramp is not being strech according to the distribution of values in the raster histogram. In QGIS, SNAP or many other EO-related softwares, the color distribution matches the histogram to produce proper visualizations.
Solution: either you make that happen in your code or simply convert your backscatter values to decibel (which is a very common procedure when working with SAR data and produces an almost normal distrubution of the data). The conversion can be done in a EO software or more directly in your imported image with:
srcdB = 10*np.log10(src)
Once done, you can properly display your image:
import rasterio
from rasterio.plot import show
import numpy as np
with rio.open(r'/.../S1B_IW_GRDH_1SDV_20190319T161451_20190319T161520_015425_01CE3C_A401_Cal.tif') as src:
img2 = src.read()
imgMeta = src.profile
srcdB = 10*np.log10(src) # to decibel
show(srcdB, cmap='gray') # show using rasterio

Resources