How to run the Ricoh Theta preview in c#?

cplusplus
#1

Cross-posting since I don’t know the answer for this but I think this may be a useful question. From Samuel L on Stack Overflow.

I’m working on an application requiering the Ricoh Theta live preview . The doc of Ricoh Theta says nothing. I found a request to run it in javascript but nothing for c# so far.

First, I’ve send the http request with the camera._getLivePreview , which is working (at least I have no error) :

var url = requests("commands/execute");
        request = WebRequest.Create(url);
        request.ContentType = "application/json";
        request.Method = "POST";

        using (var streamWriter = new StreamWriter(request.GetRequestStream()))
        {
            string json = "{\"name\":\"camera._getLivePreview\"," +
                          "\"parameters\":{\"sessionId\":\"" + sid + "\"}}";

            streamWriter.Write(json);
            streamWriter.Flush();
            streamWriter.Close();
        }

Then I’ve tried to use a solution I’ve found here in order to print the image given in bytes in the response :

        var response = request.GetResponse().GetResponseStream();

        BinaryReader reader = new BinaryReader(new BufferedStream(response), new System.Text.ASCIIEncoding());

        List<byte> imageBytes = new List<byte>();
        bool isLoadStart = false; 
        byte oldByte = 0; 
        while (true)
        {
            byte byteData = reader.ReadByte();

            if (!isLoadStart)
            {
                if (oldByte == 0xFF)
                {
                    // First binary image
                    imageBytes.Add(0xFF);
                }
                if (byteData == 0xD8)
                {
                    // Second binary image
                    imageBytes.Add(0xD8);

                    // I took the head of the image up to the end binary
                    isLoadStart = true;
                }
            }
            else
            {
                // Put the image binaries into an array
                imageBytes.Add(byteData);

                // if the byte was the end byte
                // 0xFF -> 0xD9 case、end byte
                if (oldByte == 0xFF && byteData == 0xD9)
                {
                    // As this is the end byte
                    // we'll generate the image from the data and can create the texture
                    // imageBytes are used to reflect the texture
                    // imageBytes are left empty
                    // the loop returns the binary image head
                    isLoadStart = false;
                }
            }
          oldByte = byteData;
          byteArrayToImage(imageBytes.ToArray());
        }

    }

Since it was not printing anything, I tried to make a method sending the imageurl to an image src (using code found here) :

public void byteArrayToImage(byte[] byteArrayIn)
        {
            string imreBase64Data = Convert.ToBase64String(byteArrayIn);
            string imgDataURL = string.Format("data:image/png;base64,{0}", imreBase64Data);
            imgPreview.Source = imgDataURL;
        }

The XAML of the Image :

<Image Source="" 
               x:Name="imgPreview"/>

How to make it work ?

Edit : Basically, I think the real question here is “how to print an image from a byte array ?”

1 Like
#2

Isn’t this question closer to how to get a motionjpeg stream to appear on a Xamarin screen? That seems like what the person is trying to do.

#3

@codetricity
Actualy, what I’m trying to do, and I’m still working on it, is how to display the live preview.
I’ve managed to get to the mjpeg stream, and I think the issue is the display, and once resolved, I will have the live preview. But the main topic is the preview.

1 Like
#4

I’m not sure how the Xamarin screen works. Most people use JavaScript or Java (for Android). Maybe you can take the concept and port it to C#?

This app uses Java in Android

2 Likes
#5

Thank you for your help @codetricity !
I’ve checked everything, and continued researching, and it looks like the problem is from Xamarin Forms itself.

It looks like the method byteArrayToImage is executed only after the general method. (I swaped to camera.getLivePreview with "parameters":{} in order to work with Theta V and Theta Z1)

I also tried with :
myImage.Source = ImageSource.FromStream() => new MemoryStream(imageBytes.toByteArray); inside the general method, just before isLoadStart=false which is executed when the last byte of the current frame is received, and only the last image is displayed.

In order to make sure only the last image was displayed, I changed the while’s condition to while (i < 15) to work with only 15 frames, then tried with 20, 50, 100, and each time only the last image is displayed.

Some people just updated the image source with a white image, or with just myImage.Source = " ";, or added a Thread.Sleep(3000), but nothing worked.

I’ve seen here and there it is better to use the stream url to display it with a package, but I can’t find the url requierd.

Best regards,
Samuel

1 Like