8
$\begingroup$

I am looking to generate image masks using Graphics. For this, the requirements are that:

  1. The rasterized mask must have the exact same dimensions as the image with which it will be used.
  2. The image coordinates system (as described in the documentation of ImageValue, under Details) must line up perfectly with the Graphics coordinate system.

Neither seems to work readily.

Mask has an incorrect size

dims = {20, 20};

mask = Rasterize[
  Graphics[{},
   PlotRange -> Transpose[{{0, 0}, dims}], ImageSize -> dims,
   PlotRangePadding -> None
  ],
  ImageResolution -> 72
 ]

The mask is of the wrong size. ImageDimensions[mask] gives {20, 22}.

Coordinates don't line up

Example code:

dims = {21, 21};

pix = Image@ReplacePart[ConstantArray[0, dims], {{11, 11}} -> 1]

mask = Rasterize[
  Graphics[{Disk[dims/2, 6]},
   PlotRange -> Transpose[{{0, 0}, dims}], ImageSize -> dims,
   PlotRangePadding -> None
  ],
  ImageResolution -> 72
 ]

The image size is odd, so there is a middle pixel. pix visualizes this pixel. mask draws a disk around it. But the pixel is clearly not in the middle of the disk:

Magnify[mask + pix, 5]

enter image description here

Attempted workarounds

  • ImageMargins -> 0, ImagePadding -> None does not help.
  • Adding ImageSize to Rasterize as well, in addition to Graphics, does not help.
  • RasterSize can force a specific image size, but it does not help with alignment

System information

Mathematica 13.0.1, macOS 10.14.6 (Mojave), and a retina screen

$\endgroup$
8
  • $\begingroup$ Use RasterSize -> dims instead? ImageSize for Rasterize is only the display dimensions… $\endgroup$
    – SHuisman
    Mar 8 at 10:29
  • $\begingroup$ I'm not really a fan of RasterSize. I suspect what it does is a rescaling after creating an image. The ImageSize and the ImageResolution together should give a good result. The reason why I worry about such rescaling is that it might mess up the alignment between the image coordinates and the graphics coordinates. $\endgroup$
    – Szabolcs
    Mar 8 at 11:41
  • 1
    $\begingroup$ Would RegionImage be of use? $\endgroup$
    – Greg Hurst
    Mar 8 at 22:59
  • 1
    $\begingroup$ @Szabolcs Why do you suspect such a thing? I've never noticed that, and i always use RasterSize. Even the help of Rasterize says: ImageSize => final displayed image size in printer's points. (So only display!). $\endgroup$
    – SHuisman
    Mar 9 at 10:48
  • 1
    $\begingroup$ @AlexeyPopkov The first problem can be reproduced in v13.0.0 Linux (Wolfram Cloud): i.stack.imgur.com/8KGMW.png $\endgroup$
    – xzczd
    Mar 9 at 12:37

1 Answer 1

6
$\begingroup$

The first behavior seems to be a bug of v13. In v12.3.1 it works as expected:

enter image description here

As to the second example, this seems to be another bug introduced in v12.3.1 or earlier, because v9.0.1 works as expected:

$Version
dims = {21, 21};
pix = Image@ReplacePart[ConstantArray[0, dims], {{11, 11}} -> 1];
mask = Rasterize[Graphics[{Disk[dims/2, 6]},PlotRange -> Transpose[{{0, 0}, dims}]
    (*,ImageSize -> dims*), PlotRangePadding -> None], "Image", 
    ImageResolution -> 72, RasterSize -> dims];
(* mask + pix *)
ImageAdd[mask, pix]

enter image description here

For comparison here's v12.3.1 result:

enter image description here

Remark

  1. I've removed the ImageSize option in Graphics and add the RasterSize option to Rasterize, otherwise the alignment will be wrong even in v9. (Yeah, once again, this seems to be a bug, in v9. )

  2. I've used ImageAdd in v9 because the syntax mask + pix is introduced in v11.1.

  3. I've explicitly set the second argument of Rasterize to "Image" in v9, because the default setting before v11.2 is "Graphics".

$\endgroup$
9
  • $\begingroup$ I think the PlotRange is correct. For example, for a 1-by-1 image it should go from 0 to 1 when using ImageValue coordinates. But the centre of the Disk[] was indeed off. It should have been dims/2. I fixed that. I hope I did not make other mistakes. I'll check a couple of hours later. $\endgroup$
    – Szabolcs
    Mar 8 at 13:20
  • $\begingroup$ It is interesting that uncommenting ImageSize -> dims in the above code in version 8.0.4 reproduces exactly the wrong alignment of version 13. $\endgroup$ Mar 8 at 14:21
  • $\begingroup$ Show[mask, ImageSize -> dims] isn't needed in version 8 and its presence makes the whole comparison invalid because this piece of code converts Image to Graphics which at the next step is rasterized again to Image. I hadn't included this in my check with version 8. $\endgroup$ Mar 8 at 14:29
  • $\begingroup$ @AlexeyPopkov "because this piece of code converts Image to Graphics which at the next step is rasterized again to Image" This doesn't seem to be the case in v9 period. I just checked the InputForm, mask is a Graphics[Raster[…],…] expression, and after Show[…] the InputForm is still a Graphics[Raster[…],…] expression. It's a bit surprising that ImageAdd[mask, pix] works as expected in v8, because ImageDimensions@mask isn't {21,21} in v8 and v9, it's {360, 378}! I'm not sure if this is by design or another bug in v8/v9 period. $\endgroup$
    – xzczd
    Mar 8 at 14:57
  • 2
    $\begingroup$ @xzczd I wouldn't rely on the assumption that the WRI staff monitors the site. The only way to be sure that the support is aware of the problem is to send a report. And bigger weights are assigned to the problems reported by many people. $\endgroup$ Mar 9 at 12:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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