Converting and displaying a http requested camera image

Hi forum,

I’m running in various exceptions on client side when i try to display a image, send by a webserver.

My configuration:
CLIENT: Spider 1.0, Wifi RS21, SDK 2015 R1
SERVER: Spider 1.0, Wifi RN71, Serial Camera L1, SDK 2015 R1, RoSchmi Driver v8 [url]https://www.ghielectronics.com/community/codeshare/entry/927[/url]

I’m sending text data stable without problems on this system (thx to Roschmi).

On the server side i prepare my image bevor i send like this:


request.Response.HeaderData["Content-type"] = "images/bmp";  // jpeg ?
request.Response.HeaderData["Connection"] = "close";
request.Response.HeaderData["Cache-Control"] = "no-cache";
request.Response.StatusCode = GTM.GHIElectronics.HttpResponse.ResponseStatus.OK;

serialCameraL1.StartStreaming();
while (!serialCameraL1.NewImageReady);
// i get a correct sized array with data (160 x 120 * 3 + 54)
byte[] document = GHI.Utilities.Bitmaps.ConvertToFile(serialCameraL1.GetImage());
camera.StopStreaming();

request.Response.HeaderData["Content-Length"] = document.Length.ToString();

request.Response.Send(document, firstBatch, chunkSize, chunkDelay);

The server output window shows me the sending of the complete image.

On the client side i use the code snippet from the documentation to get the array:


byte[] result = new byte[57654];
int read = 0;

using (var req = HttpWebRequest.Create("url to query") as HttpWebRequest)
{
	using (var res = req.GetResponse() as HttpWebResponse)
	{
		using (var stream = res.GetResponseStream())
		{
			do
			{
				read = stream.Read(result, 0, result.Length);

				Thread.Sleep(20);
			} while (read != 0);
		}
	}
}

No i try the following (and many other things):


// pic is a correct sized array with data
GT.Picture pic = new GT.Picture(result, GT.Picture.PictureEncoding.BMP);
displayT35.SimpleGraphics.DisplayImage(pic, 0, 0);  // Exception
displayT35.SimpleGraphics.DisplayImage(pic.MakeBitmap(), 0, 0);  // Exception

What am I doing wrong?

Thx for any hlp
dutzend

1 Like

@ dutzend - Hi,
what kind of exceptions do you get?
Dit you try to receive pictures with the PC http client which is included in the my project?
Can you give a link to the “documentation” where your Client code is from?
Did you update the RN171 Firmware to the lates version?
RoSchmi

Hi,
thx for fast answering…

Exception:

Exception System.Exception - CLR_E_FAIL (1)
#### Message: 
#### Microsoft.SPOT.Bitmap::.ctor [IP: 0000] ####
#### RemoteControl.Program::cameraTimer_Tick [IP: 00a5] ####
#### Gadgeteer.Timer::dt_Tick [IP: 0018] ####
#### Microsoft.SPOT.DispatcherTimer::FireTick [IP: 0010] ####
#### Microsoft.SPOT.Dispatcher::PushFrameImpl [IP: 0054] ####
#### Microsoft.SPOT.Dispatcher::PushFrame [IP: 001a] ####
#### Microsoft.SPOT.Dispatcher::Run [IP: 0006] ####
#### Gadgeteer.Program::Run [IP: 001d] ####

Eine Ausnahme (erste Chance) des Typs “System.Exception” ist in Microsoft.SPOT.Graphics.dll aufgetreten.

Documentation: [url]https://www.ghielectronics.com/docs/30/networking[/url]

Client-App: I can start a download (“Start downloading page…”), the server sending completly but the client don’t see the and of the response…

Firmware: i do it update now

dutzend

Hi,

is see in this moment on the server side only the first chunk is filled with data. All bytes >1420 are 0…

dutzend

@ dutzend - I just set up Version 8 on a Spider and can load the test Images from the resources and a bigger .jpg Image (165 KB) from the SD-Card with no problems

@ dutzend -
you try to write the image from the camera to a Byte Array. However in NETMF Byte Arrays are limited in size
[url]https://www.ghielectronics.com/community/forum/topic?id=10174&page=1[/url]
I think you should write the Image to a MemoryStream and then send the Contents of the Memory stream in chunks over http.

Edit: The Image file seems to be not so large that the Byte Array length is an issue.
We should find out, if the bug in GHI’s “ConvertToFile” function is still not fixed.

[url]https://www.ghielectronics.com/community/forum/topic?id=17180[/url]

Hi,

  • I use the SDK 2016 R1 (from the beginning, failure in my first post)
  • I see now a picture from my server in the client app (i only changed the content-type to jpeg).
  • the incoming array is now filled
  • I am not able to do the firmware upgrade (cannot join my fritz box)

The exception do not disappear, only the first line throw no exception…


GT.Picture currentPicture = new GT.Picture(result, GT.Picture.PictureEncoding.BMP);
//byte[] outputArray = GHI.Utilities.Bitmaps.ConvertToFile(new Bitmap(result, Bitmap.BitmapImageType.Bmp));
//Bitmap currentPicture = new Bitmap(outputArray, Bitmap.BitmapImageType.Jpeg);
             
//displayT35.SimpleGraphics.DisplayImage(currentPicture.MakeBitmap(), 0, 0);

So I assume that you use the http-Server in Access-Point mode.
What is the Firmware Version on your RN 171?
With older firmware Versions WPA2_PSK encryption does not work in the “Join Network” mode. You can temporary set your Fritz-Box to “Open-Network” and can then do the Firmware update.
Do not forget to change to “Open” in the spider App as well.


bool ActionResult = wifi_RN171.JoinWirelessNetwork("xyz", "xyz", 0, Gadgeteer.Modules.RoSchmi.WiFi_RN171.WirelessEncryptionMode.Open, "80");

Hi,

I think the problem is here:


using (var res = req.GetResponse() as HttpWebResponse)
{
    using (var stream = res.GetResponseStream())
    {
        do
        {
            read = stream.Read(result, 0, result.Length);
            Thread.Sleep(20);
         } while (read != 0)
    }
}

It was a failure to say the array is completetly filled, only the first 1420 byte has data!
It looks that the loop is ending after the first chunk. I see on the server side the sending loop is running (output window), the client already want to show the picture…

dutzend

@ dutzend - did you try a longer time as Thread.Sleep(20), perhaps Thread.Sleep(200) ?

Hi,

@ RoSchmi - Yes, in the Moment i try something like that:


using (var res = req.GetResponse() as HttpWebResponse)
{
    do
    {
        using (var stream = res.GetResponseStream())
        {
            read = stream.Read(buffer, 0, buffer.Length);  // 1420

            buffer.CopyTo(result, offset);
            offset += read;

            Thread.Sleep(200);
        }
    } while (read != 0);
}

I move the loop one level higher, now i run in System.Argument.OutOfRangeException at the end of the array i think…

dutzend

@ dutzend - this cannot work as you always try to read from another stream.

The solution - thx RoSchmi:


using (var res = req.GetResponse() as HttpWebResponse)
{
    using (var stream = res.GetResponseStream())
    {
        do
        {
            int bufferLength = result.Length - offset >= chunkSize ? chunkSize : result.Length - offset;
            byte[] buffer = new byte[bufferLength];

            read = stream.Read(buffer, 0, buffer.Length);

            buffer.CopyTo(result, offset);
            offset += read;

            //Thread.Sleep(20);
        } while (read != 0);
    }
}

@ dutzend - just found out that



doesn't throw an exception when a lower resolution is selected:


```cs

serialCameraL1.ImageResolution = SerialCameraL1.Resolution.QQVGA;

1 Like

Hi,

i am very frustrated…
The sending process on the server stops always…


request.Response.Send(document, true, 1420, 50);

Sometimes always is fine for some loops, sometimes it stops in one of the first chunks.
I am not able to do the Firmware update (i opend my network).

I try various rn171 modules and different Spider boards, it is always the same.

Thx for any hlp
dutzend

Which Firmware Version is on your RN-171?. You can see it in the Messages from the RN-171 during initialization.

Hi RoSchmi,

wifly-EZX Ver 4.00.1, Apr 19 2013 11:47:20 on RN-171

Thx
dutzend

Hi,

STOPPED:

Sending document …
Header was sent
GC: 23msec 269316 bytes used, 7070352 bytes available
Type 0F (STRING ): 1368 bytes
Type 11 (CLASS ): 16896 bytes
Type 12 (VALUETYPE ): 1164 bytes
Type 13 (SZARRAY ): 64140 bytes
Type 03 (U1 ): 59568 bytes
Type 04 (CHAR ): 900 bytes
Type 07 (I4 ): 1116 bytes
Type 0F (STRING ): 108 bytes
Type 11 (CLASS ): 2448 bytes
Type 15 (FREEBLOCK ): 7070352 bytes
Type 17 (ASSEMBLY ): 38628 bytes
Type 18 (WEAKCLASS ): 96 bytes
Type 19 (REFLECTION ): 168 bytes
Type 1B (DELEGATE_HEAD ): 1404 bytes
Type 1D (OBJECT_TO_EVENT ): 600 bytes
Type 1E (BINARY_BLOB_HEAD ): 132252 bytes
Type 1F (THREAD ): 2304 bytes
Type 20 (SUBTHREAD ): 240 bytes
Type 21 (STACK_FRAME ): 3948 bytes
Type 22 (TIMER_HEAD ): 72 bytes
Type 26 (WAIT_FOR_OBJECT_HEAD): 48 bytes
Type 27 (FINALIZER_HEAD ): 552 bytes
Type 28 (MEMORY_STREAM_HEAD ): 36 bytes
Type 29 (MEMORY_STREAM_DATA ): 396 bytes
Type 31 (IO_PORT ): 576 bytes
Type 34 (APPDOMAIN_HEAD ): 72 bytes
Type 36 (APPDOMAIN_ASSEMBLY ): 4356 bytes
GC: performing heap compaction…
Got free memory: 7070352 with time for Garbage Collection of 99 ms
From 19 bytes 19 were sent

COMPLETE:

Sending document …
Header was sent
GC: 24msec 269316 bytes used, 7070352 bytes available
Type 0F (STRING ): 1368 bytes
Type 11 (CLASS ): 16896 bytes
Type 12 (VALUETYPE ): 1164 bytes
Type 13 (SZARRAY ): 64140 bytes
Type 03 (U1 ): 59568 bytes
Type 04 (CHAR ): 900 bytes
Type 07 (I4 ): 1116 bytes
Type 0F (STRING ): 108 bytes
Type 11 (CLASS ): 2448 bytes
Type 15 (FREEBLOCK ): 7070352 bytes
Type 17 (ASSEMBLY ): 38628 bytes
Type 18 (WEAKCLASS ): 96 bytes
Type 19 (REFLECTION ): 168 bytes
Type 1B (DELEGATE_HEAD ): 1404 bytes
Type 1D (OBJECT_TO_EVENT ): 600 bytes
Type 1E (BINARY_BLOB_HEAD ): 132252 bytes
Type 1F (THREAD ): 2304 bytes
Type 20 (SUBTHREAD ): 240 bytes
Type 21 (STACK_FRAME ): 3948 bytes
Type 22 (TIMER_HEAD ): 72 bytes
Type 26 (WAIT_FOR_OBJECT_HEAD): 48 bytes
Type 27 (FINALIZER_HEAD ): 552 bytes
Type 28 (MEMORY_STREAM_HEAD ): 36 bytes
Type 29 (MEMORY_STREAM_DATA ): 396 bytes
Type 31 (IO_PORT ): 576 bytes
Type 34 (APPDOMAIN_HEAD ): 72 bytes
Type 36 (APPDOMAIN_ASSEMBLY ): 4356 bytes
GC: performing heap compaction…
Got free memory: 7070352 with time for Garbage Collection of 103 ms
From 19 bytes 19 were sent
CLOS
OPEN
GET /0 HTTP/1.1
Connection: Keep-Alive
Host: 192.168.1.1

@ dutzend - Updating the Firmware should not be a Problem with this firmware if you do not use encryption in your Fritz-Box.
Just set the directives in my Utility first to connect to your Network by DHCP to get an ip.
Set the correct SSID and Password for your Network.


//#define WorkAsAccessPoint
 #define WorkJoinedToNetwork
//#define WorkJoinedToNetworkFirmwarUpdate

if you do not get an Ip please show the relevant part of the output window.
if you get an Ip you can Change the directives to


//#define WorkAsAccessPoint
//#define WorkJoinedToNetwork
 #define WorkJoinedToNetworkFirmwarUpdate

The utility should then automatically connect to the Server of Microchip and update the firmware.

The calls of the garbage collector which you showed are normal. In my driver I forced a call of the garbage collector before each http send to avoid interfering of the garbage collector with http transmission accidentially.

Hi RoSchmi,

i can try in the Moment with my phone, it is the same issue:

AOK
<4.00>
set wlan ssid Windows Phone7628
AOK
<4.00>
set wlan channel 0
AOK
<4.00>
set wlan auth 4
AOK
<4.00>
set wlan phrase c12286F-
AOK
<4.00>
set wlan hide 1
AOK
<4.00>
join
Auto-Assoc Windows chan=0 mode=NONE FAILED
<4.00>

Thx
dutzend