|
How to use GetImage API method in C#? Anonymous |
15 year
|
Hello,
Could someone please provide a simple example of how to use the RoboRealm API's GetImage method in a C# or VB.NET program?
The API GetImage method has signature:
GetImage(string name, out object image, out object width, out object height)
Alas, I can't make any sense of this. I would have thought that the returned image would be a byte array but try as I might, I cannot turn the type "object" into a byte[].
I've been using the RoboRealm API to read variables without trouble. I do this by making a reference to RR_COM_API.dll that is included with the RoboRealm distribution.
I've looked at all the other related postings I could find on this forum but none of them include a simple example of how to make this work in C#--at least none that work for me.
So a simple example would be greatly appreciated!
Thanks,
patrick
|
|
|
Anonymous |
15 year
|
Hi Patrick
Try the following, we used the trennet camera as a current source example and it saves it to the temp folder
RR_API rr = new RR_API();
if (!rr.connect("localhost"))
{
MessageBox.Show("Could not connect to localhost!");
return;
}
Byte[] image = new Byte[1280*960];
Dimension d = rr.getDimension();
// get the current processed image from RoboRealm and save as a PPM
d = rr.getImage(image, 1280 * 960);
if (d != null)
{
//rr.savePPM(@"c:\temp\test.ppm", image, d.width, d.height);
rr.saveImage(null, @"c:\temp\test.jpg");
}
// disconnect from API Server
rr.disconnect();
program.robo
|
|
|
Anonymous |
15 year
|
Many thanks for your reply. However, I am using the DLL version of the API that comes with the main RoboRealm distribution. It is included as the file RR_COM_API.dll. In that version, the signature for GetImage is different than the one you are using, namely:
GetImage(string name, out object image, out object width, out object height)
so it won't work the way you describe. I'm starting to wonder if the RR_COM_API.dll version of the API is out of sync with the source code?
Thanks,
patrick
|
|
|
Anonymous |
15 year
|
Well if you must use a com interop, its not a full c# implementation then :) Note to other C# users trying this you will need to run TlbImp.exe on the RR_COM_API.dll and then reference RR_COM_APILib.dll in your code and not the RR_COM_API.dll directly. You may also need to run regsvr32 on RR_COM_API.dll in order for it to compile correctly. This code was tested on VS Express 2008
============================================
RR_COM_APILib.API_WrapperClass rr = new RR_COM_APILib.API_WrapperClass();
object height = "";
object width = "";
object image = "";
if (rr.Connect("localhost") == 0)
{
MessageBox.Show("Could not connect to localhost!");
return;
}
int d = rr.GetImage("Processed", out image, out width, out height);
if (d != 0)
{
rr.SaveImage("Processed",@"c:\temp\test.jpg");
}
// disconnect from API Server
rr.Disconnect();
|
|
|
Anonymous |
15 year
|
Thanks for the followup. Before you replied, I got it working by adding the C# API source directly to my project. But for completeness, I just now tried it with your com interop solution using VS2005 and that worked too.
One last question: I don't really want to write the image to a file: instead, I want to create a bitmap in memory from the RoboRealm image byte array. So using your original code, why does the following modification fail with error: "Parameter is not valid at ... System.Drawing.Image.FromStream(etc...)"?
RR_API rr = new RR_API();
if (!rr.connect("localhost"))
{
MessageBox.Show("Could not connect to localhost!");
return;
}
Byte[] image = new Byte[1280*960];
Dimension d = rr.getDimension();
// get the current processed image from RoboRealm and save as a PPM
d = rr.getImage(image, 1280 * 960);
if (d != null)
{
//rr.savePPM(@"c:\temp\test.ppm", image, d.width, d.height);
//rr.saveImage(null, @"c:\temp\test.jpg");
memoryStream ms = new MemoryStream(image);
Bitmap testImage = (Bitmap)Bitmap.FromStream(ms);
}
// disconnect from API Server
rr.disconnect();
|
|
|
Tom from United States [1 posts] |
13 year
|
Hi,
Is there is solution to this problem of how to use image with C# MemoryStream without getting "Parameter is not valid"?
Thanks.
|
|
|
Anonymous |
13 year
|
Tom,
Can you be a little more specific with your request? Can you post an example of your code that is generating the error? Or is this code from our API? Or is this even a RoboRealm related question?
Thanks,
STeven.
|
|
|
Anonymous |
13 year
|
Hi Steven,
My question was specific to the post before mine. The Anon. asked about how to get access to a Bitmap object and showed his code:
memoryStream ms = new MemoryStream(image);
Bitmap testImage = (Bitmap)Bitmap.FromStream(ms);
I also tried this and got the same parameter error. It looks to me like the image (that is the argument of MemoryStream) is not compatible with c# Bitmap.FromStream(ms);
The reason for doing this is to be able to post process the image outside of RoboRealm. With a Bitmap object it is very easy to analyse and show in c# form.
Thanks
Tom
|
|
|
from United States [214 posts] |
13 year
|
Hi Tom,
These are the methods I have been using in C# to get a Bitmap from RoboRealm. You don't have to use the imageBytes and imageDimensions arrays--I just use them for convenience. One in place, I use them like this:
getImageBytes("MyMarker");
Bitmap MyBitmap = getImageBitmap("MyMarker");
-----
private static SortedList<string, byte[]> imageBytes = new SortedList<string, byte[]>();
private static SortedList<string, int[]> imageDimensions = new SortedList<string, int[]>();
private static RR_API.RR_API RR;
RR = new RR_API.RR_API();
RR.connect("localhost");
public void getImageBytes(string marker)
{
int width = 1280;
int height = 960;
byte[] imageData = new byte[width * height];
Dimension d = null;
while (d == null)
{
d = RR.getImage(marker, imageData, width * height);
RR.waitImage(1);
}
if (imageBytes.ContainsKey(marker))
{
imageBytes[marker] = imageData;
imageDimensions[marker][0] = d.width;
imageDimensions[marker][1] = d.height;
}
else
{
imageBytes.Add(marker, imageData);
imageDimensions.Add(marker, new int[2]);
imageDimensions[marker][0] = d.width;
imageDimensions[marker][1] = d.height;
}
}
public Bitmap getImageBitmap(string marker)
{
return BitsToBitmapRGB24(imageBytes[marker], imageDimensions[marker][0], imageDimensions[marker][1]);
}
// Create RGB24 bitmap from Byte array
public Bitmap BitsToBitmapRGB24(Byte[] bytes, int width, int height)
{
//swap RGB to BGR
Byte tmp;
for (int x = 3; x < bytes.GetLength(0); x += 3)
{
tmp = bytes[(x + 2)];
bytes[x + 2] = bytes[x];
bytes[x] = tmp;
}
if (bytes.GetLength(0) < width * height * 3)
{
return null;
}
Bitmap bmp = new Bitmap(width, height, PixelFormat.Format24bppRgb);
int i;
BitmapData data = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.WriteOnly, bmp.PixelFormat);
if (data.Stride == width * 3)
{
Marshal.Copy(bytes, 0, data.Scan0, width * height * 3);
}
else
{
for (i = 0; i < bmp.Height; i++)
{
IntPtr p = new IntPtr(data.Scan0.ToInt32() + data.Stride * i);
Marshal.Copy(bytes, i * bmp.Width * 3, p, bmp.Width * 3);
}
}
bmp.UnlockBits(data);
return bmp;
}
--patrick
http://www.pirobot.org
|
|
|
Anonymous |
13 year
|
Patrick,
Thanks for that code. We merged the two routines in getImageBitmap and placed that into the API to help others with the same issue.
Thanks!
STeven.
|
|
|
from United States [214 posts] |
13 year
|
|