7
$\begingroup$

This more then a .net question but I'm in Mathematica using.Suppose I want to get a image from my clipboard,so I make a function like following.If there is a image in your clipboard then you run this code.You will get a image NETObject:

Needs["NETLink`"]
InstallNET[];
LoadNETType["System.Windows.Forms.Clipboard", StaticsVisible -> True];
img=GetImage[]

(*« NETObject[System.Drawing.Bitmap]»*)

How to make the img be a image?There is a related post:

But his image from a Mathemtica expresssion.

$\endgroup$
14
  • $\begingroup$ LockBits or something like it might be needed; unfortunately my .NET is not up to snuff. $\endgroup$ Dec 11, 2016 at 10:41
  • $\begingroup$ @J.M. It's little difficult as my Google. $\endgroup$
    – yode
    Dec 11, 2016 at 11:32
  • $\begingroup$ Here is example code which does what you want in matlab. It is not completely straightforward to translate to Mathematica but a good starting point. Can you explain what exactly you are trying to solve? I could imagine that there might be other possibilities to achieve what you need than using .NET. See e.g. this for an alternative to get a picture from clipboard. $\endgroup$ Dec 12, 2016 at 9:01
  • $\begingroup$ @AlbertRetey Wow,thanks for your links.Actually I have found that postbefore this,I just want to convert a image object to image in Mathematica. :) $\endgroup$
    – yode
    Dec 12, 2016 at 9:40
  • 1
    $\begingroup$ Probably related: mathematica.stackexchange.com/questions/95938/… $\endgroup$ Dec 19, 2016 at 22:41

2 Answers 2

5
+250
$\begingroup$

I don't know much of .net and it probably shows, but at least I got something to work albeit very,very slowly.

Your code (which I also turned into a bitmap on the clipboard using Mathematica's "Copy as Bitmap" menu item):

Needs["NETLink`"]
InstallNET[];
LoadNETType["System.Windows.Forms.Clipboard", StaticsVisible -> True];
img = GetImage[]

Using a few of .Net's Image methods to get pixel information:

res = Table[
   {
    img@GetPixel[r, c]@R,
    img@GetPixel[r, c]@G,
    img@GetPixel[r, c]@B,
    img@GetPixel[r, c]@A
    }, {c, 0, img@Height - 1}, {r, 0, img@Width - 1}];

Image[res, "Byte", ColorSpace -> "RGB"]

And after waiting perhaps a few minutes (I said it was slow) with the above mentioned image already loaded in the clipboard you get this:

Mathematica graphics

$\endgroup$
2
  • $\begingroup$ Wow,it's seem you make it.Thanks very very much. :) $\endgroup$
    – yode
    Dec 19, 2016 at 23:52
  • $\begingroup$ Feel free for the extra bounties please. :) $\endgroup$
    – yode
    Mar 8, 2017 at 18:01
5
$\begingroup$

Done

Needs["NETLink`"]; InstallNET[];
LoadNETType /@ {"System.Windows.Forms.Clipboard", 
   "System.Drawing.Rectangle", "System.Drawing.Imaging.ImageLockMode",
    "System.Runtime.InteropServices.Marshal"};
img = Clipboard`GetImage[];
width = img[Width];
height = img[Height];
lock = img[
   LockBits[Rectangle`FromLTRB[0, 0, width, height], 
    ImageLockMode`ReadWrite, img[PixelFormat][Format24bppRgb]]];
stride = Abs[lock[Stride]];
intPtr = lock[Scan0];
totalB = stride*height;
byte = NETNew["System.Byte[]", totalB];
Marshal`Copy[intPtr, byte, 0, totalB];
data = NETObjectToExpression[byte];
Marshal`Copy[byte, 0, intPtr, totalB];
img[UnlockBits[lock]];
img = Image[Map[Reverse/@Partition[#, 3] &,Partition[data, width*3,stride]],"Byte"]
$\endgroup$
1
  • $\begingroup$ Looks good. Though the Compile is a bit strange as it uses global variables width and stride that should be passed as parameter or derived locally. Compile, as used here, is also not faster. BTW Image[Map[Reverse, ArrayReshape[Drop[data, {stride, -1, stride}], Length[data]/stride, width, 3}], {2}], "Byte"] would be an alternative to your last line, though it's just as fast as what you have. $\endgroup$ Mar 9, 2017 at 19:54

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.