3
$\begingroup$

Update: I've determined that my problem is partly specific to my 4k display. When I run the exact same code on a 2k display, I have no trouble at all, despite MMA still treating $ImageResolution as 144. Additionally, some rasterized Graphics don't play well with Dynamics Graphics Primitives in v12.2. See below

The following code is flawless in v12.0, but in v12.2 it becomes almost unresponsive with large values for size. For instance, a size of 1500 is almost unusable on my machine in v12.2. With the graphic open, I literally can't even use the mouse to select text inside of a MMA notebook.

size = 500;
Show[
 Rasterize@Graphics@Disk[], 
 Graphics@{Red, AbsolutePointSize@10,
 Dynamic@Point@MousePosition["Graphics", {0, 0}]},
ImageSize -> size]

Original: I have a GUI that is using Show to render a dynamically updated graphic on top of a large, rasterized graphic. In version 12.0, this isn't an issue because you can easily set the ImageSize and MMA displays it accordingly. In version 12.1 $ImageResolution was introduced and things get tricky. For instance, in 12.2 (using macOS 10.14.6) Graphics is ignoring $ImageResolution, which results in a large graphics object that can cause the Front End to become very sluggish (even crash), specifically when combining the graphics with Dynamic content (such as a Dynamic@MousePosition["Graphics"]). In the following example, setting the $ImageResolution doesn't work.

Unprotect[$ImageResolution];
$ImageResolution = 72;
Graphics[{Disk[]}, ImageSize -> 500]
ImageDimensions@%
{1000, 998}

Any clue how to force Graphics to use the value I'm assigning?

Note that in that example the final size of the Graphics is identical to the same code when run in 12.0, but it takes up more memory and gives me trouble when displaying larger graphics (such as over 20" wide). In many cases it is causing MMA to completely crash. My interactive graphics are never causing crashes in 12.0.

Also note that I know Graphics is the function giving the trouble, consider the following;

Show[
 Rasterize[ Graphics@Disk[], RasterSize -> 500],
ImageSize -> 500]
ImageDimensions@%
{500, 499}
Show[
 Rasterize[Graphics@Disk[], RasterSize -> 500],
 Graphics@{},
ImageSize -> 500]
ImageDimensions@%
{1000, 998}

Just including the empty Graphics function is enough to double the actual ImageDimensions of the graphic.

$\endgroup$

1 Answer 1

3
$\begingroup$

Graphics are resolution independent, so $ImageResolution has no real meaning for them. ImageResolution matters when you render the graphic to pixels. i.e. it is a property of the raster.

Your original example of ImageDimensions@Graphics[...] equivalent to ImageDimensions@Image@Graphics[...]. Image[g_Graphics] is an automagic conversion to a raster. Why does Image ignore your setting of $ImageResolution? Don't know, I would have to ask the developer for Image. IIRC in 12.1 it would always use 72.

If you care about the dimensions, always use Rasterize.

$\endgroup$
8
  • $\begingroup$ Graphics primitives are resolution independent, but rendered Graphics in the front end are not. The front end is using $ImageResolution to determine how to render the Graphics primitives in the current environment. When you have a high resolution display, MMA is bumping $ImageResolution from 72 to 144. You reference ImageDimensions converting the Graphics object to an Image, but the front end is basically doing the same thing when it is rendered. In v12.2 the result is a much larger ByteCount for a graphic compared to v12.0, strictly due to the $ImageResolution. $\endgroup$
    – atlasgeo
    May 20, 2021 at 0:33
  • $\begingroup$ Regarding Rasterize, maybe you missed the last two examples. I rasterize my main graphic, specifying the ImageResolution, which gives me the control I need. But in v12.1 and later, when combining a dynamic graphic object with the raster (using Show), the Graphics function hijacks the ImageResolution and the result is a much larger memory footprint, which leads to instability with the dynamic graphics objects. $\endgroup$
    – atlasgeo
    May 20, 2021 at 0:36
  • 2
    $\begingroup$ The FrontEnd does not know nor cares about $ImageResolution. That is simply the default value that Rasterize will pass to the FrontEnd when it asks the FrontEnd to rasterize something. When the FrontEnd renders a graphic on screen, it is going to match the density of the display. $\endgroup$
    – ihojnicki
    May 20, 2021 at 1:07
  • 1
    $\begingroup$ The second Graphic isn't hijacking anything. The follow up call to ImageDimensions@% causes the output to be rasterized. If you need convincing, try it in LinkSnooper (Evaluation > Notebook's Kernel > LinkSnooper). You will see the Kernel calling back into the FrontEnd via ExportPacket when you evaluate ImageDimensions@%. $\endgroup$
    – ihojnicki
    May 20, 2021 at 1:07
  • 1
    $\begingroup$ As for 12.0 and earlier vs 12.1 and later, 12.1 and later are HiDPI aware. 12.0 and earlier are not. CurrentValue["WindowResolution"] will tell you resolution of the monitor the notebook is located on, which is probably more than 72dpi. If you leave $ImageResolution set to Automatic, Rasterize will end up using Max[CurrentValue[{"ConnectedDisplays", "Resolution"}]]. If you have an example that crashes, you should supply that example to tech support. $\endgroup$
    – ihojnicki
    May 20, 2021 at 2:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.