Gstreamer dx9screencapsrc/gdiscreencapsrc change captured area while playing - c#

I'm trying to set up one of the above sources to capture the screen on a windows machine. Everything works fine apart from one important detail: I can't change the coordinates of the captured window in either src while pipeline is playing.
I'm currently using C# + Gstreamer-Sharp, yet I'm already considering a native C wrapper.
Should I be able to change the position of the window using the above plugins while playing?
If yes, could this be a problem related to Gstreamer-sharp?
Or does it require a procedure other than simply changing the values of the elements in the pipe?
This is what I do...
var pipeline = new Gst.Pipeline();
screenCapSource = Gst.ElementFactory.Make("gdiscreencapsrc", "ScreencapSource") as Gst.Base.PushSrc;
SetCapWindow(0,0,320,240); //<- works
//Capsfilter...
//X264 encoder
//udpsink
//link...
//launch pipleline
//working fine...
//When pipeline is playing, this doesn't work.
//I never change the dimensions, only the position of the window - to no effect.
public void SetCapWindow(Int32 x, Int32 y, Int32 width, Int32 height){
screenCapSource["x"] = x;
screenCapSource["y"] = y;
screenCapSource["width"] = width;
screenCapSource["height"] = height;
}
This issue has been posted before on the Gst mailing list by me and others but no replies.
BTW: A workaround would be using an Appsink to push screencaps into the pipeline from managed code, performance isn't great however.

Related

NTwain ICapSupportedSizes is Not Supported

I'm using NTwain to scan documents into memory and I have it all working except for one part: When trying to set the size of the page to scan, it scans the entire width and height, rather than just the specified size.
I went and examined the details of NTwain's capabilities on the current source, and found the the ICapSupportedSizes was not supported for any action.
Here's how I'm setting the capabilities (this is on an open, valid source)
_twain.CurrentSource.Capabilities.ICapXResolution.SetValue(new TWFix32() { Whole = 600 });
_twain.CurrentSource.Capabilities.ICapYResolution.SetValue(new TWFix32() { Whole = 600 });
_twain.CurrentSource.Capabilities.ICapPixelType.SetValue(PixelType.BlackWhite);
_twain.CurrentSource.Capabilities.ICapSupportedSizes.SetValue(SupportedSize.USLegal);
_twain.CurrentSource.Capabilities.CapDuplexEnabled.SetValue(BoolType.False);
UPDATE:
I've found out that none of the settings are actually working. I set it as black and white, even if it shows black and white in the settings, it displays in color. Doesn't matter what DPI I set it at either as it defaults to 300 no matter what. I've updated it to grab out the source and use that to change the settings and call Enable, but it still doesn't work.
Any help is appreciated.
Thanks!
Enviornment Information
.NET Framework 4.6.1
Win Forms
C#
NTwain
Scanner: Canon Flatbed Scanner Unit 102
You will need to use the DGImage.ImageLayout property to set the page size in a generally-supported way.
For example:
var ds = _twain.CurrentSource;
ds.Capabilities.ICapUnits.SetValue(Unit.Inches);
ds.DGImage.ImageLayout.Get(out TWImageLayout imageLayout);
imageLayout.Frame = new TWFrame
{
Left = 0,
Right = pageWidthInInches,
Top = 0,
Bottom = pageHeightInInches
};
ds.DGImage.ImageLayout.Set(imageLayout);

C# Program Only Works in Debug Mode

Me and some of my colleagues are working on a project together, and have encountered a weird issue we can't manage to fix.The project involves the creation of a VNC connection between a client and a server, and is written in C# (we're using Visual Studio 2010). We're using the VNCSharp library for the client.The issue I speak of is that once we start the connection with the server, an ArgumentException is thrown.
Some of the information supplied was this:
********** Exception Text **********
System.ArgumentException: Parameter is not valid.
at System.Drawing.Bitmap..ctor(Int32 width, Int32 height, PixelFormat format)
at VncSharp.RemoteDesktop.SetupDesktop()
at VncSharp.RemoteDesktop.Initialize()
at VncSharp.RemoteDesktop.Connect(String host, Int32 display, Boolean viewOnly, Boolean scaled)
at VncSharp.RemoteDesktop.Connect(String host)
at RemoteDesktopTest.Form2.startConnection()
Another weird thing about this is that it only occures some of the times, whereas in others it works perfectly well. Specifically, it always works when run in debug mode (i.e, when we run the program line-by-line using F11), and either works or doesn't work when run regularly (i.e Ctrl+F5), without any pattern we could recognize.
We would be really grateful for any and all help; if there are any details I can add that would assist in the answering of this question, please let me know.
Additionally, I apologize for any grammar/spelling mistakes; English is not my first language... and I also apologize if something about this question is not alright. We're all beginners and this is our first "big project", so this is also my first time asking a question in Stack Overflow.
EDIT:
There are some parts of the code that are potentially relevant.
These are the lines of code automatically generated after we added the VncSharp control to the form and customized its settings:
this.remoteDesktop1 = new VncSharp.RemoteDesktop();
this.remoteDesktop1.AutoScroll = true;
this.remoteDesktop1.AutoScrollMinSize = new System.Drawing.Size(608, 427);
this.remoteDesktop1.Dock = System.Windows.Forms.DockStyle.Fill;
this.remoteDesktop1.Location = new System.Drawing.Point(0, 0);
this.remoteDesktop1.Name = "remoteDesktop1";
this.remoteDesktop1.Size = new System.Drawing.Size(1113, 580);
this.remoteDesktop1.TabIndex = 1;
This is the line of code in which I call the Connect method, while IP is simply the string taken from a text box:
remoteDesktop1.Connect(this.IP);
These are from the method which handles the ConnectComplete event (e is the EventArgs object passed to the method):
this.Location = new Point(0,0);
this.Size = Screen.PrimaryScreen.WorkingArea.Size;
this.remoteDesktop1.Size = new System.Drawing.Size(e.DesktopWidth, e.DesktopHeight);
Aside from the line in which the Disconnect method is called, we've written literally no other lines of code that deal with this object. If I'll realize I'd forgotten something, I'll edit again and add it. Also, if there's anything specific in the code I should add here, please let me know.
The issue was related to timing, it seems.
Out of debug mode, the program ran too fast and those width and height variable didn't have their values updated.
Luckily, VncSharp is open source, so I could add my own line and leave it in a loop as long as either of those two variables still has its default value, and now it works.
Thanks for the help, everyone :)
Had the same problem. For me it worked to compile the vncsharp solution in debug mode.
In RfbProtocol line 398 (first line of the ReadServerInit method), I transformed
int w = Reader.ReadUInt16();
to
int w = 0;
while (w == 0)
w = Reader.ReadUInt16();

.NET - Capturing cursor bitmap at specific coordinates

DISCLAIMER
This question is somewhat similar to another on StackOverflow, C# - Capturing the Mouse cursor image - but with a slightly different requirement.
BACKGROUND
I am writing a scriptable automation client that scraps data from 3 legacy Win32 systems.
Two of these systems may indicate the presence of finished tasks via a change in cursor bitmap when the cursor is hovered over some specific areas. No other hints (color change, status message) are offered.
My own code is derived from the original post mentioned on the disclaimer.
REQUIREMENTS
While I an able to capture the cursor bitmaps by programatically moving the cursor to a specific coordinate and capturing it via CURSORINFO, the idea was to allow an interactive user to continue using the computer. As it is, the forced positioning disrupts the process.
QUESTION
Is there a way to capture the cursor bitmap by parametrized position (e.g., request the CURSORINFO as if the focus was in window W at coordinates X, Y)?
A solution fulfilling the specifics of this question was implemented using the information provided by Hans Passant, so all credit must go to him.
The current setup is as shown:
It runs on a machine with two displays. Not shown in the picture is a small application that is actually responsible for the event monitoring and data scraping - it runs minimized and unattended.
Solution
Obtain the Window handle for the application to be tested (in this case, I cycled through all processes returned by Process.GetProcesses():
IntPtr _probeHwnd;
var _procs = Process.GetProcesses();
foreach (var item in _procs)
{
if (item.MainWindowTitle == "WinApp#1")
{
_probeHwnd= item.MainWindowHandle;
break;
}
}
With the window handle for the target application, we are now able to craft specific messages and send to it via SendMessage.
In order to pass coordinates to SendMessage we need to serialize both X and Y coordinates into a single long value:
public int MakeLong(short lowPart, short highPart)
{
return (int)(((ushort)lowPart) | (uint)(highPart << 16));
}
Knowing the specific coordinates we want to probe (_probeX,_probeY), now we can issue a WM_NCHITTEST message:
SendMessage(_probeHwnd, WM_NCHITTEST, NULL, (LPARAM)MakeLong(_probeX, _probeY));
We need GetCursorInfo to obtain the Bitmap:
Win32Stuff.CURSORINFO ci = new Win32Stuff.CURSORINFO();
Win32Stuff.GetCursorInfo(ci);
Check if the return flag from GetCursorInfo indicates that the cursor is showing (pco.flags == CURSOR_SHOWING):
Use CopyIcon in order to obtain a valid handle for the cursor bitmap:
IntPtr hicon = default(IntPtr);
hicon = Win32Stuff.CopyIcon(ci.hCursor);
Use GetIconInfo to extract the information from the handler:
Win32Stuff.ICONINFO icInfo = default(Win32Stuff.ICONINFO);
Win32Stuff.GetIconInfo(hicon, icInfo);
Use the System.Drawing.Icon class to obtain a manageable copy using Icon.FromHandle, passing the value returned by CopyIcon;
Icon ic = Icon.FromHandle(hicon);
Extract the bitmap via Icon.ToBitmap method.
Bitmap bmp = ic.ToBitmap();
Limitations
This solution was tested on two different OSes: Windows XP and Windows 8. It only worked on Windows XP. On Windows 8 the cursor would flicker and return to the 'correct' format immediately, and the the captured CURSORINFO reflected that.
The test point areas must be visible (i.e., application must not be minimized, and test points can't be under an overlapping window. Tested window may be partially overlapped, though - and it doesn't need to have focus.)
When WM_NCHITTEST is issued, the current physical cursor over WebApp changes to whatever cursor bitmap is set by the probed application. CURSORINFO contains the cursor bitmap set by the probed application, but the coordinates always indicate the 'physical' location.

Fellow Oak DICOM - changing image window level

I am not an experienced programmer, just need to add a DICOM viewer to my VS2010 project. I can display the image in Windows Forms, however can't figure out how to change the window center and width. Here is my script:
DicomImage image = new DicomImage(_filename);
int maxV = image.NumberOfFrames;
sbSlice.Maximum = maxV - 1;
image.WindowCenter = 7.0;
double wc = image.WindowCenter;
double ww = image.WindowWidth;
Image result = image.RenderImage(0);
DisplayImage(result);
It did not work. I don't know if this is the right approach.
The DicomImage class was not created with the intention of it being used to implement an image viewer. It was created to render preview images in the DICOM Dump utility and to test the image compression/decompression codecs. Maybe it was a mistake to include it in the library at all?
It is difficult for me to find fault in the code as being buggy when it is being used for something far beyond its intended functionality.
That said, I have taken some time to modify the code so that the WindowCenter/WindowWidth properties apply to the rendered image. You can find these modifications in the Git repo.
var img = new DicomImage(fileName);
img.WindowCenter = 2048.0;
img.WindowWidth = 4096.0;
DisplayImage(img.RenderImage(0));
I looked at the code and it looked extremely buggy. https://github.com/rcd/fo-dicom/blob/master/DICOM/Imaging/DicomImage.cs
In the current buggy implementation setting the WindowCenter or WindowWidth properties has no effect unless Dataset.Get(DicomTag.PhotometricInterpretation) is either Monochrome1 or Monochrome2 during Load(). This is already ridiculous, but it still cannot be used because the _renderOptions variable is only set in a single place and is immediately used for the _pipeline creation (not giving you chance to change it using the WindowCenter property). Your only chance is the grayscale _renderOptions initialization: _renderOptions = GrayscaleRenderOptions.FromDataset(Dataset);.
The current solution: Your dataset should have
DicomTag.WindowCenter set appropriately
DicomTag.WindowWidth != 0.0
DicomTag.PhotometricInterpretation == Monochrome1 or Monochrome2
The following code accomplishes that:
DicomDataset dataset = DicomFile.Open(fileName).Dataset;
//dataset.Set(DicomTag.WindowWidth, 200.0); //the WindowWidth must be non-zero
dataset.Add(DicomTag.WindowCenter, "100.0");
//dataset.Add(DicomTag.PhotometricInterpretation, "MONOCHROME1"); //ValueRepresentations tag is broken
dataset.Add(new DicomCodeString(DicomTag.PhotometricInterpretation, "MONOCHROME1"));
DicomImage image = new DicomImage(dataset);
image.RenderImage();
The best solution: Wait while this buggy library is fixed.

Emulating click based event on a web page

This link goes to an implementation of the imagination captcha imagination
The authors have themselves requested for people to make algorithms to try its efficiency against AI attacks.
Essentially the first page is asking for a mouse click anywhere on the image... My problem is that my algorithm comes up with the point (x,y) on the image but I want to emulate it real time on this link...
Can some one tell me how can i send the point values on this link and get back the message whether i was successful or not....
Essentially I am asking how can i emulate a mouse click on this link at the points that my algorithm gives using C#...
I am asking this only for studying the features of this captcha and its accuracy.
Thanks a lot
If you are able to execute JavaScript on that page directly, this code will do:
submitClick(document.getElementById("img").value, x, y, "tiled");
Otherwise, hit this url, substituting your own values for id, x, and y:
http://goldbach.cse.psu.edu/s/captcha/captcha_controller.php?id=87170&x=66&y=149&source=tiled
Parse the response - If your coordinates are correct, the response will contain "step 2". If not, the response will contain "step 1" and it will have a <div id="error">.
If you want to use their live site from code, I think you're talking about a screen scrape. I highly recommend looking into the HTML Agility Pack (available via nuget). This is going to allow you to read the DOM into your application and then interact with it however you please.
This could be a dumb answer but if you're trying to emulate a mouse click and find out if it's successful, why not use the Selenium Browser add-in to record your scripts / write' your own.
Then you can have a test suite to try against you're various different captchas.... hope this achieves what you're trying to do....
WebAii over at telerik has this feature. Here is some sample code i used at some point in the past customized for your situation. just put this in a class, left out the class container because it jacks up the formatting
protected static Manager _manager = null;
protected static Manager _manager = null;
protected Browser _main;
protected Find _find;
public WebAiiAutomater()
{
if (_manager != null)
{
foreach (var broswer in _manager.Browsers)
{
broswer.Close();
}
return;
}
var settings = new Settings(BrowserType.InternetExplorer, #"c:\log\") { ClientReadyTimeout = 60 * 1000 };
_manager = new Manager(settings);
_manager.Start();
_manager.LaunchNewBrowser();
_manager.ActiveBrowser.AutoWaitUntilReady = true;
_main = _manager.ActiveBrowser;
_find = _main.Find;
_main.NavigateTo(#"http://goldbach.cse.psu.edu/s/captcha/");
//start looping over your alogrithm trying different x,y coords against ClickImage(x,y
}
public bool ClickImage(int x, int y)
{
//var beginsearch = _find.ById("captcha_img"); //this should get you the image, but you don't need
_manager.Desktop.Mouse.Click(MouseClickType.LeftClick, x, y);
Thread.sleep(1000); //wait for postback - might be handled internally though
var errordiv = _find.ById("error");
return errordiv !=null;
}

Categories