1

With Python turtle I'm trying to save the canvas as a png. I've researched it and found a way to save it as an eps file without any modules, but I'm finding it hard to convert the eps file into a png.

Is there a way to convert eps to png without downloading another module? If not can someone tell me more about ImageMagick, because I have looked at it, but I'm confused how to use it? I've also seen it being linked to linux and is it outdated?

If not converting eps to png, is there a even simpler way to save the canvas as a png?

Btw I have seen this, but I don't understand it :/ How to convert a .eps file to a high quality 1024x1024 .jpg?

fmw42
  • 46,825
  • 10
  • 62
  • 80
Jared Parker
  • 390
  • 2
  • 3
  • 16
  • Imagemagik is a good place to start, this blog has something pour example http://peterhansen.ca/blog/convert-eps-to-png-with-imagemagick.html . – Simon Hobbs Aug 23 '17 at 00:06
  • Possible duplicate of [Convert images drawn by turtle to PNG in Python](https://stackoverflow.com/questions/35629520/convert-images-drawn-by-turtle-to-png-in-python) – DYZ Aug 23 '17 at 01:59
  • Can you save as SVG instead? – o11c Aug 05 '18 at 00:54

2 Answers2

1

From the link you show, there is this Imagemagick command:

convert -density 300 image.eps -resize 1024x1024 image.jpg

Most EPS files are vector images. They have no physical size in pixels, since it a vector drawing with commands that describe how to draw each object. It is not a raster image containing pixels and does not have any particular pixel set of dimensions.

So with vector files, you set the printing density to tell Imagemagick (which passes it off to Ghostscript to do the rasterizing work) to convert the vector data to raster data and then save it as a raster format output image. Nominal density is 72 dpi (sometimes 92 or 96). So if you use -density 288 with the following command:

convert -density 288 image.eps image.png

It would result in an image that is 4 times larger in each dimension than if you just did

convert image.eps image.png

which for default dpi of 72 would be the same as

convert -density 72 image.eps image.png

Note that 72*4=288.

Now you have a large high quality raster png, especially if the eps file was line drawing with thin lines like blue-prints.

However if that is too large and you want to reduce it back to its nominal size by 1/4, you could do (note 1/4 = 25%)

convert -density 288 image.eps -resize 25% image.png

This process is sometimes called supersampling and would produce a better looking result than just doing

convert image.eps image.png

In the original command, they decide to get a high quality raster image and just resize to 1024x1024.

So you can resize to any size you want after producing a high definition raster image from the EPS vector image.

The larger the density you use, the higher the quality will be in the PNG, but it will take longer to process. So you have to trade time vs quality and pick the smallest density that produces good enough quality in a reasonable amount of time.

I do not know if Python Wand supports setting the density or if it supports reading PDF file, which requires Ghostscript. But you can use Python Subprocess module to make a call to an Imagemagick command line. See https://www.imagemagick.org/discourse-server/viewtopic.php?f=4&t=32920

fmw42
  • 46,825
  • 10
  • 62
  • 80
1

I've been having problems with ImageMagick having had its security policy changed so it can't interact with Ghostscript. (for good reason... but it's questionable that it doesn't allow you to locally override the default policy so web apps can be protected while whitelisted uses can still work.)

For anyone else slamming into convert: not authorized, here's how to invoke Ghostscript directly:

gs -dSAFER -dEPSCrop -r300 -sDEVICE=jpeg -o image.png image.eps
  • -dSAFER puts Ghostscript into sandboxed mode so you can interpret untrusted Postscript. (It should be default, but backwards compatibility.)
  • -dEPSCrop asks Ghostscript to not pad it out to the size of a printable page. (details)
  • ImageMagick's -density 300 becomes -r300 when it invokes Ghostscript. (details)
  • -sDEVICE is how you set the output format (See the Devices section of the manual for other choices.)
  • -o is a shorthand for -dBATCH -dNOPAUSE -sOutputFile= (details)

You could then use ImageMagick's mogrify command to resize it to fit exact pixel dimensions:

mogrify -resize 1024x1024 image.png

(mogrify is like convert but replaces the input file rather than writing to a new file.)

UPDATE: In hindsight, I should have checked whether Pillow supported EPS before posting that first answer.

The native Python solution would be to use Pillow's support for invoking Ghostscript (like ImageMagick in that respect, but with a native Python API).

However, Pillow's docs don't explain how they arrive at a size in pixels and only take an optional multiplier (scale) for the default size rather than an absolute DPI value.

If that doesn't bother you, and you've got both Pillow and Ghostscript installed, here's how to do it without ImageMagick:

#!/usr/bin/env python3

from PIL import Image

TARGET_BOUNDS = (1024, 1024)

# Load the EPS at 10 times whatever size Pillow thinks it should be
# (Experimentaton suggests that scale=1 means 72 DPI but that would
#  make 600 DPI scale=8⅓ and Pillow requires an integer)
pic = Image.open('image.eps')
pic.load(scale=10)

# Ensure scaling can anti-alias by converting 1-bit or paletted images
if pic.mode in ('P', '1'):
    pic = pic.convert("RGB")

# Calculate the new size, preserving the aspect ratio
ratio = min(TARGET_BOUNDS[0] / pic.size[0],
            TARGET_BOUNDS[1] / pic.size[1])
new_size = (int(pic.size[0] * ratio), int(pic.size[1] * ratio))

# Resize to fit the target size
pic = pic.resize(new_size, Image.ANTIALIAS)

# Save to PNG
pic.save("image.png")

ssokolow
  • 14,938
  • 7
  • 52
  • 57