xion Posted March 15, 2005 Posted March 15, 2005 (edited) I've got great problems solving the following problem: I've got some high speed camera that comes with an c++ api and SDK. There is an OnFrameCapture callback Function that returns a C++ pointer to the starting point of some RAW Image data stored in unmanaged Memory Now I want to 1) Get the Image 2) convert it to jpeg 3) save it to hard disk - I know some header data of the image like size, bits/p, pitch... - The Pointer is returned as UInt32 - I also know the byte structure in memory (RGB24 / RGB32 / ...) My Program is in vb.net, but I could also include some c# code... All my tries ended up between the marshal class, API memory functions, unsafe code... Please help me! It's urgent! (code should work on sunday :o ) thx in advance Edited March 15, 2005 by xion Quote
IngisKahn Posted March 15, 2005 Posted March 15, 2005 System.Drawing.Image does all you need. It can be created from a handle and saved in your choice of formats. Quote "Who is John Galt?"
xion Posted March 16, 2005 Author Posted March 16, 2005 System.Drawing.Image does all you need. It can be created from a handle and saved in your choice of formats. Yes, but Drawing.Image cannot load from unmanaged memory! (would be the .fromHBitmap Function which doesn't work... Quote
HJB417 Posted March 16, 2005 Posted March 16, 2005 I'm assuming the pointer points to an array of bytes aka 'unsigned char*', determine the length of this byte array and 1) copy it using Marshal.Copy. 2) load the byte array in to a MemoryStream. 3) and using the new instance of the memory stream, invoke the method Image.FromStream. Quote
xion Posted March 16, 2005 Author Posted March 16, 2005 (edited) I'm assuming the pointer points to an array of bytes aka 'unsigned char*', determine the length of this byte array and 1) copy it using Marshal.Copy. 2) load the byte array in to a MemoryStream. 3) and using the new instance of the memory stream, invoke the method Image.FromStream. Good Idea, I'll try that! This would work, but the data returned in the byte array is no image data... Goin' to contact the manufacturer for information on that. Maybe there's some header included or the Image Size does not match ok, I've got to correct: This is indeed Image-Data (I can open the dumped stream with photoshop RAW import) but there is some miss-handling with the colormanagement. Maybe this is caused by the camera, that supports multiple formats like RGB32, RGB24, RGB16, RGB15, RGB8, Y8 Monochrome and so on... So: does anybody know how to pass these color formats to image.fromstream? (it rases an error if i call the function with the memorystream only) Edited March 16, 2005 by xion Quote
xion Posted March 16, 2005 Author Posted March 16, 2005 converting RAW image byte array to image / bitmap and convert it Now, the new Problem is to - convert the byte array to an image (using color management information) - convert the image to jpeg and - save it to disk (need a quite fast method, this should happen ~ 55 times/sec. thx in advance Quote
HJB417 Posted March 16, 2005 Posted March 16, 2005 unmanaged code = faster runtime speed managed code = faster developtime speed when mixing the two, you will have to use marshalling and usually this involves copying data from one runtime to another (e.x.: CRT -> CLR or vice versa). with the exception of converting the image to a jpeg, everything should be easy to do in c/c++. There are several free image processing/converting libraries for c/c++ as I've used a couple in the past. So my recommendation to you is to bust out some c/c++ code for faster code execution. The image class is also available in unamanged code via gdiplus.lib. Quote
xion Posted March 16, 2005 Author Posted March 16, 2005 unmanaged code = faster runtime speed managed code = faster developtime speed when mixing the two, you will have to use marshalling and usually this involves copying data from one runtime to another (e.x.: CRT -> CLR or vice versa). with the exception of converting the image to a jpeg, everything should be easy to do in c/c++. There are several free image processing/converting libraries for c/c++ as I've used a couple in the past. So my recommendation to you is to bust out some c/c++ code for faster code execution. The image class is also available in unamanged code via gdiplus.lib. I would need some ready source code to implement this - 'cause c++ is not my favourite - so to say - and as i said, the program has to be running on sunday. thx Quote
HJB417 Posted March 16, 2005 Posted March 16, 2005 post the c# code, and what are the specs of the machine you're using? Quote
xion Posted March 17, 2005 Author Posted March 17, 2005 post the c# code' date=' and what are the specs of the machine you're using?[/quote'] This is the vb .net code: vid is the activex control of the camera vid.InquireImageMem returns current image settings vid.GetImageMem returns the memory pointer as UInt32 Dim ptr As IntPtr Dim memsize, nwidth, nheight, nbits, npitch As Integer vid.InquireImageMem(nwidth, nheight, nbits, npitch) ptr = New IntPtr(Convert.ToInt32(vid.GetImageMem)) memsize = nwidth * nheight * nbits / 8 Dim b(memsize) As Byte Marshal.Copy(ptr, b, 0, memsize) Dim oFileStream As System.IO.FileStream oFileStream = New System.IO.FileStream("b" & nextfid & ".RAW", System.IO.FileMode.Create) oFileStream.Write(b, 0, b.Length - 1) oFileStream.Close() Dim stmBLOBData As New MemoryStream(b) preview.Image = Image.FromStream(stmBLOBData, False, False) 'This line rases the Error - wrong parameter nextfid += 1 what specs do you need? Quote
HJB417 Posted March 17, 2005 Posted March 17, 2005 1) why are you using a filestream and not a memory stream? Using a memory stream will be faster. 2) I see you loading the image, but I don't see code converting it to a jpeg and saving it. Quote
xion Posted March 17, 2005 Author Posted March 17, 2005 1) why are you using a filestream and not a memory stream? Using a memory stream will be faster. 2) I see you loading the image, but I don't see code converting it to a jpeg and saving it. Thank you for your help - but I found the most easy and through gdi+ also fast method: Dim ptr As IntPtr Dim memsize, nwidth, nheight, nbits, npitch, stride As Integer vid.InquireImageMem(nwidth, nheight, nbits, npitch) stride = nwidth * nbits / 8 ptr = New IntPtr(Convert.ToInt32(vid.GetImageMem)) Dim im As New Bitmap(nwidth, nheight, stride, get_PixelFormat, ptr) im.save... Don't know why it took me so long to find this out - but searching through the web this solution is hardly mentioned... Quote
xion Posted March 17, 2005 Author Posted March 17, 2005 1) why are you using a filestream and not a memory stream? Using a memory stream will be faster. 2) I see you loading the image, but I don't see code converting it to a jpeg and saving it. 1) it is a memory stream, i just save the raw data into a file to debug it... like a memory dump. 2) well, i wasn't able to convert it up to now... but take the source code of my last post. this is everything I ever wanted :) works great at 40FPS and more... Still have to make some improvements, but alltogether it shouldn't make any problems... Thx, guys - Wishing to help once too, xion Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.