i'm trying to use Wand to create a multi-size ico, but i don't find anything talking about that, only normal conversion, to ico... i've found "Sequences":
https://wand.readthedocs.org/en/latest/roadmap.html
and sequences look like what i need, but i only see samples trying to read the multiple images, but not how to create, am i missing something? or is not possible?
or is it possible to do using PIL/PILLOW?
You can append() a single image to Image.sequence list. For example:
from wand.color import Color
from wand.image import Image
with Image(width=32, height=32, background=Color('red')) as ico:
with Image(width=16, height=16, background=Color('green')) as s16:
ico.sequence.append(s16)
ico.save(filename='multisized.ico')
Result (multisized.ico):
I had a similar problem, but with creating a multi-page PDF from multiple JPEG files. In Imagemagick i used command -adjoin. In Wand i did the following:
from glob import glob
from wand.image import Image
files = glob('*.jpg')
with Image() as orig: # create empty Image object
for f in files:
page = Image(filename=f)
orig.sequence.append(page)
orig.save(filename='result.pdf')
Related
If I have multiple base64 strings that are images (one string = one image). Is there a way to combine them and decode to a single image file? i.e. from multiple base64 strings, merge and output a single image file.
I'm not sure how I would approach this using Pillow (or if I even need it).
Further clarification:
The source images are TIFFs that are encoded into base64
When I say "merge", I mean turning multiple images into a multi-page image like you see in a multi-page PDF
I dug through the Pillow documentation (v5.3) and found something that seems to work. Basically, there are two phases to this:
Save encoded base64 strings as TIF
Append them together and save to disk
Example using Python 3.7:
from PIL import Image
import io
import base64
base64_images = ["asdfasdg...", "asdfsdafas..."]
image_files = []
for base64_string in base64_images:
buffer = io.BytesIO(base64.b64decode(base64_string))
image_file = Image.open(buffer)
image_files.append(image_file)
combined_image = images_files[0].save(
'output.tiff',
save_all=True,
append_images=image_files[1:]
)
In the above code, I first create PIL Image objects from a bytes buffers in order to do this whole thing in-memory but you can probably use .save() and create a bunch of tempfiles instead if I/O isn't a concern.
Once I have all the PIL Image objects, I choose the first image (assuming they were in desired order in base64_images list) and append the rest of the images with append_images flag. The resulting image has all the frames in one output file.
I assume this pattern is extensible to any image format that supports the save_all and append_images keyword arguments. The Pillow documentation should let you know if it is supported.
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/
How can I achieve this with Wand library for python:
convert *.png stack_of_multiple_pngs.tiff
?
In particular, how can I read every png image, pack them into a sequence and then save the image as tiff stack:
with Image(filename='*.tiff') as img:
img.save(filename='stack_of_multiple_pngs.tiff')
I understand how to do it for gifs though, i.e. as described in docs. But what about building a sequence as a list and appending every new image I read as a SingleImage()?
Having trouble figuring it out right now.
See also
With wand you would use Image.sequence, not a wildcard filename *.
from wand.image import Image
from glob import glob
# Get list of all images filenames to include
image_names = glob('*.tiff')
# Create new Image, and extend sequence
with Image() as img:
img.sequence.extend( [ Image(filename=f) for f in image_names ] )
img.save(filename='stack_of_multiple_pngs.tiff')
The sequence_test.py file under the test directory will have better examples of working with the image sequence.
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
I've looked around and read the docs, and found no way or solution, so I ask here. Is there any packages available to use Python to convert a JPG image to a PNG image?
You could always use the Python Image Library (PIL) for this purpose. There might be other packages/libraries too, but I've used this before to convert between formats.
This works with Python 2.7 under Windows (Python Imaging Library 1.1.7 for Python 2.7), I'm using it with 2.7.1 and 2.7.2
from PIL import Image
im = Image.open('Foto.jpg')
im.save('Foto.png')
Note your original question didn't mention the version of Python or the OS you are using. That may make a difference of course :)
Python Image Library: http://www.pythonware.com/products/pil/
From: http://effbot.org/imagingbook/image.htm
import Image
im = Image.open("file.png")
im.save("file.jpg", "JPEG")
save
im.save(outfile, options...)
im.save(outfile, format, options...)
Saves the image under the given filename. If format is omitted, the
format is determined from the filename extension, if possible. This
method returns None.
Keyword options can be used to provide additional instructions to the
writer. If a writer doesn't recognise an option, it is silently
ignored. The available options are described later in this handbook.
You can use a file object instead of a filename. In this case, you
must always specify the format. The file object must implement the
seek, tell, and write methods, and be opened in binary mode.
If the save fails, for some reason, the method will raise an exception
(usually an IOError exception). If this happens, the method may have
created the file, and may have written data to it. It's up to your
application to remove incomplete files, if necessary.
As I searched for a quick converter of files in a single directory, I wanted to share this short snippet that converts any file in the current directory into .png or whatever target you specify.
from PIL import Image
from os import listdir
from os.path import splitext
target_directory = '.'
target = '.png'
for file in listdir(target_directory):
filename, extension = splitext(file)
try:
if extension not in ['.py', target]:
im = Image.open(filename + extension)
im.save(filename + target)
except OSError:
print('Cannot convert %s' % file)
from glob import glob
import cv2
pngs = glob('./*.png')
for j in pngs:
img = cv2.imread(j)
cv2.imwrite(j[:-3] + 'jpg', img)
this url: https://gist.github.com/qingswu/1a58c9d66dfc0a6aaac45528bbe01b82
import cv2
image =cv2.imread("test_image.jpg", 1)
cv2.imwrite("test_image.png", image)
I don't use python myself, but try looking into:
http://www.pythonware.com/products/pil/
import Image
im = Image.open("infile.png")
im.save("outfile.jpg")
(taken from http://mail.python.org/pipermail/python-list/2001-April/700256.html )