18
$\begingroup$

I have discovered a problem that affects my use of Mathematica. When I use the menu command Edit > Copy As > Bitmap the colors in the copy are subtly degraded. To make this more apparent I copied and pasted repeatedly with the following result:

enter image description here

This is a major problem as I have been assuming that Copy As > Bitmap was a lossless operation.

Is there an explanation for this behavior? Is there a better work-around than using Print Scrn, pasting, and cropping? Which versions and platforms are affected?

I am using Mathematica 10.1 under Windows 7.


Update

  • Following both Oleksandr's comments Alexey's analysis I removed any profile associated with my monitor from the Windows Color Management dialog, and repeated the experiment (using Alexey's code).

  • Now the last copy is visually identical to the original, confirming that this is a problem with how Mathematica handles monitor profiles.

  • Notably the LUT for my calibration profile is still loaded into my graphics card (it was loaded at start-up by the utility ColorVisionStartup). This means that it is possible to have both calibration and verbatim copying in Mathematica; the problem entirely separate.

  • Un-associating the monitor profile in Color Management after the LUT is loaded is a viable work-around, but quite inconvenient and prone to error as one would need to remember to re-associate the profile before restarting Windows.

$\endgroup$
27
  • 1
    $\begingroup$ I am not sure if it is documented, because color management certainly does not work properly (it is the cause of the slow startup and annoying "formatting notebook contents" messages experienced by many, and also Nasser's bizarre orange problem). Anyway, if you search within the installation directory for *.icc, you will find there are a couple of them in there. These also exist in version 9 and the same slow startup problem exists in that, but the implementation is sufficiently limited that there are no other observable issues until version 10 as far as I know. $\endgroup$ Aug 29, 2015 at 18:06
  • 2
    $\begingroup$ This is probably the question OleksandrR. is referring to: my-mathematica-has-turned-orange-and-not-able-to-find-out-why $\endgroup$ Aug 29, 2015 at 19:42
  • 2
    $\begingroup$ On Windows Mathematica versions 8, 9 and 10 have exact the same problem. $\endgroup$ Aug 29, 2015 at 21:48
  • 5
    $\begingroup$ Should this question be tagged as a Windows problem? I can't reproduce it on OS X. After making six copies of a bitmapped gradient I see no degradation. $\endgroup$
    – m_goldberg
    Aug 29, 2015 at 23:52
  • 2
    $\begingroup$ I can't tell at first but this seems to be related mathematica.stackexchange.com/questions/26105/… $\endgroup$
    – William
    Sep 8, 2015 at 6:08

1 Answer 1

13
+50
$\begingroup$

UPDATE from 06.11.2015

Since writing the original answer I installed updates for my Windows 7 x64. Now the original bug isn't there anymore but there still persists more fundamental bug which I observe in versions 8.0.4, 9.0.1, 10.0.1, 10.2 and 10.3 installed on the same system. This bug becomes evident when you look at the plots of horizontal channel intensity values generated by the code in the original answer. Below is output from version 10.3:

output


Original answer

I'm also on Windows 7 x64 and observe the same problem with Mathematica 10.2.

Here is a demonstration of what happens on the level of channel values. It supports Oleksandr's supposition that we have a color management issue here.

In a new Notebook I generate an image:

Image[ConstantArray[Range[0, 1, .001], {40}]]

image

Then I programmatically copy it as Bitmap, paste below the original and save the clipboard content in lst (the following code should be evaluated in a Cell placed after the output generated by the above code):

lst = Table[SelectionMove[EvaluationNotebook[], Before, EvaluationCell];
   SelectionMove[EvaluationNotebook[], Previous, CellContents];
   FrontEndTokenExecute[EvaluationNotebook[], "CopySpecial", "MGF"];
   SelectionMove[EvaluationNotebook[], After, Cell, 1];
   FrontEndTokenExecute[EvaluationNotebook[], "Paste"];
   NotebookGet[ClipboardNotebook[]], {20}];

Here is how my Notebook looks afterwards:

screenshot

Now I extract horizontal channel values for successive images and plot them separately for every channel:

channelData = 
  ImageData[ToExpression[#[[1, 1, 1, 1]]], Automatic, Interleaving -> False][[All, 
      20]] & /@ lst;
Column[ListLinePlot[channelData[[All, #]], PlotRange -> All, 
    PlotLabel -> {"Red", "Green", "Blue"}[[#]], ImageSize -> 700] & /@ {1, 2, 3}]

plots

Indeed it looks like some color transformation is applied to image when you copy it as Bitmap which results in color degradation mainly due to clipping off color values after conversion and also due to rounding off errors.

I suppose that the FrontEnd relies upon some Windows functionality for rendering of an expression when you copy it as Bitmap. And even when what you copy is already an Image, FrontEnd nevertheless handles it the same way.


The only workaround I can suggest is do not rely upon FrontEndTokens for rasterization and use Rasterize instead. Just for completeness, this answer demonstrates why we should not rely upon FrontEndTokens even for exporting.


Workaround

In the comment William points to the thread which contains .NET-based solution allowing to copy graphics into clipboard already in compressed PNG format with highest quality currently available in Mathematica. For your particular application the solution by Todd Gayley can be modified as follows (the following respects the styles of the selected Notebook):

Needs["NETLink`"]

CopyAsPNG[g_, opts : OptionsPattern[]] := 
  CopyAsPNG[Rasterize[Style[g, Options[SelectedNotebook[]]], "Image", opts]];
CopyAsPNG[i_Image] := Module[{png, strm, dataObject}, InstallNET[];
  png = ExportString[i, "PNG"];
  NETBlock[strm = NETNew["System.IO.MemoryStream", ToCharacterCode[png]];
   dataObject = NETNew["System.Windows.Forms.DataObject"];
   dataObject@SetData["PNG", strm];
   LoadNETType["System.Windows.Forms.Clipboard"];
   Clipboard`SetDataObject[dataObject]]]

Checking:

ColorData["VisibleSpectrum", "Panel"] // CopyAsPNG
Paste[]

screenshot

$\endgroup$
10
  • $\begingroup$ On my system (Mathematica 10.2, Windows 10) your code just gives me 20 perfect copies of the original image. $\endgroup$ Sep 6, 2015 at 10:14
  • $\begingroup$ Alexey, thank you for your analysis. Windows somehow manages to avoid this problem when using Print Screen so clearly it is possible. Unfortunately Print Screen is inconvenient and has trouble when the object to copy is larger that one display space. I appreciate your reminder to use Export for e.g. .PDF but unfortunately neither Export nor Rasterize respect my FontProperties -> "ScreenResolution" setting so I again have trouble. $\endgroup$
    – Mr.Wizard
    Sep 6, 2015 at 18:53
  • $\begingroup$ @Simon I think one needs to have a calibration profile loaded to see this effect. $\endgroup$
    – Mr.Wizard
    Sep 6, 2015 at 18:55
  • $\begingroup$ @Simon I am trying to pin down the exact combination of factors that result in this problem. It may have something to do with my use of ColorVisionStartup but I am not sure. Alexey, what method of display calibration are you using and how is the LUT loaded? $\endgroup$
    – Mr.Wizard
    Sep 6, 2015 at 19:27
  • $\begingroup$ @Mr.Wizard I didn't calibrated my monitor, it is just the defaults after Win7 installation (but I probably tuned ClearType settings). How can I find information about LUT in my system? $\endgroup$ Sep 7, 2015 at 0:22

Your Answer

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

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