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$
  • $\begingroup$ LockBits or something like it might be needed; unfortunately my .NET is not up to snuff. $\endgroup$ – J. M. will be back soon Dec 11 '16 at 10:41
  • $\begingroup$ @J.M. It's little difficult as my Google. $\endgroup$ – yode Dec 11 '16 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$ – Albert Retey Dec 12 '16 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 '16 at 9:40
  • 1
    $\begingroup$ Probably related: mathematica.stackexchange.com/questions/95938/… $\endgroup$ – Sjoerd C. de Vries Dec 19 '16 at 22:41
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$
  • $\begingroup$ Wow,it's seem you make it.Thanks very very much. :) $\endgroup$ – yode Dec 19 '16 at 23:52
  • $\begingroup$ Feel free for the extra bounties please. :) $\endgroup$ – yode Mar 8 '17 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$
  • $\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$ – Sjoerd C. de Vries Mar 9 '17 at 19:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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