7

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.

yode
  • 26,686
  • 4
  • 62
  • 167
  • LockBits or something like it might be needed; unfortunately my .NET is not up to snuff. – J. M.'s missing motivation Dec 11 '16 at 10:41
  • @J.M. It's little difficult as my Google. – yode Dec 11 '16 at 11:32
  • 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. – Albert Retey Dec 12 '16 at 09:01
  • @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. :) – yode Dec 12 '16 at 09:40
  • so you are saying that the .NET image object you are trying to convert does not necessarily come from the clipboard and the clipboard reference is just for an easy example? If so, you might want to make that more clear in your question to avoid answers explaining the Clipboard notebook solutions or even close votes as it could be seen as a duplicate to the one I linked to... – Albert Retey Dec 12 '16 at 10:09
  • @AlbertRetey Well I check my presentation,I found it is suitable for a .NET qeuestion in Mathematica I think?I just by clipboard to get a content. :) – yode Dec 12 '16 at 13:50
  • 1
    Probably related: http://mathematica.stackexchange.com/questions/95938/using-a-pointer-in-netlink – Sjoerd C. de Vries Dec 19 '16 at 22:41
  • @J.M. As your promption,I made it in a efficient way.Thanks a lot.. – yode Mar 08 '17 at 13:16
  • You're learning the usage of .netlink and don't want to use Paste? – xzczd Mar 08 '17 at 14:10
  • @xzczd The Paste will not give any output,isn't it? – yode Mar 08 '17 at 14:46
  • Are you sure?: https://i.stack.imgur.com/qzkY2.gif – xzczd Mar 08 '17 at 14:58
  • @xzczd It is a print,but a output. :) – yode Mar 08 '17 at 15:05
  • Then you just need this function: http://mathematica.stackexchange.com/a/41722/1871 – xzczd Mar 08 '17 at 15:07
  • OK, since OP is just interested in the usage of .netlink, let me keep this in comment rather than posting an answer: if one only needs to output the picture on the clipboard into Mathematica, I think using Paste[]; pic = ToExpression@First@NotebookRead@Experimental`NextCell[]; NotebookDelete@Experimental`NextCell[]; pic is simpler. – xzczd Mar 08 '17 at 17:55

2 Answers2

5

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

yode
  • 26,686
  • 4
  • 62
  • 167
Sjoerd C. de Vries
  • 65,815
  • 14
  • 188
  • 323
5

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"]
yode
  • 26,686
  • 4
  • 62
  • 167
  • 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. – Sjoerd C. de Vries Mar 09 '17 at 19:54