Jump to content

Using the DLL files of an application compiled with C# with labview


Recommended Posts

There definitely is data in the "Image Data" Cluster.

Of course you forgot again to show the part of the screen where it would display the "new picture" to proof your claim that there is nothing shown. So we can not tell what is captured but something for sure is captured.

You may also want to remove the Draw Unflattened function. It adds nothing anymore.

Edited by Rolf Kalbermatter
Link to comment
3 hours ago, Rolf Kalbermatter said:

Doesn't matter. The SDK draws asynchonously into the Picture Box window. No matter which window handle you use, the moment you cause the screen capture from the window handle to occur is totally and completely asynchronous to the drawing of the SDK. And there is a high chance that the screen capture operations BitBlit() or PrintWindow() will capture parts of two different images drawn (blitted into the window) by the SDK function.

I meant this part:

image.png.0ca1697625027e333ffa6b7273ff980b.png.0ac882a5b2475fe59c68c2abe32b9ec9.png

It just makes no sense to capture Empty.vi window and a little sense to capture the whole main VI window, when a concrete .NET window region is wanted. Ok, when drawn onto Empty.vi panel, the whole window must be captured.

Edited by dadreamer
Link to comment

There exists an easier callback variation, that doesn't involve calling PostLVUserEvent. I have used it few times in the projects with VLC video streaming from several cameras. It's an asynchronous method too, but it works for sure. The main point is that on the diagram we call DSNewPtr and pass new pointer to the library. When the callback is called, it just writes data by that pointer. In LabVIEW we just read the data by the pointer constantly and process it, if necessary. It's good for common video translation or for simple image processing, when not each video frame is required. Still needs the DLL to be written/compiled though.

Link to comment
7 minutes ago, dadreamer said:

There exists an easier callback variation, that doesn't involve calling PostLVUserEvent. I have used it few times in the projects with VLC video streaming from several cameras. It's an asynchronous method too, but it works for sure. The main point is that on the diagram we call DSNewPtr and pass new pointer to the library. When the callback is called, it just writes data by that pointer. In LabVIEW we just read the data by the pointer constantly and process it, if necessary. It's good for common video translation or for simple image processing, when not each video frame is required. Still needs the DLL to be written/compiled though.

I have no idea how to do this, if anyone guides me I can go step by step :)

Link to comment

You can copy the snippet. Explanation: The Bitmap is a constructor node, and you give it the image reference. Then you get the data, in this case, one RGB pixel at 0,0. If this works, the bitmap object has a method that returns the handle to the data.

Edit: The Bitmap constructor is in System.drawing.

If you are worried about tearing (capturing data from 2 different frames) you can use the PictureBox' VisibleChanged LoadCompleted callback.

Edited by Gribo
Link to comment

I have nothing to add to this thread, other than @alvise I think if you get this working you owe a few people some beer 🙂

To those patiently contributing to this thread, I sincerely thank you. This community is so much stronger due to you folks. Please never leave!

Link to comment
3 hours ago, Gribo said:

You can copy the snippet. Explanation: The Bitmap is a constructor node, and you give it the image reference. Then you get the data, in this case, one RGB pixel at 0,0. If this works, the bitmap object has a method that returns the handle to the data.

Edit: The Bitmap constructor is in System.drawing.

If you are worried about tearing (capturing data from 2 different frames) you can use the PictureBox' VisibleChanged LoadCompleted callback.

That callback will almost certainly never get triggered! The SDK is not aware about that it is drawing into a .Net PictureBox. It only sees the window handle that is used by the PictureBox for its drawing canvas. And that works on a level way below .Net in the Windows window manager inside the kernel. If you would try to do anything with that PictureBox such as drawing lines or anything into, it you would get very nasty flickering as the SDK function trying to bitblit into the windows device context (HDC) will fight with the PictureBox functions who tries to do GDI drawing into the same HDC. We are abusing here the PictureBox simply as a container to provide a window handle. In this way we can let Windows window clipping handle all the issues about making sure that the SDK can't draw beyond that area provided by the PictureBox control. But for the rest we are not really using any functionality from the PictureBox .Net control. Respectively when we tried to retrieve the image, that failed since the PictureBox control is not aware about what was drawn into its window. And the same applies for the LabVIEW Get Image control function.

Edited by Rolf Kalbermatter
Link to comment
9 hours ago, dadreamer said:

I meant this part:

image.png.0ca1697625027e333ffa6b7273ff980b.png.0ac882a5b2475fe59c68c2abe32b9ec9.png

It just makes no sense to capture Empty.vi window and a little sense to capture the whole main VI window, when a concrete .NET window region is wanted. Ok, when drawn onto Empty.vi panel, the whole window must be captured.

It wasn't me who brought that back into the discussion. I was under the strong impression that we were already working for some time on the PictureBox solution as drawing canvas area. alvise suddenly brought this Empty.vi subpanel solution back into the picture.

Edited by Rolf Kalbermatter
Link to comment
9 hours ago, Neil Pate said:

I have nothing to add to this thread, other than @alvise I think if you get this working you owe a few people some beer 🙂

To those patiently contributing to this thread, I sincerely thank you. This community is so much stronger due to you folks. Please never leave!

My debt is debt :) The problem here is weird and interesting.

 

Gribo I agree with what rolfk said here. I tried something like this and got no results.

6 hours ago, Rolf Kalbermatter said:

That callback will almost certainly never get triggered! The SDK is not aware about that it is drawing into a .Net PictureBox. It only sees the window handle that is used by the PictureBox for its drawing canvas. And that works on a level way below .Net in the Windows window manager inside the kernel. If you would try to do anything with that PictureBox such as drawing lines or anything into, it you would get very nasty flickering as the SDK function trying to bitblit into the windows device context (HDC) will fight with the PictureBox functions who tries to do GDI drawing into the same HDC. We are abusing here the PictureBox simply as a container to provide a window handle. In this way we can let Windows window clipping handle all the issues about making sure that the SDK can't draw beyond that area provided by the PictureBox control. But for the rest we are not really using any functionality from the PictureBox .Net control. Respectively when we tried to retrieve the image, that failed since the PictureBox control is not aware about what was drawn into its window. And the same applies for the LabVIEW Get Image control function.

I tried to capture the image for the whole Main VI screen, everything is showing but the video in the picturebox area is not showing, interesting thing.

image.png.2c0648121086fc19dcd1e99a59f05e4c.png

 

 

image.png.0c93f6bdcbb91e6d551ab72b99ae6dfc.png

6 hours ago, Rolf Kalbermatter said:

It wasn't me who brought that back into the discussion. I was under the strong impression that we were already working for some time on the PictureBox solution as drawing canvas area. alvise suddenly brought this Empty.vi subpanel solution back into the picture.

I was wondering how it would be with the VI screen, but of course the result is disappointment :)

Link to comment
Posted (edited)

I guess that's the method dadreamer said.

I tried this and got a result like the one below. It can take a screenshot, but it has a disadvantage, of course, it reads the whole of the main screen and reads it according to the movement of the slider bar :)

image.png.0f57f87db8dfba4b2b2ca0a0fc39be9e.png

image.png.ff7aabc2ac5aa8c6799817329a5ef3be.png

 

 

The disadvantages are the same in both cases because if I pull the scroll bars down, the image changes.The good thing about this method is that it only takes the picturebox screen. But Moving the scrollbar of the Fronpanel turns the picturebox a black color around it.

image.png.6dbf905f2aa4a9542d869893e124ff61.png

image.png.37ef4dcf1c86ea33962560c41e6747bc.png

Edited by alvise
Link to comment

Glad something finally worked for you 🙂 What about pressing that BitBlt button? And you don't need to cast the handle to U64 - just change ToInt32 method to ToInt64 and pass the wires to the VI.

Edited by dadreamer
Link to comment
Posted (edited)

 

19 minutes ago, dadreamer said:

 pass further to the VI.           

I don't quite understand what you mean to say here.

 

-BitBlt button is already pressed, if I don't press it, it can't take any image.
I changed it to -ToInt64, it's ok.

It works, but there is a small problem :)
It must always have two images on the screen and the Picturebox must always be in the middle of the screen, right?

 

image.png

 

Edited by alvise
Link to comment
27 minutes ago, alvise said:

It must always have two images on the screen and the Picturebox must always be in the middle of the screen, right?

Since BitBlt is used, your PictureBox object should be visible and on screen completely, because when it's not, then black areas are captured. PrintWindow on the other side should deal with (partially) hidden windows better, but I have no idea why it doesn't work in your case.

Edited by dadreamer
Link to comment
Posted (edited)

Having two images and especially the Picturebox screen that is constantly on the screen takes up a lot of space and I can't always fit it on the screen. You mentioned earlier a method that can be done without using callback. What method is this? and also I don't know how to create a C++ example code with callback function as I don't really understand the callback thing.

Edited by alvise
Link to comment
18 minutes ago, alvise said:

You mentioned earlier a method that can be done without using callback. What method is this?

Callback is still needed. I said that PostLVUserEvent call may be omitted.

On 5/27/2022 at 5:00 PM, dadreamer said:

There exists an easier callback variation, that doesn't involve calling PostLVUserEvent.

If you don't know C even at very basic level and can't compile DLLs, I'm afraid I can't help here. There are many example on making C/C++ DLLs on the net. My advice is to learn them carefully and only after that go to callback things.

Link to comment
Posted (edited)

I know c/c++ at a basic level. I can compile it if there is a sample code. I just don't know how to create a piece of code for this callback function.

 

Edited by alvise
Link to comment
Posted (edited)

In fact, I'm clearly convinced that I should work with the Callback function. When I try to draw directly on the picturebox picture the video starts fighting with the picture drawn on the screen and I get a very bad flicker. This causes a lot of hassle when trying to use it with image processing.
So in this case there is nothing left to do, I will have to create a wrapper dll.

Edited by alvise
Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.