The instructions are simple enough in the Wand docs for reading a sequenced image (e.g. animated gif, icon file, etc.):
>>> from wand.image import Image
>>> with Image(filename='sequence-animation.gif') as image:
... len(image.sequence)
...but I'm not sure how to create one.
In Ruby this is easy using RMagick, since you have ImageLists. (see my gist for an example.)
I tried creating an Image (as the "container") and instantiating each SingleImage with an image path, but I'm pretty sure that's wrong, especially since the constructor documentation for SingleImage doesn't look for use by the end-user.
I also tried creating a wand.sequence.Sequence and going from that angle, but hit a dead-end as well. I feel very lost.
The best examples are located in the unit-tests shipped with the code. wand/tests/sequence_test.py for example.
For creating an animated gif with wand, remember to load the image into the sequence, and then set the additional delay/optimize handling after all frames are loaded.
from wand.image import Image
with Image() as wand:
# Add new frames into sequance
with Image(filename='1.png') as one:
wand.sequence.append(one)
with Image(filename='2.png') as two:
wand.sequence.append(two)
with Image(filename='3.png') as three:
wand.sequence.append(three)
# Create progressive delay for each frame
for cursor in range(3):
with wand.sequence[cursor] as frame:
frame.delay = 10 * (cursor + 1)
# Set layer type
wand.type = 'optimize'
wand.save(filename='animated.gif')
Related
I'm looking for a library that enables to "create pictures" (or even videos) with the following functions:
Accepting picture inputs
Resizing said inputs to fit given template / scheme
Positioning the pictures in pre-set up layers or coordinates
A rather schematic approach to look at this:
whereas the red spots are supposed to represent e.g. text, picture (or if possible video) elements.
The end goal would be to give the .py script multiple input pictures and the .py creating a finished version like mentioned above.
Solutions I tried were looking into Python PIL, but I wasn't able to find what I was looking for.
Yes, it is possible to do this with Python.
The library you are looking for is OpenCV([https://opencv.org][1]/).
Some basic OpenCV python tutorials (https://docs.opencv.org/master/d9/df8/tutorial_root.html).
1) You can use imread() function to read images from files.
2) You can use resize() function to resize the images.
3) You can create a empty master numpy array matching the size and depth(color depth) of the black rectangle in the figure you have shown, resize your image and copy the contents into the empty array starting from the position you want.
Below is a sample code which does something close to what you might need, you can modify this to suit your actual needs. (Since your requirements are not clear I have written the code like this so that it can at least guide you.)
import numpy as np
import cv2
import matplotlib.pyplot as plt
# You can store most of these values in another file and load them.
# You can modify this to set the dimensions of the background image.
BG_IMAGE_WIDTH = 100
BG_IMAGE_HEIGHT = 100
BG_IMAGE_COLOR_DEPTH = 3
# This will act as the black bounding box you have shown in your figure.
# You can also load another image instead of creating empty background image.
empty_background_image = np.zeros(
(BG_IMAGE_HEIGHT, BG_IMAGE_WIDTH, BG_IMAGE_COLOR_DEPTH),
dtype=np.int
)
# Loading an image.
# This will be copied later into one of those red boxes you have shown.
IMAGE_PATH = "./image1.jpg"
foreground_image = cv2.imread(IMAGE_PATH)
# Setting the resize target and top left position with respect to bg image.
X_POS = 4
Y_POS = 10
RESIZE_TARGET_WIDTH = 30
RESIZE_TARGET_HEIGHT = 30
# Resizing
foreground_image= cv2.resize(
src=foreground_image,
dsize=(RESIZE_TARGET_WIDTH, RESIZE_TARGET_HEIGHT),
)
# Copying this into background image
empty_background_image[
Y_POS: Y_POS + RESIZE_TARGET_HEIGHT,
X_POS: X_POS + RESIZE_TARGET_WIDTH
] = foreground_image
plt.imshow(empty_background_image)
plt.show()
Most people recommend "wand" when it comes to imagemagick for python but how can I append images using it in python ? I want to add lables to bottom of images using imagemagick in python : http://www.imagemagick.org/Usage/annotating/ but wand api seems to be very basic and doesn't have lots of imgemagick commands including labels and appending.
Is there any other way to use imagemagick in python ? my images are png type and are BytesIO streams inside the python code not files so I can not pass them to imagemagick using command line and can't save them on any temporary file either.
I'm not really sure what your asking for, but I'm guessing you want to write a label "below" an image. Here's an example with the wand library.
from wand.image import Image
from wand.compat import nested
from wand.color import Color
from wand.font import Font
with nested(Image(filename='logo:'),
Image(filename='null:')) as (source, text):
text.font = Font('Impact', 64)
text.read(filename='label:Hello world!')
largest_width = max(source.width, text.width)
offset = (largest_width - min(source.width, text.width)) / 2
with Image(width=largest_width,
height=source.height + text.height,
background=Color('WHITE')) as dst:
dst.composite(source, 0, 0)
dst.composite(text, int(offset), source.height)
dst.save(filename="output.png")
Overview
with nested(Image(filename='logo:'),
Image(filename='null:')) as (source, text):
Create two images. You would be responsible for replacing logo: image with your ByteIO buffer. The null: image is a placeholder for allocating a wand instance.
text.font = Font('Impact', 64)
text.read(filename='label:Hello world!')
This defines the typeface & text to draw. The label: protocol can be replaced with caption: for additional behavior(s?).
with Image(width=largest_width,
height=source.height + text.height,
background=Color('WHITE')) as dst:
Create a third "blank" image that is large enough to include both images.
dst.composite(source, 0, 0)
dst.composite(text, int(offset), source.height)
Copy the image data from the source & text to the new image.
Imagemagick is great but has steep learning curve. You need to have 3rd party ImageMagick installed (Would have to be 32 or 64 bit depending on your version of python). Installation alone is a pain considering you need to add it to path and the executable is necessary to run your script.
Consider something more portable and contained like Pillow which has number of features for achieving your goal.
pip install pillow
In pillow you can read images from BytesIO. And also draw or print on them. There is number of options available.
from PIL import Image, ImageDraw
import io
# Reading bytes from file but you can skip that and simply open your bytes like below.
with open('picture.jpg', 'rb') as f:
im = Image.open(io.BytesIO(f.read()))
draw = ImageDraw.Draw(im)
draw.text((10,10), "Hello World", fill=(255))
im.show() # do whatever you like with the image
Check the docs for more examples. https://pillow.readthedocs.io/en/latest/
Okay, first thing first. This is a near duplicate of this question.
However, the issue I am facing is slightly different in a critical way.
In my application, I read a generic file name in, load said image, and display it. Where it gets tricky is I have overlay the appearance of being 'highlighted'. To do this, I was using the Image.blend() function, and blending it with a straight yellow image.
However, when dealing with blend, I was fighting the error that the two images are not compatible to be blended. To solve this, I opened the sample image I had in paint, and just pasted yellow over the whole thing, and saved it as a copy.
It just occurred to me that this will fail when a different type of image is read in by file name. Remember this needs to be generic.
So my question is: Instead of making a copy of the image manually, can I get python to generate one by copying the image and modifying it so it is solid yellow? Note: I do not need to save it after, so just making it happen is enough.
Unfortunately, I am not allowed to share my code, but hopefully the following will give an idea of what I need:
from PIL import Image
desiredWidth = 800
desiredHeight = 600
primaryImage = Image.open("first.jpg").resize((desiredWidth, desiredHeight), Image.ANTIALIAS)
# This is the thing I need fixed:
highlightImage = Image.open("highlight.jpg").resize((desiredWidth, desiredHeight), Image.ANTIALIAS)
toDisplay = Image.blend(primaryImage, highlightImage, 0.3)
Thanks to anyone who can help.
Sounds like you want to make a new image:
fill_color = (255,255,0) #define the colour as (R,G,B) tuple
highlightImage = Image.new(primaryImage.mode, #same mode as the primary
primaryImage.size, #same size as the primary
fill_color)#and the colour defined above
this creates a new image with the same mode and size as the already opened image, but with a solid colour. Cheers.
Also if you are using Pillow instead of original PIL you can even get the color by name:
from PIL.ImageColor import getcolor
overlay = 'yellow'
fill_color = getcolor(overlay, primaryImage.mode)
So I have implemented the following screenshot functionality into my game just to log progress and stuff like that. This is my code:
pygame.image.save(screen, save_file)
Pretty basic. I recently upgraded to python 3.3 and have since been having the issue of distorted colors using this function. Here is what I mean:
Distorted Color:
So it looks quite nice, but it isn't how it supposed to be. This is the actual image:
Is this a known issue or is it just me? Are there any fixes to it or is it just a broken function at the moment. I am using pygame 1.9.2pre and I am assuming it is just a bug with the pre release but I was having issues using any other versions of pygame with python 3.3.
Some users have reported difficulty with saving images as pngs:
I only get .tga files even when I specify .png. Very frustrating.
If you use .PNG (uppercase), it will result in an invalid file (at least on my win32). Use .png (lowercase) instead.
PNG does not seem to work, I am able to get a preview of it in Thunar, but everywhere else It says that it is not a valid PNG.
Saving in a different format may be helpful. For example, BMP is a simple format, so it's unlikely that Pygame's implementation will be buggy.
If you really want to save as PNG, you can reverse the distortion by swapping the red channel with the green one. This is fairly easy. For example, using PIL:
from PIL import Image
im = Image.open("screenshot.png")
width, height = im.size
pix = im.load()
for i in range(width):
for j in range(height):
r,g,b = pix[i,j]
pix[i,j] = (g,r,b)
im.save("output.png")
Or you can save as BMP and convert to PNG after the fact:
from PIL import Image
im = Image.open("screenshot.bmp")
im.save("screenshot.png")
for future reference, this trick worked for me:
from PIL import Image
imgdata = pygame.surfarray.array3d(screen).transpose([1,0,2])[:,:,::-1]
Image.fromarray(imgdata).save('output.png')
I need to use python wand (image-magick bindings for python) to create a composite image, but I'm having some trouble figuring out how to do anything other than simply copy pasting the foreground image into the background image. What I want is, given I have two images like:
and
both jpegs, I want to remove the white background of the cat and then paste it on the room. Answers for other python image modules, like PIL, are also fine, I just need something to automatize the composition process. Thanks in advance.
You can achieve this using Image.composite() method:
import urllib2
from wand.image import Image
from wand.display import display
fg_url = 'http://i.stack.imgur.com/Mz9y0.jpg'
bg_url = 'http://i.stack.imgur.com/TAcBA.jpg'
bg = urllib2.urlopen(bg_url)
with Image(file=bg) as bg_img:
fg = urllib2.urlopen(fg_url)
with Image(file=fg) as fg_img:
bg_img.composite(fg_img, left=100, top=100)
fg.close()
display(bg_img)
bg.close()
For those that stumble across this in the future, what you probably want to do is change the 'white' color in the cat image to transparent before doing the composition. This should be achievable using the 'transparent_color()' method of the Image. Something like 'fg_img.transparent_color(wand.color.Color('#FFF')), probably also with a fuzz parameter.
See:
http://www.imagemagick.org/Usage/compose/
http://docs.wand-py.org/en/latest/wand/image.html