Skip to content

robust resolution in jpeg and gif #404

@drbergman

Description

@drbergman

As hinted at in a recent Slack post1, GIF resolution depends on the domain size. The same is true for make jpeg.

Something like

magick -density 300 $(OUTPUT)/s*.svg -resize 1024x1024 $(OUTPUT)/out.gif

works to resolve this (and a similar command for the jpeg target). The issue with this simple fix is that for larger domains, this would rasterize at much higher resolutions than necessary (don't always need -density 300) only to then lose all that resolution on a resize (-resize 1024x1024).

So, something more robust would be needed. I see two options:

  • do the math in the Makefile
  • doing the math when writing the SVG2

Either way, exposing these through Makefile variables would be a nice touch for users.

Proposed solution

Simplest is to introduce new Makefile variables that set defaults that can be customized:

MAGICK_DENSITY := 96
MAGICK_RESIZE_X := 1024
MAGICK_RESIZE_Y := 1024
MAGICK_RESIZE := $(MAGICK_RESIZE_X)x$(MAGICK_RESIZE_Y)

jpeg: 
	magick mogrify -density $(MAGICK_DENSITY) -format jpg -resize $(MAGICK_RESIZE) $(OUTPUT)/s*.svg

gif:
	magick -density $(MAGICK_DENSITY) $(OUTPUT)/s*.svg -resize $(MAGICK_RESIZE) $(OUTPUT)/out.gif

Notes:

  1. This simplifies the jpeg target down to one line, eliminating need for intermediate files to store height and width
  2. I am now getting a deprecation warning for magick convert (currently used in the gif target), so we'll eventually need to migrate to this new syntax, but I don't know if that will disrupt others with an older installation of magick...

For future reference

Here's my understanding of how all the numbers are computed after looking into this:

  1. PhysiCell records in the <svg> element the width and height attributes. These are the simulation domain size plus necessary padding for title text and colorbar (if needed). Title text padding scales with the domain size so if you display the snapshot as a 1-inch-wide figure, the text is always the same size. The colorbar has a fixed padding (which is what causes it to render different widths and sometimes pushes the label outside the clipping mask.
  2. Magick interprets these as the number of pixels in each dimension and computes a desired physical size of the image in inches using 1"=96pixels. E.g. 960 pixels --> 10 inches
  3. The -density flag converts this desired size (in inches) to pixels, treating the flag value as dpi. E.g., -density 300 would take the 10" above and set that dimension to rasterize to 300 x 10 = 3000 pixels.
  4. Rasterize at these dimensions
  5. If -resize is provided, then downsample (if either dimension has more pixels from above then requested in this flag), preserving the aspect ratio. Minor note: if the -resize value ends with ! (e.g. -resize 1000x1000!), this will force both dimensions; i.e. not preserve the aspect ratio. To finish our example, if -resize 1000x1000 and the rasterized intermediate was 3000x6000 pixels, the final image will be 500x1000 pixels

Footnotes

  1. When we reduce the domain size via the config file, we're noticed that the gifs generated with magick appear to have lower resolution. Is there a way to maintain or improve the resolution when using a smaller domain? The output SVGs seem to retain their quality.

  2. width and height attributes control the resolution. Those attributes are dependent on the simulation domain size, but are not equivalent due to padding for text / colorbar, so those could be good targets to put default sizes.

Metadata

Metadata

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions