I am trying to set individual pixels on a Gtk.Image widget. The documentation states that the ImageProp property of a Gtk.Image returns a Gdk.Image which seems to let you edit the individual pixels, but whenever I use this it only returns null.
My solution so far is to load the image from disk as a System.Drawing.Bitmap, edit it, save it to a temporary file, then load it back into a Gtk.Image, but this is obviously not ideal.
For
Gtk.Image image = new Gtk.Image("images/test.png");
Gdk.Image gdkImage = image.ImageProp;
Why is gdkImage always null?
The image itself loads and displays correctly.
Although I have no prior experience with GTK# or C#, based on whatever little I know about Gtk & what I could look up online, I will make an attempt to provide some inputs.
You can get Gdk.Image for a Gtk.Image only if you have created the Gtk.Image from a Gdk.Image using the mentioned property, otherwise you will get null as in your case where you are creating it from a file or as suggested by creating it from Gdk.Pixbuf. In current case, you could try to get Gdk.Image from Gdk.Drawable using Gdk.Drawable.GetImage method or use Gdk.Image.Get method. You can make use of GdkWindow associated with Gtk.Image as Gdk.Drawable in the mentioned cases. For Gdk.Window to be valid the widget should have been shown or realized. But it is quite likely that you may end with null in both the cases.
Side Note: GdkImage APIs are deprecated in the newer versions of Gtk, please note it may not be so in the case of GTK# as yet.
Thus it might be a good idea to use Gdk.Pixbuf instead. It is possible to get pixels for GdkPixbuf and modify the same in GTK. But unfortunately it appears that in case of GTK# that particular property (Pixels) of Gdk.Pixbuf is made as read only. One option maybe to use Gdk.Pixdata from Gdk.Pixbuf which is created from the image, modify the pixels using methods in Gdk.Pixdata, create a Gdk.Pixbuf out of it & copy that back to the original Gdk.Pixbuf. Unfortunately I cannot be sure about this, you can give it a shot though.
Alternatively you can consider drawing onto Gdk.Drawable. There are examples available wherein the Gdk.Drawable assocaited with Gtk.Widget (usually Gtk.DrawingArea) is updated in the Expose Event callback.
I hope that the information provided can provide you with some pointer to proceed.
Use Pixbuf first:
Gdk.Pixbuf pixbufImage = new Gdk.Pixbuf(#"images/test.png");
Gtk.Image gtkImage = new Gtk.Image(pixbufImage);
Gdk.Image gdkImage = gtkImage.ImageProp;
Related
I'm trying to render a SkiaSharp element in my WPF application using an OpenGL backend in the hopes of making it faster. I found this documentation explaining how to work with the resulting surface created, but it has this extremely unhelpful sentence in it:
Skia does not create a OpenGL context or Vulkan device for you. In OpenGL mode it also assumes that the correct OpenGL context has been made current to the current thread when Skia calls are made.
The documentation then proceeds to also assume that I know how to create said OpenGL or Vulkan device. After Googling this for an hour or so, I can tell you there are a few ways to do this (apparently), involving OpenTK, or creating the context manually, or using a WindowsFormsHost to host my drawing element, but I have been completely unable to find any specific information on what I need to do to make these things happen. If I have found this info in my Google searches, I lack the knowledge to recognize it as the answer.
To be 100% clear, what I'm asking is this: What do I need to do before the following lines of code will work?
var context = GRContext.CreateGl();
var gpuSurface = SKSurface.Create(context, true, new SKImageInfo(PageData.Instance.GetTotalWidth(), PageData.Instance.GetTotalHeight()));
Still looking for alternatives that don't require adding a 5 MB DLL just to use one object, but this is what I have for now.
I ended up going with this after installing OpenTK and OpenTK.GLControl from NuGet:
public SKSurface GetOpenGlSurface(int width, int height)
{
if (GPUContext == null)
{
GLControl control = new GLControl(new GraphicsMode(32, 24, 8, 4));
control.MakeCurrent();
GPUContext = GRContext.CreateGl();
}
var gpuSurface = SKSurface.Create(GPUContext, true, new SKImageInfo(width, height));
return gpuSurface;
}
It's worth noting that doing this and rendering various images using the GPU instead actually drastically cut performance, even with a decent video card. This is probably because I'm terrible at this, and I'm introducing bottlenecks. I suspect someone who knows what they're doing can avoid these pitfalls just fine.
We have some legacy code that has some... odd mannerisms. You can't really trust the file extension to know what kind of file it is. The big example is that the jpgs are actually tifs.
There may be other intricacies so I can't expect anything but the file's data itself to tell me if an image can be processed. I've wrapped it in a try/catch for now but I don't like using exceptions for flow control.
try
{
using (Bitmap current = (Bitmap)Bitmap.FromFile(file))
{
// Use current
}
}
catch
{
// Must not be an image file
}
We can't change legacy code to make sense. Is there a better way than this to know that file is an image?
It may sound dumb, but Bitmap opens files that are bmp or derivatives(png,jpeg, etc)
Could you try to check if the file extension has any of those extensions?
First off, you probably want to be using Image.FromFile instead of Bitmap.FromFile.
There really is no easy way to do what you're asking. FromFile will delegate to GDI+, and there's no way to know if GDI+ will like the file or not until you actually try to open it.
You could try to write code to do some basic sanity check the headers of all the image types you want to support. In the end though, it's still very possible that the header will be valid but the file itself will be corrupt. Also, you've added a new piece of complexity and possible vector for bugs in your code for processing image headers.
I would argue that this is in fact an exceptional case, and not an example of using exceptions for flow control. If a file that you think is an image turns out to not be, that's an exception.
I have a class that wraps around a Bitmap and I would like to have a way of knowing if the bitmap has been changed (via SetPixel or GDI+).
I don't need to know exactly when it happens, I just need a way to tell if it has happened since the last check.
Now, I'm assuming that something like that isn't already packed in the Bitmap class, so what would be the best way to solve this problem?
I could provide my own wrapper functions for GetPixel and SetPixel, but then I'd have no idea if the Bitmap was changed using GDI. I COULD make a wrapper for that too but that really seems like a huge overkill.
Another possible option would be to save a copy and then check pixel by pixel. This would obviously work and would be trivial to write but it's much too slow for my needs.
You should use a hash or check sum. There are some easy ways to do this but I think the simplest way would be to have a string hash property in your class then call GetHashCode() on the bitmap/binary string/whatever container you're storing it in. Set it to the classes property, check the current hashcode against that value to see if anything has changed. You could also write your own little checksum function or choose from (I'm sure) a vast array of third party options.
I'm currently trying to help automate some coded UI tests using C# for a web application. A frequent problem I'm encountering is that it can be extremely difficult to determine if a UITestControl object exists on the page or not. Unfortunately, Microsoft's documentation on their MSDN website for anything regarding coded UI tests is practically non-existant (see here their page for UITestControl).
Basically what I'm asking is:
What is the best way to determine if a UITestControl exists on the page or not?
How does the UITestControl.Exists property work?
What does the UITestControl.Find() method do?
How does the UITestControl.TryFind() method work?
How I've tried to handle it:
As I mentioned earlier, the documentation on all of these classes and methods is mostly blank. The most you can get to describe any of the methods and properties is a 1 line description in Intellisense, so I've been experimenting with the methods that are listed.
First I tried checking if the UITestControl.Exists property was true, but over time and consulting others' experience with it, it became apparent that it always returns true, even if the browser isn't open. Since the option that seemed most obvious wasn't working, I tried using the UITestControl.Find() method, but since it takes no arguments and returns nothing I couldn't figure out what it did. I tried using the UITestControl.TryFind() method, and occasionally it worked, but I found that it only seemed to return false when I wasn't on the correct page; it always returned true otherwise. Clearly I had no idea how it worked, and shouldn't use it as a test.
I figured if I couldn't get the provided methods to do their job, I'd have to try to make my own tools. I most recently tried using Mouse.Hover(UITestControl) in a try/catch block to determine if the control exists like so:
public bool DoesExist(UITestControl control){
if(control == null)
return false;
try{ Mouse.Hover(control); }
catch (UITestException)
{
return false;
}
return true;
}
It works sometimes, but in certain situations it seems to return false positives for reasons I don't understand. I'm still flying blind, and I'm nearly out of ideas.
I am using Visual Studio 2012, and Microsoft .NET Framework version 4.5.50709.
Partial answer about the Find() and TryFind() methods.
After setting the various search properties in the class instance for the control the Find() method does the actual searching for a control to match. The SearchProperties are used to try and find a control. If no controls are found then the search fails - forget exactly what happens then, possibly an exception is thrown but the documentation does not state that. If one control is found that the Find() completes. If two or more are found then the search continues by using FilterProperties to reduce the number of controls found to one.
The Coded UI recorder generates code of the style UIControl aControl = this.UIMap.uione.uitwo.uithree; which leads to the question of how does uione get a value referring to a control such that uitwo can be evauated? The only answer I have found is in the Description part of http://blogs.msdn.com/b/balagans/archive/2009/12/28/9941582.aspx which says "the search for the control starts ( explicit by Find() or implicit by any usage of the control in actions or property validations )".
So Find() performs the search for a control and it can be called explicitly or implicitly.
TryFind() is basically the same as Find() except that it returns a boolean indicating whether the control was found. Again, the documentation is poor but I believe that TryFind() returns true if exactly one control is found, false otherwise.
Another useful find method is FindMatchingControls which returns a (possibly empty) collection of all controls that match the search criteria.
As per yonitdm's answer, using the BoundingRectangle can help when there are multiple items that match but most are not on display. The values of Top and Left can also be used. Doing a FindMatchingControls and screening the results to ignore anything with negative Top or Left may work.
When developing tests the DrawHighlight method is useful, it draws a rectangle around a control. The same sort of rectangle that is drawn when recording assertions with the cross-hairs tool.
The Coded UI content index has lots of good information. The link to "How does UI Test Framework find (search) for a control" may be particularly helpful for you.
Instead of using obj.Exists() we have coded our own exists method that uses a combination approach of EnsureClickable() and BoundingRectangle.Width>0 to make sure that the control has a screen point.
ETA- oops, sorry left off an important part. Updated to add .Width to make sure it's greater than 0, you may need to use length if you width is somehow not working.
I am using tryfind() .. it is working fine.
if (obj_webor.GenLink.TryFind())
{
logdata.WriteLine(obj_webor.GenInnerText + " Exist !");
}
else
{
logdata.WriteLine(obj_webor.GenInnerText + " Does Not Exist");
}
Earlier i was using obj_webor.GenLink.exist().. but is was giving error if it was control not existing and exception occurs. tryfind is ok
I'm concerned about the third parameter in this overload, validateImageData. The documentation doesn't explain much about it, it only states that it causes the image data to be validated but no details, what exactly is done to validate the image data?
public static Image FromStream (
Stream stream,
bool useEmbeddedColorManagement,
bool validateImageData
)
I want to use this in a web application, so, I want to know what exactly will happen if I set validateImageData to true, I want to be sure that what the user uploads is a valid image, is it recommended to set validateImageData to true or is it enough to catch the exception if one is thrown? Also, can setting validateImageData to true affect the performance in any way? (users can upload images up to 250k in size)
Thanks
From Reflector, we see:
if (validateImageData)
{
num = SafeNativeMethods.Gdip.GdipImageForceValidation(new HandleRef(null, zero));
if (num != 0)
{
SafeNativeMethods.Gdip.GdipDisposeImage(new HandleRef(null, zero));
throw SafeNativeMethods.Gdip.StatusException(num);
}
}
So we see that GdipImageForceValidation is called (recall, System.Drawing is just a wrapper over GDI+). The documentation for this function isn't very good:
This function forces validation of the image.
Not very useful. However, the point is made - the image file is interrogated to ensure it is safe to load. This may cause the whole image to be loaded into memory.
If you are accepting inputs from users, I certainly would set this flag to true - you never know what kind of files (malformed or otherwise) users will upload. Better safe than sorry. This is why the default is true.
Note also that GDI+ is not recommended for server environments. You're better off using System.Windows.Media.Imaging.
By perusing inside reflector you'll see that by default .NET always calls a native API in the GDI+ libraries named GdipImageForceValidation (which is by passing true for the validateImageData parameter). I can't find much out about the native API in MSDN, only this, which tells us no more than the name of the function itself. However, it appears that this method causes a performance degradation based on Justin Roger's post about loading images in the fastest possible way via .NET. It is also intuitive to expect that any "validation" step would take away from performance.
However, if you specify false for the validateImageData parameter, .NET will explicitly trigger an unmanaged code security demand, meaning the framework authors decided that forcing image validation was necessary in order to make the promise of managed code being safe, and ultimately being able to trust the data that the caller says represents an image. So while specifying flase for validateImageData may increase performance, in a less-than-full-trust security context, it may generate an exception, and you had better trust the data you think is an image.
I remember reading some problems with that parameter. See this post (it's pretty old but just to be carefull).
Why not just try and see what happens with that flag set and not set?
In either case you should handle any exceptions that might get thrown.