4
$\begingroup$

According to the Documentation (second example under "Properties & Relations"),

AbsoluteThickness is independent of the image size

Let us check (Mathematica 13.0.0 on Windows with 96 DPI display resolution, so I set AbsoluteThickness[72/96] in order to get a line of 1 px width):

Table[Image[
  ImageResize[
   ImageTake[ImageCrop@
     Rasterize[Graphics[{AbsoluteThickness[72/96], Line[{{0, 0}, {0, 1}}], 
        PlotRange -> {{-is, is}, {-.1, 1.1}}}], ImageSize -> is], 10], Scaled@10, 
   Resampling -> "Constant"], Magnification -> 1], {is, 10, 300, 20}]

First /@ ImageDimensions /@ %

screenshot

{20, 10, 20, 20, 10, 20, 20, 10, 20, 20, 10, 20, 20, 10, 20}

Apparently, it depends on ImageSize in a strange and unpredictable way. Also, the color isn't always Black as it should be.

Let us check it with version 12.3.1 on the same machine (I set AbsoluteThickness[1], because in this version 1 pt == 1 px):

Table[Image[
  ImageResize[
   ImageTake[
    ImageCrop@
     Rasterize[
      Graphics[{AbsoluteThickness[1], Line[{{0, 0}, {0, 1}}], 
        PlotRange -> {{-is, is}, {-.1, 1.1}}}], ImageSize -> is], 10],
    Scaled@10, Resampling -> "Constant"], Magnification -> 1], {is, 
  10, 300, 20}]

First /@ ImageDimensions /@ %

screenshot

{20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20}

The line thickness is consistent but equals 2 px instead of 1 px, and the rendering of the line caps depends on ImageSize in an unpredictable way. Also, the color isn't Black as it should be.

And with version 8.0.4 on the same machine:

Table[Image[
  ImageResize[
   ImageTake[
    ImageCrop@
     Rasterize[
      Graphics[{AbsoluteThickness[1], Line[{{0, 0}, {0, 1}}], 
        PlotRange -> {{-is, is}, {-.1, 1.1}}}], "Image", 
      ImageSize -> is], 10], Scaled@10], Magnification -> 1], {is, 10,
   300, 20}]

First /@ ImageDimensions /@ %

screenshot

{20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20}

Similar to version 12.3.1.

Is it a bug? How can I get consistent rendering with version 13?

$\endgroup$
7
  • 1
    $\begingroup$ @DanielHuber What do you mean? After Rasterize we have Image, not Graphics. Image can't have any graphics directives, including AbsoluteThickness. $\endgroup$ Commented Jan 18, 2022 at 10:34
  • 1
    $\begingroup$ If you resize the image after rasterizing it, the absolute thickness is not retained. $\endgroup$ Commented Jan 18, 2022 at 11:04
  • 4
    $\begingroup$ The assumption that each line should render as one pixel thick is inaccurate, since it depends on the center of the Line primitive being center aligned with an element on the grid (in this case, a pixel). Seeing that the FrontEnd works in a point-based coordinate system, the odds of your primitive aligning perfectly with the grid are not particularly favorable. As for why it is not black, Antialiasing. $\endgroup$
    – ihojnicki
    Commented Jan 18, 2022 at 14:39
  • 1
    $\begingroup$ @ihojnicki Thank you very much! You can post it as an answer, and I'll accept it. With Antialiasing -> False I get consistent one-pixel thick rendering in all mentioned versions, and the line is Black as it should. $\endgroup$ Commented Jan 18, 2022 at 15:07
  • 1
    $\begingroup$ On Windows, there is another factor comes into play: the system-wise scaling factor. AFAIK, on modern laptop, Windows detects hi-res display and automatically suggests a non-100% scaling. On my laptop it's 125%, so I have Lookup[SystemInformation["Devices","ConnectedDisplays"],"Scale"][[1]]==1.25*96/72. $\endgroup$
    – Silvia
    Commented Jan 21, 2022 at 14:05

1 Answer 1

3
$\begingroup$

As it becomes clear from the discussion in the comments, the cited Documentation statement isn't about rendering of the line primitives. It is about an abstract vector graphics scene, without any assumption about how it will be represented physically.

By applying Rasterize we render the abstract scene using some algorithm and obtain a discrete approximation of the original abstract vector object. Depending on the algorithm, the approximation can represent the features of the original more or less closely.

Citing ihojnicki,

The assumption that each line should render as one pixel thick is inaccurate, since it depends on the center of the Line primitive being center aligned with an element on the grid (in this case, a pixel). Seeing that the FrontEnd works in a point-based coordinate system, the odds of your primitive aligning perfectly with the grid are not particularly favorable. As for why it is not black, Antialiasing. – ihojnicki

Apparently, by default we have antialiasing turned on for Graphics what is the reason for the effects demonstrated in the question. By turning antialiasing off we get consistent one-pixel thick Line rendering in all mentioned versions, and the color is Black as it should:

Table[Image[
  ImageResize[
   ImageTake[ImageCrop@
     Rasterize[Style[
       Graphics[{AbsoluteThickness[72/96], Line[{{0, 0}, {0, 1}}], 
         PlotRange -> {{-is, is}, {-.1, 1.1}}}], Antialiasing -> False], ImageSize -> is],
     10], Scaled@10, Resampling -> "Constant"], Magnification -> 1], {is, 10, 300, 20}]
First /@ ImageDimensions /@ %

output

{10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10}
$\endgroup$

Your Answer

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

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