Saving image files from Music21 - python

I've downloaded a bunch of .krn files, and I'd like to convert them into images - either pngs or jpgs - using music21. I've tried this:
When I do this:
from music21 import *
op = krnfile
s = converter.parse(op)
s.show()
I see a great image file in the Jupyter Notebook I'm using, but when I try to save that file programatically like this:
s.write(fp = 'outputfile.png', fmt = 'png')
It says:
Music21ObjectException: cannot support showing in this format yet: png
Which seems a little weird since it obviously manages to make an image for display in the notebook.
It looks like maybe I could use LilypondConverter.createPNG(fileName=None) from this, but is installing Lilypond required? I already have MuseScore2 installed, which opens when I call s.show().
Thanks a lot!
Alex

Install musescore on your computer, re-run python -m music21.configure to help it find it and then do:
from music21 import *
op = 'krnfile.krn'
s = converter.parse(op)
fp = s.write('musicxml.png')
# or just s.show('musicxml.png') to test that it works.
If it's a multi-page file, fp will be the path to the first page. It will end in -1 or -01 or -001 etc. You can read through the directory to find other files with the same name until there are no more to get all the images.

If you use n.show('lily.png'), it should create a temporary png file somewhere. Try to use it and an image may open.
Sorry i don't know much yet, I hope it helps.

Related

Image moves or deletes when displaying with PIL

Recently, I have been working on one of my python3 programs and then I wanted to to open a picture. Here is the code that I used to do it:
from PIL import Image
r = Image.open('C:/Users/sudam/OneDrive/Desktop/programming/python/projects/good night app/morning.png' )
r.show()
But as soon as I run this code,the windows photo viewer opens and gives and error saying that the specified file was moved. I tried googling this question but all of the answers I got only worked for python2, but not for python3.
Because you have whitespace in your path you need to use the r"string" format.
Also you need to use:
PIL.ImageShow.show(r)
to show your image.
It's also recommended to check if the file exist before opening any file.
You can do like this:
from pathlib import Path
from PIL import Image, ImageShow
path =r"C:/Users/sudam/OneDrive/Desktop/programming/python/projects/good night app/morning.png"
if Path(path).is_file():
r = Image.open(path)
ImageShow.show(r)
else:
print(f'{path} not exist')

Python Pillow Image.show() Path Issue?

Honest warning—I'm a total beginner.
I'm using Python 3.8.2 in IDLE and sometimes in Spyder.
My goal: to open an image (located in a folder) in Preview using Pillow
My code:
from PIL import Image
my_image = Image.open("flower.jpg")
my_image.show(r"/Users/User/Desktop/flower.jpg")
I run this, and it works! But it only works if the jpg is on the Desktop. I want to put the image in a folder. So I changed my last line of code to something like this:
my_image.show(r"/Users/User/Desktop/folder/flower.jpg")
I put the image in the folder, run the program, and get this error:
**FileNotFoundError: [Errno 2] No such file or directory: 'flower.jpg'**
Oddly, if I put the jpg back onto the Desktop and still use the path with "folder" in it, the program runs successfully and shows me the image.
Is this a problem with the path? How can I use Image.show() to open an image that is located somewhere other than the Desktop?
Thank you!
If you want to open and view an image using an absolute path, you'll have to change this line:
my_image = Image.open(path_to_image_dir)
You've incorrectly passed a string to PIL.Image.show. This doesn't throw an error, since PIL.Image.show happens to take an optional string parameter title, which it will use as a title in the image window. Don't pass any parameters to show, and change "flower.jpg" in the line above to the actual path.

Issue with removing files in python

I'm currently having some issues removing a file in python. I am creating a temporary file for pdf to image conversion. It is housed in a folder that holds a .ppm file and converts it to a .jpg file. It then deletes the temporary .ppm file. Here is the code:
import pdf2image
from PIL import Image
import os
images = pdf2image.convert_from_path('Path to pdf.pdf', output_folder='./folder name')
file = ''
for files in os.listdir('./folder name'):
if files.endswith(".ppm"):
file = files
path = os.path.join('folder name',file)
im = Image.open(path)
im.save("Path to image.jpg")
im.close()
os.remove(path)
The issue is at the end in the os.remove(path). I get the following error:
PermissionError: [WinError 32] The process cannot access the file because it is being used by another process: 'path to ppm file'
I would appreciate any help and thanks in advance.
Not really the answer to your question, but you can just output in the correct format at the start, and avoid the issue in the first place:
pdf2image.convert_from_path('Path to pdf.pdf', output_folder='./folder name', fmt='jpg')
To actually answer your question, I'm not sure why you're having the issue, because really the close() should prevent this problem. Perhaps check out this answer and try using a with statement? Or maybe the permissions release is just delayed, I'm curious what throwing that remove in a loop for as long as it throws an exception would do.
Edit: To set the name, you'll want to do something like:
images = pdf2image.convert_from_path('Path to pdf.pdf', output_folder='./folder name', fmt='jpg')
for image in images:
# Save the image
The pdf2image documentation looks like it recommends using a temporary folder, like in this example, and then you can just .save(...) the PIL image:
import tempfile
with tempfile.TemporaryDirectory() as path:
images_from_path = convert_from_path('/home/kankroc/example.pdf', output_folder=path)
# Do something here
Edit: I realized that the reason it was in use is probably because you need to close() all the images in images. You should read up on the pdf2image documentation and about the PIL images that it spits out for more details.

Convert EMF/WMF files to PNG/JPG

I am receiving an form upload with a Word docx document. I got all the parsing done successfully. I have to then display that Word document on the web.
The problem I am running into at this moment is that I have embedded EMF files (that the PIL library recognizes as WMF format), and I cannot figure how to convert them to something that can be displayed on the web (arbitrarily chosen PNG).
The code is somewhat simple:
im = PIL.Image.open(StringIO.StringIO(data))
fmt = im.format
if (fmt == 'WMF'):
fmt = 'PNG'
output = StringIO.StringIO()
im.save(output, format=fmt)
data = output.getvalue()
output.close()
return '''<img src="data:image/{0};base64,{1}" />'''.format(fmt, base64.encodestring(data))
The error i get is:
IOError: cannot find loader for this WMF file
These Word documents come from average user that may just have cut-and-paste images from the web or insert from file.
Is there a solution for me on a linux system?
Thanks.
EDIT:
To my defense, I tried to upload that document to google drive and the image is not displayed either. Maybe there are no simple solutions?
pip install Pillow
from PIL import Image
Image.open("xxx.wmf").save("xxx.png")
I found it easier to use the Wand package for such conversion. I tried the previous suggestions without success. So here is what I did:
(BTW, I wanted to convert all '.wmf' files into pdf)
import os
from wand.image import Image as wima
folder='C:/Users/PythonLover/Pictures/pics'
for oldfilename in os.listdir(folder):
if oldfilename.endswith(".wmf"):
with wima(filename=folder+'/'+oldfilename) as img:
newfilename = oldfilename.split('.')[0]+'.pdf'
newfilename = folder+'/'+newfilename
img.format = 'pdf'
img.save(filename=newfilename)
You need to understand what you are dealing with in order to see why what you are attempting to do is problematic. WMF files (or the more recent EMF and EMF+ formats) require Windows GDI to render the image it describes. So there is no simple solution when you are converting this format outside of Windows, since you need to replicate the GDI API.
One solution is to use the unoconv tool which relies on the UNO bindings for OpenOffice/LibreOffice. A second solution would use the pyemf module to decode the input, and then a second tool (to be done by you) would render it.
You may use libwmf to convert image to SVG and then pyrsvg to convert to PNG (described in another question).
I haven't found libwmf project website, but Debian (and Ubuntu) has package libwmf-bin that contains wmf2svg utility.
WMF stands for Windows Metafile; EMF stands for Enhanced Metafile. These files drive Windows to display an image. Within Microsoft Office applications it is a standard format for vector images. The Metafile is managed by Microsoft and is not an open format.
Since libreoffice is an alternative to Microsoft Office in Linux environment, it would be better to have a small service where we can use libreoffice and imagemagick(install them if you cannot).
Then a language independent solution would be this:
build a libreoffice container using this Dockerfile(or install libreoffice)
FROM linuxserver/libreoffice:7.2.2
start a RESTful API(or RPC API) in the container receiving an emf file and sending back a png file
in the service we implement the following function:
a. save the emf file in a path, say /mnt/b.emf
b. convert the file by the command libreoffice --headless --convert-to png /mnt/b.emf in any language; for example, in Python we can use the snippet at the end of this answer.
c. read the png file /mnt/b.png and send it back via the API
use imagemagick to trim the white space of the resultant image
Here is the Python implementation:
from os
from flask import Flask, jsonify, request
def emf_to_png(im):
temp_emf_path = '/tmp/temp.emf'
temp_png_path = '/tmp/temp.png'
with open(temp_emf_path, 'wb') as f:
f.write(im)
command = f"libreoffice --headless --convert-to png {temp_emf_path} --outdir /tmp"
os.system(command)
command = f'convert {temp_png_path} -fuzz 1% -trim +repage {temp_png_path}'
os.system(command)
f = open(temp_png_path, 'rb')
png_b = f.read()
f.close()
os.remove(temp_emf_path)
os.remove(temp_png_path)
return png_b
app = Flask(__name__)
#app.route("/convert/emf2png", methods=["POST"])
def start_training():
try:
emf = request.data
png_b = emf_to_png(emf)
return jsonify(code=200, message="succeed", data=png_b)
except Exception as e:
return jsonify(code=100, message=f"error {e}")
if __name__ == '__main__':
app.run("0.0.0.0", port=1111)
References:
https://stackoverflow.com/a/28749719/3552975
https://ask.libreoffice.org/t/convert-to-jpg-wmf-on-linux-resolution-issue/44578
I have a similar problem, but I used bash and inkscape to convert the images to png format, I attach the small script that performs this task for me:
#!/usr/bin/bash
for file in *.emf; do
export_name=$(echo $file | sed 's/\.emf$/.png/');
echo inkscape $file -e $export_name
inkscape $file -e $export_name
done
For more information, check the inkscape option:
inkscape --help
# -e, --export-png=FILE NAME
On linux you can use inkscape to do the conversion from .emf to .png with the help of command (pip install Command)
I also tried pillow and wand before, they both only works on windows.
import command
path_emf = 'path_to_your_emf_file'
path_png = 'path_to_save_png_file'
command.run(['inkscape', '-e', path_png, path_emf])

Where does Python Imaging LIbrary Save Objects

I am using the Image.save method from PIL and I cannot find where the file is being placed. I have done a system search yet still no luck.
My code looks like this:
print imageObj.save(fileName, "JPEG")
and gives the proper None response to say that it is working. Any idea where they go and how I can find them?
Thanks!
You should pick a location to save the image when setting the filename variable.
filename = "/Users/clifgray/Desktop/filename.jpeg"
imgObj.save(filename)

Categories