14

Is there a way to get the dimensions that the results of a Text[] will occupy within a Graphics[]? Specifically, if I run something like

Graphics[Text[
  Style["how quickly daft jumping zebras vex", 
   FontFamily -> "Verdana", FontSize -> 20]], PlotRange -> 1]

how can I get the dimensions relative to the coordinate system of the text?

edit: I have the PlotRange->1 in there because I'm using the text on a larger field and manipulating the text and other graphics using transformations that depend on the coordinate system. The text also is likely to change (hence my using sample text), so I'd like to have the transformations depend on measurements derived from the text (taking into account the styling of it).

Isaac
  • 3,189
  • 1
  • 29
  • 35
  • Just a point, PlotRange is irrelevant in this object, even though it is visible in the AbsoluteOptions. You probably want Graphics[Text[ Style["how quickly daft jumping zebras vex", FontFamily -> "Verdana", FontSize -> 20]], ImageSize -> 400, AspectRatio -> 0.1] – Verbeia Feb 12 '12 at 23:21
  • 1
    @Verbeia: but why 400 and 0.1? I had the PlotRange->1 in there because I'm using text on a larger field and manipulating the text and other graphics using transformations that depend on the coordinate system... and I suppose I should edit that information into the question. – Isaac Feb 12 '12 at 23:25
  • Isaac, they were the round numbers that fit nicely on my system. I should probably have said "something like" that code. By the say, Chris' answer is a much better approach for your particular problem so I will delete my partial answer. Hopefully someone poses a question soon where these CurrentValue options are the answer, because I think they are worth documenting. – Verbeia Feb 13 '12 at 00:27
  • 1
    @Verbeia please pose a question yourself even if you know the answer. I would like to read more about CurrentValue and fonts. – Mike Honeychurch Feb 13 '12 at 04:39
  • @MikeHoneychurch Ok :) http://mathematica.stackexchange.com/q/1684/8 and I actually don't know the answer – Verbeia Feb 13 '12 at 04:56
  • Could you explain how you want to use this information? Maybe there is another way to accomplish what you want to do without needing to get the text object dimensions (in case that turns out to be very difficult) – Szabolcs Feb 13 '12 at 06:41
  • @Szabolcs: On occasion, I have used Photoshop to create an animated GIF that had text scrolling through the image (generally, text too long to view in whatever size the image had to be). While it's not terribly hard to do in Photoshop, it occurred to me that I ought to be able to almost completely automate the process so that given a graphic size, some text, and where to have it scroll through, the mechanics of generating appropriate frames so that the text scrolled at a uniform length-per-second rate would be taken care of. Chris's answer with Andy's comment is sufficient to make it work. – Isaac Feb 13 '12 at 06:50
  • @Szabolcs: http://i.stack.imgur.com/Pkadw.gif is an example of what I've got it doing now, using Rasterize[ ... , "RasterSize"] with Style[ ... , LineBreakWithin -> False] (the bits of scrolling text are fragments of lyrics from different songs). – Isaac Feb 13 '12 at 07:02

2 Answers2

8

Here you go:

t = Text[Style["how quickly daft jumping zebras vex", 
    FontFamily -> "Verdana", FontSize -> 20]];
{l, h} = d = Rasterize[t, "RasterSize"];
Graphics[{Green, Rectangle[{0, 0}, d], Black,
  Inset[t]}, PlotRange -> {{0, l}, {0, h}}, ImageSize -> l]

enter image description here

Chris Degnen
  • 30,927
  • 2
  • 54
  • 108
  • 1
    I can definitely use this to get the job done, but it's in terms of image size/pixels, rather than coordinates... – Isaac Feb 13 '12 at 00:22
  • 1
    Actually... it looks like it's rasterizing the output form of the Text[] command: http://i.stack.imgur.com/YkeeK.png is the output of Rasterize[Text[Style["Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris varius imperdiet lectus nec bibendum. Maecenas felis ipsum, elementum mattis tristique id, mollis a nisl. Nulla magna dolor, ullamcorper eleifend posuere non, vehicula ut augue.", FontFamily -> "Hypatia Sans Pro", FontSize -> 20], {0, 0}, {0, 0}]], so Rasterize[..,"RasterSize"] gives {724, 104} which isn't the length of the text on a single line... – Isaac Feb 13 '12 at 00:34
  • @ Isaac - You can inset the resultant graphics into another graphic using coordinates, e.g. Graphics[{Red, Rectangle[{0, 0}, {1, 0.2}], Inset[%, {0, 0}, {0, 0}]}, PlotRange -> {{0, 1}, {0, 0.2}}, ImageSize -> 400] – Chris Degnen Feb 13 '12 at 00:44
  • The problem is the line wrapping—I want the width of the rendered text all on one line, but Rasterize[] is wrapping the text at the width of the window. – Isaac Feb 13 '12 at 00:46
  • 4
    You can also use the option LineBreakWithin -> False in the options passed to Style if line wrapping is what you are trying to avoid. – Andy Ross Feb 13 '12 at 02:35
  • @AndyRoss: That did it! – Isaac Feb 13 '12 at 06:45
  • @Isaac I was writing up another answer but I realized that it would not add too much, so I only want to mention that Offset coordinates are important here: `text = Style["how quickly daft jumping zebras vex", FontFamily -> "Verdana", FontSize -> 20];
    box = Rasterize[text, "BoundingBox"][[1 ;; 2]];
    
    Graphics[
     {Text[text, {0, 0}, {-1, -1}],
      EdgeForm[Thin], FaceForm[None],
      Rectangle[{0, 0}, Offset[box, {0, 0}]]},
     PlotRange -> All
    ]`
    
    – Szabolcs Feb 13 '12 at 07:18
  • @Isaac It should have been possible to do it with ExportPacket and PageWidth -> Infinity, but I failed: http://library.wolfram.com/conferences/devconf99/hintonimportexport/Links/ImportExport19991021_lnk_29.html – Szabolcs Feb 13 '12 at 07:19
  • @Isaac, did you ever get a direct answer in coordinate units? I've asked a similar Q about extracting bounding boxes and still looking for a general method. – alancalvitti Mar 16 '15 at 17:21
  • @alancalvitti: I think I just ended up using pixels/image size rather than coordinates, but I don't remember for sure. – Isaac Mar 16 '15 at 22:02
  • This answer seems incorrect. When I do With[{nmax = 10}, Graphics[ Table[With[{v = StringJoin @@ Table["a", Mod[n, 2, 1]*10]}, Inset[Text[v], Offset[Rasterize[Text[v], "RasterSize"]/2, {0, n/nmax}], {0, 0}]], {n, 1, nmax}] ]] my text is misaligned. The other answer gives a correctly aligned graphic. – Jason Gross Jan 10 '18 at 17:54
  • @JasonGross Can you please add here as a comment the code that gives the correctly aligned graphic because it is not clear what you mean. – Chris Degnen Jan 10 '18 at 20:40
  • With[{nmax = 10}, Graphics[Table[ With[{v = StringJoin @@ Table["a", Mod[n, 2, 1]*10]}, Inset[Text[v], Offset[ImageDimensions[ImageCrop[Graphics[Text[v]]]]/2, {0, n/nmax}], {0, 0}]], {n, 1, nmax}]]] has all of the text horizontally aligned on the left, which is what I expect when I specify that the x-location text-width/2 should line up with the center of the text. However, neither one of these works with pdf export (see https://mathematica.stackexchange.com/questions/163457/how-does-pdf-export-compute-the-size-of-the-bounding-box-of-inset) – Jason Gross Jan 10 '18 at 20:48
3

Faced with the same problem, I found this solution:

a = Text[Style["vvddfhfh", 40], {0, 0}];
{width,height} = ImageDimensions[ImageCrop[Graphics[a]]]

which gives me the size of the actual rendering of the styled text, as opposed to the render of the output form of the Text command seen in the other answer

Marco83
  • 213
  • 1
  • 2
  • 4