# How to embed an image into a string?

Note: The bug described in the post is in Mathematica 9, and has been fixed in 10.0.

The documentation for String contains the following statements:

Strings can contain any sequence of ordinary and special characters:

Strings preserve internal formatting:

Strings can have any expression embedded:

"ab \[Integral]\!$$\*FractionBox[\(1$$, $$x$$]\)\[DifferentialD]x cd"

Strings can contain graphics:

"ab \!$$\*\nGraphicsBox[DiskBox[{0, 0}],\nImageSize->{34., Automatic}]$$ cd"

So I assumed that an image could be inserted anywhere in the string. I tried to copy images in different ways:

• from other Mathematica notebook cells, explicitly Imported before
• from web pages opened in a browser
• from image editors e.g. Paint
• taking screenshots

and paste them into expressions (as list elements, function arguments etc) and it all worked perfectly well. But when I try to paste images into string literals, then the string looks good (with the image embedded) in the input cell, but the expression gets corrupted when evaluated -- it is not even a String anymore:

(* In[1]:= *) logo = Import["http://wolfram.com/favicon.ico", "Image"]
(* Out[1]= *) 

(* In[2]:= *) Shallow["Mathematica ", 1] (* The image was copy-pasted from the previous cell *)
(* Out[2]//Shallow= *) Times[<<5>>]

Question 1: Is it a bug?

It is interesting that inserting plots into string literals works well.

I need a solution to insert images into strings programmatically. It could also serve as a workaround for this bug. I was not able to find a built-in function that does exactly this, so I tried to use "\!$$\*…$$" markup mentioned in the documentation for String. I was not able to find a documentation for this markup, so I started experimenting.

Question 2: Is there a complete documentation for this markup?

After several attempts, I ended up with the following function:

(* In[3]:= *) imageToString[image_Image] :=
"\!$$\*" <> ToString[ToBoxes[image], InputForm] <> "$$";

(* In[4]:= *) "Mathematica " <> imageToString[logo]
(* Out[4]= *) Mathematica 


It seems to do what I need.

Question 3: Are there any shortcomings in my implementation? Is there a more simple/standard way to do this?

-
Hi, why your code with In[3]:= in the head of line, not so convenient when copy to notebook to evaluate. – HyperGroups Jun 17 '13 at 0:27
I tried to make it look as close as possible to what I see on the screen. I did not think about copying from the question, sorry for that. What is the preferred way to format Mathematica input/output? Would it help if I used comments (* In[1]:= *)? – Vladimir Reshetnikov Jun 17 '13 at 0:39
But you realize that these aren't really custom glyphs, in the sense that they won't be displayed by external applications when you copy or export them, right? So if you're confined to Mathematica anyway, why are you forced to store the information as String type in the first place? – Jens Jun 17 '13 at 6:08
It looks like a bug to me, since pasting directly into a string literal works for Graphics but not for Image. The tutorial String Representation of Boxes is probably the best documentation for the markup. – Simon Woods Jun 17 '13 at 10:04
@Jens I sometimes convert things to String to get a more strict Hold attribute than HoldComplete. It usually acts as an atom object and prevents any affection from outside for good and ever. – Silvia Jun 17 '13 at 10:10

You can convert any expression to string by using ToString. If you want to preserve the visual representation, you should use ToString[(*your expression*), StandardForm].

logo = Import["http://wolfram.com/favicon.ico", "Image"]
logostr = ToString[logo, StandardForm]
StringJoin["Mathematica", logostr]
% // StringQ


Edit:

By checking the cell expression of the paste-into cell, I think I'd like to agree with Simon's comment that it looks like a bug:

-
I think this is quite clearly a malformed box expression, so I'm going to go ahead and tag this question with bugs. – Oleksandr R. Jun 19 '13 at 5:32
@OleksandrR. I agree. – Silvia Jun 19 '13 at 6:21

It's not clear when it is desirable to save an image inside a string. A similar outcome can be achieved by keeping everything (any possible format image, graphics, text, equation) in a list, and then just choosing the method of display. For example:

logo = Import["http://wolfram.com/favicon.ico", "Image"];
list = {"a string, an image ", logo, " and another image ", logo};


Of course this is not naturally formatted well for presentation, but this can be easily achieved by

Row[list]


If you look at the FullForm of this, it is perfectly well formed -- it is a long expression starting with

Row[List["a string, an image ", <<1>>, <<21>>,
Image[RawArray["Byte", List[List[List[0, 0, 0, 0],

-
IMO, sometimes Row (or any non-atom expression) could be too fragile in certain contexts. In that case, keeping things in String could serve as a more complete "HoldForm" wrapper than other structures. (But not always. e.g. String cannot prevent Dynamic in it.) – Silvia Jun 19 '13 at 10:28
@Silvia -- I guess I wasn't imagining that the Row was used for anything other than display; it's the List that forms the backbone and contains the objects. – bill s Jun 19 '13 at 10:57