Contents
Introduction
This project presents a new approach of sending binary data through the wire
using Direct Internet Message Encapsulation. You may download the 'DIME and
DimeSoapExtension
Sample' on
Microsoft MSDN web site. During my experimentations of web service
implementation I was always unhappy that binary datas had to be base64 encoded.
With DIME you may send your binary data in its native format instead of
requiring it to be encoded into XML using base-64 encoding, XML-escaped, or
character set transformations into UTF-8. This is perfect to send to the client
the jpeg picture grabbed on the webcam.
Web Service
This project will get the jpeg picture from the webcam using COM Interop, use
GDI+ to add the time to the picture, use a DNS resolution to add the client's
machine name to the Event Log and increments a system counter.
You may use as a starting point the solution DimeSample downloaded from MSDN.
Add a new C# ASP.NET Web Service project called: DimeWebcamService
. At this
point you need to add references to projects Dime and DimeSoapExtension
from
the DimeSample Solution. Then add a reference to 'CamServer 1.0 Type Library'
on the COM tab. If 'CamServer 1.0 Type Library' is not in the list, you need to
register the Dll CamServer.dll in the 'COM Components' directory.
Add the using statements:
using DimeSoapExtension;
using Dime;
using System.Net;
And finally add the
GrabFrame
Web Method to the source code obtained by the
wizard:
[DimeExtension]
[WebMethod]
public DimeAttachment GrabFrame( short nQuality )
{
string addr = HttpContext.Current.Request.UserHostAddress.Trim();
string name;
IPHostEntry host = null;
try
{
host = System.Net.Dns.GetHostByAddress( addr );
if ( host != null )
{
name = host.HostName;
for( int i = 0; i < host.Aliases.Length; i++ )
name += "*" + host.Aliases[i];
eventLog.WriteEntry( addr + " : " + name );
}
else
{
name = "ERROR";
eventLog.WriteEntry( name );
}
}
catch( System.Exception error )
{
}
CAMSERVERLib.Camera cam = new CAMSERVERLib.CameraClass();
byte[] picture = (byte[])cam.GrabFrame( nQuality );
performanceCounterShoot.Increment();
MemoryStream ms = new MemoryStream( picture );
Bitmap bmp = new Bitmap( ms );
Graphics g = Graphics.FromImage( bmp );
string strDate = DateTime.Now.ToLongDateString() +
" - " +
DateTime.Now.ToLongTimeString();
StringFormat drawFormat = new StringFormat();
drawFormat.Alignment = StringAlignment.Center;
g.DrawString( strDate,
new Font( FontFamily.GenericSansSerif, 10 ),
new SolidBrush( Color.Black ),
new RectangleF( 1,1,320,240 ),
drawFormat
);
g.DrawString( strDate,
new Font( FontFamily.GenericSansSerif, 10 ),
new SolidBrush( Color.White ),
new RectangleF( 0,0,320,240 ),
drawFormat
);
MemoryStream ms2 = new MemoryStream();
ImageCodecInfo[] icf = ImageCodecInfo.GetImageEncoders();
EncoderParameters encps = new EncoderParameters( 1 );
EncoderParameter encp = new EncoderParameter( Encoder.Quality, (long) nQuality );
encps.Param[0] = encp;
bmp.Save( ms2, icf[1], encps );
ms2.Seek( 0, SeekOrigin.Begin );
DimeAttachment attachment = new DimeAttachment( "image/jpeg",
TypeFormatEnum.MediaType,
ms2 );
return attachment;
}
To be able to use the
DimeAttachement
class as a return value of the Web
Service we need to add the attribute
[DimeExtension]
to the method
GrabFrame
. Now that we have the Web Service delivering the jpeg picture we need to display
it on a client.
ASP.NET Client
In past articles the client was implemented as an ActiveX. It was good for the
exercise but had drawbacks, for example you had to install the ActiveX on the
client machine.
This time the client is implemented has an ASP.NET Web Application. Add a new
C# ASP.NET Web Application to DimeSample solution, call it
DimeASPNETClient.
Again you need to add references to projects Dime and DimeSoapExtension from
the DimeSample Solution. Then add a web reference to
http://localhost/DimeSample/DimeWebcamService/DimeWebcamService.asmx. Rename
created localhost folder to TechHead. By adding a web reference we created a
proxy to access the DIME Webcam Web Service. Now we need to modify it. In the
Solution Explorer window make sure the DimeASPNETClient is selected. Click on
"Show All files" icon. Expand the "Web References" node in the DimeASPNETClient
project until you see Reference.cs. Reference.cs is the generated proxy. Double
click Reference.cs toedit it in the code editor.
Add the using statement:
using DimeSoapExtension;
Add the
[DimeExtension]
attribute to the
GrabFrame
method:
[DimeExtension]
public DimeAttachment GrabFrame(short nQuality)
{
Next remove the generated
DimeAttachement
class from the proxy. We want the
DimeAttachement
parameters to use
DimeSoapExtension.DimeAttachment
instead.
We have everything to be able to call the DIME Webcam Web Service. We then need
to display the picture returned. Double click on the file Webform1.aspx to run
the editor. Using the toolbox add an image to the page with a width of '320px'
and height of '240px'. Edit the HTML and add in the meta part:
<meta http-equiv="Refresh" content="20">
It permits to the web page to automatically reload each 20 seconds. Now edit
the code:
private void Page_Load(object sender, System.EventArgs e)
{
TechHead.Service1 wc = new TechHead.Service1();
DimeAttachment pic = wc.GrabFrame( 65 );
FileStream fs = new FileStream( Server.MapPath( "webcam.jpg" ),
FileMode.Create, FileAccess.Write );
byte[] fsPic = new byte[pic.Stream.Length];
pic.Stream.Read(fsPic, 0, (int)pic.Stream.Length);
fs.Write( fsPic, 0, fsPic.Length );
fs.Close();
Image1.ImageUrl = Server.UrlPathEncode( "webcam.jpg" );
}
The page is reloaded due to the Refresh meta, so the
Page_Load
method is called each 20 seconds.
Trial
You may try it here:
See Me
Conclusion
As a conclusion I made some evaluation of the DIME and Base64 ways of getting
binary data from a Web Service. I used a proxy to trace outputs of the Web
Service. The results are based on ten GrabFrame: Base64 = 184 658 bytes and
DIME = 140 660 bytes. The difference is around 30 percents. You also have to
consider that it is not needed for the server to encode and for the client to
decode with the DIME solution.
Problems Faced
History
Version 1.00
|
May 13, 2002
First release.
|