In my recent question I asked How to embed an image into a string?
The suggested solution was
(* In[1]:= *) image = Import["https://wolfram.com/favicon.ico", "Image"];
(* In[2]:= *) str = ToString[image, StandardForm];
If I execute
(* In[3]:= *) CopyToClipboard[str];
and then paste it into a plain text editor (e.g. notepad on Windows) than I get a very long and verbose string:
\!\(\*GraphicsBox[TagBox[RasterBox[RawArray["Byte", List[List[List[0, 0, 0, 0], (* ... *) List[0, 0, 0, 0]]]], List[List[0, 16], List[16, 0]], List[0, 255], Rule[ColorFunction, RGBColor]], BoxForm`ImageTag["Byte", Rule[ColorSpace, "RGB"], Rule[Interleaving, True]], Rule[Selectable, False]], Rule[BaseStyle, "ImageGraphics"], Rule[ImageSizeRaw, List[16, 16]], Rule[PlotRange, List[List[0, 16], List[0, 16]]]]\)
But if I copy the image to the clipboard directly
(* In[4]:= *) CopyToClipboard[image];
and then paste it into a plain text editor than I get a compressed representation:
\!\(\*
GraphicsBox[
TagBox[RasterBox[CompressedData["
1:eJyNUgss1HEc/+9CKBIyz928OodzCOdxcU95njh5tIQbpvUgDrFKWtIDPaZk
tLTmIiJbWR6pbLVSlNSI0S0j4bS8tiZ9Oi1NFvluv99+n+++n31/3+/nYyxK
CIojEQSRrCy/gqLT2ElJ0elCBTngpItjRWvkD43fZz75v3ibne/1+uIF0ipK
iVviDPd37ADrBdyRdYz8zZYz9yozS3UhdyckeVPl+csq/+LnpR7hvqG4yUaZ
/AP9gf6uMgqtdZwgoY3ilFbtEqJ5gxaa+Zizp7CuVKK03B+K1OwBkgl+MM1m
RnjG6GQZo1tJD7V6HGkTwUMfK0Gw0gyZWvSJJ0r2GBP5Y6goBv054ai3scU5
goEhgosB3zjHpZyykL2pD0nMqadkZ9yj2qOSYOKBiRcaOf4oZ3CRqspAsaEH
oO8IaNFHe7lBZlLPMKMB7g7qPL+ktEStx0kgnTO1xEBwAHrpbIz7haNdKESN
JwtnTeho5nOByG2YJXQBQgdf6VvRHbsv/c+uoyPM4eeK4TA/TIYJgIJTmC6/
irbcFNzmuaEpKhgTp3fik54aBnU2fR7wFdAXz9DnI5S8NzLHc3MqZAejMFlx
Ed8bqyAryseL7d6otnBAX7wQI+SNaN3mJVnglSYeXfuAubuhTnGzfEcaqNI3
RWegN3pOijFYdAJIT4DU2Rk3FSwgUWOgS8UK/dpWaDicwZvnF0Ts55+nel/K
0bU9U2VocP1ZgLu8Hw/tgTxI4/0wEcDEoKMDWmy24Jy6BY4Tlrgm16fOjj9V
IT4kWqpFl4217EOoJx7RLdCqtwEfPe0AcTDAdsBLbTrynH3Tdhmz1TPN+I7F
nCCXv3SMiF9fS1DQTKZBomMwUUNoYZpCwwzVAF8IVYwquqAlu0B5Oe8UBsb4
FPPC48o8vDWvkC1Z9Spus8PrGLjLYf3ya6ey3VhHbnHESv5bHPVOYe0Ngkjf
Bdxs6aFy/2Q+bbX8mpScjCpRovZKNT8BKotUng==
"], {{0, 16}, {16, 0}}, {0, 255},
ColorFunction->RGBColor],
BoxForm`ImageTag["Byte", ColorSpace -> "RGB", Interleaving -> True],
Selectable->False],
BaseStyle->"ImageGraphics",
ImageSizeRaw->{16, 16},
PlotRange->{{0, 16}, {0, 16}}]\)
Both the long and compressed strings, if being pasted back to a Mathematica notebook, are automatically represented as the original image:
(* In[5]:= *)
I am interested in
Question 1: How to get the compressed string programmatically, without using the clipboard?
The content of CompressedData["..."]
looks like a result of the Compress
function, and indeed it could be checked that
(* In[6]:= *) ToBoxes[image][[1, 1, 1]] ===
Uncompress["
1:eJyNUgss1HEc/+9CKBIyz928OodzCOdxcU95njh5tIQbpvUgDrFKWtIDPaZk
tLTmIiJbWR6pbLVSlNSI0S0j4bS8tiZ9Oi1NFvluv99+n+++n31/3+/nYyxK
CIojEQSRrCy/gqLT2ElJ0elCBTngpItjRWvkD43fZz75v3ibne/1+uIF0ipK
iVviDPd37ADrBdyRdYz8zZYz9yozS3UhdyckeVPl+csq/+LnpR7hvqG4yUaZ
/AP9gf6uMgqtdZwgoY3ilFbtEqJ5gxaa+Zizp7CuVKK03B+K1OwBkgl+MM1m
RnjG6GQZo1tJD7V6HGkTwUMfK0Gw0gyZWvSJJ0r2GBP5Y6goBv054ai3scU5
goEhgosB3zjHpZyykL2pD0nMqadkZ9yj2qOSYOKBiRcaOf4oZ3CRqspAsaEH
oO8IaNFHe7lBZlLPMKMB7g7qPL+ktEStx0kgnTO1xEBwAHrpbIz7haNdKESN
JwtnTeho5nOByG2YJXQBQgdf6VvRHbsv/c+uoyPM4eeK4TA/TIYJgIJTmC6/
irbcFNzmuaEpKhgTp3fik54aBnU2fR7wFdAXz9DnI5S8NzLHc3MqZAejMFlx
Ed8bqyAryseL7d6otnBAX7wQI+SNaN3mJVnglSYeXfuAubuhTnGzfEcaqNI3
RWegN3pOijFYdAJIT4DU2Rk3FSwgUWOgS8UK/dpWaDicwZvnF0Ts55+nel/K
0bU9U2VocP1ZgLu8Hw/tgTxI4/0wEcDEoKMDWmy24Jy6BY4Tlrgm16fOjj9V
IT4kWqpFl4217EOoJx7RLdCqtwEfPe0AcTDAdsBLbTrynH3Tdhmz1TPN+I7F
nCCXv3SMiF9fS1DQTKZBomMwUUNoYZpCwwzVAF8IVYwquqAlu0B5Oe8UBsb4
FPPC48o8vDWvkC1Z9Spus8PrGLjLYf3ya6ey3VhHbnHESv5bHPVOYe0Ngkjf
Bdxs6aFy/2Q+bbX8mpScjCpRovZKNT8BKotUng==
"]
(* Out[6]= True *)
Unfortunately, RawArray
, CompressedData
and BoxForm`ImageTag
are all undocumented. It looks like RawArray
represents (probably, optimized) internal representation of a multi-dimensional array, and CompressedData
is equivalent to Uncompress
(e.g. unless being held, it automatically evaluates to the object represented by the compressed string) except that CompressedData
can be successfully interpreted as part of an input of the form \!\(\* ... \)
.
Question 2: Did I get their meaning right? Can they be useful in any other context?
Assuming I did it right, the closest result I was able to obtain to what I need is given by
(* In[7]:= *) toCompressedString[image_Image] :=
"\!\(\*" <> ToString[
ToBoxes[image] /.
array_RawArray :>
With[{compressed = Compress[array]},
CompressedData[compressed] /; True],
InputForm] <> "\)";
(/; True
is the Trott-Strzebonski trick that I learned trying to write this code).
Is there a more strightforward way to get this string?