5
$\begingroup$

I have created a specialized image analysis method in Mathematica that takes an image and returns a marked up image with some detection output. In order to allow others to feed images into my analysis from arbitrary sources (databases, file systems, web interfaces, scanners, etc), I would like to wrap in a .NET application (preferably C#).

Is there any way to pass an image object from .NET into MathKernel via NETLink and handle it as an Image in the kernel? I have found examples of how to get images out of MathKernel, but not the other direction.

I could write the image to a temporary file, but that seems sloppy.

$\endgroup$
3
  • 1
    $\begingroup$ In general you could pass data through a socket. Check SocketListen $\endgroup$
    – Fortsaint
    Commented Oct 2, 2019 at 18:39
  • 1
    $\begingroup$ Perhaps pass as base 64 string e.g. mathematica.stackexchange.com/a/27956/363 $\endgroup$ Commented Oct 2, 2019 at 21:50
  • 1
    $\begingroup$ In the J/Link implementation they use a PutByteArray(...) of the image data, presumably NETLink supplies a similar hook to MLPutByteArray? That will be fast and presumably pretty simple. Use PutType("Image", 1) or whatever the correct call is (can't remember) to wrap the data in Image first or whatever. I did this for my implementation of J/Link for python and remember it being pretty simple along those lines. $\endgroup$
    – b3m2a1
    Commented Oct 10, 2019 at 16:06

1 Answer 1

3
$\begingroup$

I have found through a lot of iterations that the easiest and most reliable way of doing this is to pass the images using Base64 strings.

I have included example functions for sending and retrieving images using Mathematica .NETLink. The .NETLink built in function for retrieving images (EvaluateToImage) seems to re-encode the image.

Once the image is back in a byte array, saving or displaying the image should be trivial.

using System;
using System.IO;
using Wolfram.NETLink;

namespace Example
{
    class Example
    {
        private static IKernelLink ml;

        internal void InitializeKernelLink()
        {
            ml = MathLinkFactory.CreateKernelLink();
            ml.WaitAndDiscardAnswer();
        }

        internal void SendImage()
        {        
            var path = @"C:\Example.JPG";
            var imageArray = File.ReadAllBytes(path);
            var base64Image = Convert.ToBase64String(imageArray);
            ml.Evaluate("importedImage = ImportString[\"" + base64Image + "\",\"Base64\"]");
            ml.WaitAndDiscardAnswer();
        }

        internal void GetImage()
        {
            ml.Evaluate($"ExportString[importedImage,{{\"Base64\", \"PNG\"}}]");
            ml.WaitForAnswer();
            var data = ml.GetString();
            byte[] decoded = Convert.FromBase64String(data);
        }

    }
}
$\endgroup$

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.