Post-processing screen image before rendering it on display - c#

I'm working on a tinny software (C# and WPF) that does some filtering to the screen output. Examples on the filtering I'm talking about:
Customizable blue light filtering.
Increase/Decrease screen brightness (via changing the colors, not actual brightness)
Inverting screen colors.
And some more, but the simple idea is to tweak the pixel values of the screen after everything else is done rendering, but before showing the result.
Q1: How can I actually access (and then edit) the screen image/frame?
I've heard of getting and editing the screen DC directly (Win32) but I don't know if it's a good way, nor how to do it exactly.
Q2: what is the best way of applying these filters?
I think that tweaking every single pixel individually is a really bad way of doing it. (My code runs on the CPU and this process needs to be done every frame!)
Q3: Is there an event or hook for when windows is refreshing/updating the screen?
If yes, how can I register this process to it?
Note: I want a really performant way so that I don't lose any frame rate if possible.
Note: My preferred language for this is C#, C++ is ok.
Thanks a ton.

Related

Should I use Image or WebBrowser for displaying image?

I am standing between major decision in my WP7 application. It's majore purpose is to display images, always one at a time on fullscreen.
I need perfect support for pinch to zoom, moving image (while zoomed) and switching between images via flick gesture. Most of these things are already implemented in WebBrowser control, so I would just have to generate proper html source with path to image in Isolated storage.
Or should I use common Image control and implement these gestures on my own? I would like your advice before I make this decision.
Are you targeting Windows Phone 8 or 7?
Generally, I would implement my own.
Issues with using the web-browser:
1. Perf is going to be slower.
Memory footprint is going to be higher (though I doubt you really care about this - it's not going to be massive).
If you are going to favorite/download images, it will be harder (if at all possible) to navigate to them in the browser.
The background will always be white, unless you generate HTML each time that will control that bit.
The biggest issue is that the zooming in/out will be.. Janky... You won't be able to control how zoomed out the user can make it - meaning that they can zoom out enough to make the picture very small and it won't "snap back".
It's not a bad stop-gap, and the issues with it are not so big that one can say "no - don't do it", but they are enough that you should reconsider.

Native WPF vs. Custom DirectX for displaying large images

I need to speed up my image viewer, and wondering if I should be looking into creating my own DirectX control to do so.
My image viewer displays medical images. They can be pretty large. We're talking 55mb when it comes to mammography. The pixel data is 16bit greyscale stored in a ushort array. Without getting into the gory details, my current approach is loading the pixel data into an ImageSource, and using the WPF Image control.
I've never done anything with DirectX. Is it worth diving into it? Would it be any faster than the native WPF stuff? If so how significantly? Or, should I just forget about DirectX and look into areas where I can improve my current approach?
Before somebody says so, I know WPF utilize DirectX. I'm wondering If removing the WPF layer and writing the DirectX myself will improve performance.
I have some experience drawing multi-gigabyte satellite and chart imagery. Working with imagery around 55MB should probably work okay even without trying to optimize it too much. You haven't really given enough detail to recommend one alternative over the other, so I will give my opinion on the pros and cons.
Using 2D windows APIs will be the simplest to implement and should always be fast enough if you don't need to rotate and simply want to display an image and zoom and pan around. If you treat it as one large image the performance will not be as good when you zoom out if you are drawing with halftoning to give a nice smooth image. This is because it will effectively have to read all 55mb of image every time it draws.
To get around this performance issue you can make multiple bitmaps, effectively mip-mapping your image. As you zoom out you can pick the reduced resolution image closest to the resolution you are trying to draw . If you are not familiar with mip-mapping here is a Wikipedia link:
http://en.wikipedia.org/wiki/Mipmap
Implementing it with DirectX will be 10x as difficult. Different graphics hardware has different maximum texture sizes. Most likely you will need to break your image up in to multiple textures to draw and you will also have to keep track of render states, viewing matrices, etc.
However, if you do use DirectX, you can implement lots of real-time photo adjustments You can do real-time rotation by simply adjusting view matrices. You can do real-time contrast, brightness, gamma, and sharpness easily in a pixel shader.
There are two other API's I might suggest. If you are willing to limit yourself to Vista or later then Direct2D would be a little simpler than Direct3D. Also if you ever will need to implement it on a non-windows platform I would suggest using OpenGL instead. My current project is in Direct3D because a few years ago when we started it OpenGL was falling behind and I didn't forsee the popularity of Android devices. I now wish we had used OpenGL instead.
Try profiling to see where WPF is spending its time. Are you displaying the images at their native resolution? If not it might be worthwhile to do some preprocessing and create 1/2 resolution versions.

Non-Square Icon on Windows Form?

Is it possible to display an icon in the top left corner of a Windows Form that is a different shape than the standard 16X16 pixel icon?
It appears that Skype has an icon that is much wider than standard:
Is it possible in a Windows Forms app?
You can do this but it's probably more effort than it's worth just to have a larger icon.
Hans has posted an article that roughly points to the information needed to figure out an answer this question, but hasn't posted an answer itself and so I'll clarify.
The old (pre Vista) way to do this is to override the WndProc method on your form and handle the WM_NCPAINT message. Note that this means that you are now responsible for drawing the entire window frame (the window border, title, close / restore icons etc...), not just the icon - i.e. this is a lot of effort to do a relatively minor thing.
The newer (post Vista) way to do this is to use the DWM API - note that this API is not directly exposed through the .Net Framework and so you need to use P/Invoke for this in C#. The bit that you want to do is the section titled "Drawing in the Extended Frame Window", where you extend the area that you are responsible for drawing outside of the normal client area and into the window frame. This is less hassle than it used to be (you don't have to draw things like the close buttons), however still means that you take responsibility for a lot of things that you wouldn't normally, like hit-box testing for resizing and moving.
Basically its nowhere near as simple as providing a larger icon and for most applications its probably way more effort than its worth, however you can do this in C# and that article should get you started if you really want to give it a try.
I know your looking for a plain code way to do this, but I invite you to check out DevExpress manged (yes it's third party forgive me), just google it.. I seen this thread and I started asking questions at devexpress with support and got some impressive results that you might be interested in.
Here is the ticket I put in... http://www.devexpress.com/Support/Center/Issues/ViewIssue.aspx?issueid=Q399941
Here is the result... http://www.devexpress.com/Support/Center/GetSCAttachment.ashx?id=684270b5-faed-415e-9010-64338523f8cf
So Far I used this on Xp, Vista and Windows 7 without problems using winforms only.
I hope this helps or gives you another option if the windows API don't pan out like you want on different versions of windows.
Thanks,
David
Don't think it's an icon, if you mean precisely the ICO image format.
Considering the Skype window is definitely ownerdraw window, that image can potentially be whatever you want format.
The trick is, basically, render an image skipping the pixels of some color (background color) of the "icon", so render it in "transparency".
This article can give you a hint:
Drawing Transparent Images and Shapes using Alpha Blending
It's old, but always a good one.
Yes. Override WndProc and implement WM_NCPAINT.

Overlay the word/number in the Windows game fullscreen (like in Fraps)

I think a lot of people used application "Fraps" for recording video from game. I use it for displaying FPS (frames per second) in the games. Fraps can show digits at the corner of screen when game runs.
I want to display core temperature of processor. The temperature I will find, but I need to khow, how can I display it in the game? (I need it for testing core temperatures in the game, because stress tests of Everest/AIDA64 doesn't much load the system).
Want to use C# (but can listen to all solutions, C++, Java)
Example games: Dirt2, Call of Duty 5 (DirectX)
P.S. This post was similar...
c# text/winForm overlay video games like xfire,PIX,steam,fraps etc
What you want to do is a bit more complex than you might think. There are different sources on the web about this, some might be a bit outdated. A good search Term is "Hook direct 3d", there are also other threads on stackoverflow about this topic. A good thread is also this.
One advice: You are changing the runtime code of the game, which can be detected by anti cheat mechanism and can cause banning if the game is a multiplayer game. It is even possible that widely known applications like fraps are on some sort of whitelist against these checks, but i'm not sure about that.
An alternative to what you want could be to make your form always stay on top (form.TopMost = true;). Then you can set the transparency color the same color as your form (by default it would be form.TransparencyKey = System.Drawing.SystemColors.Control;). After that you can remove the border of your form (form.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;).
Be careful not to use the transparency color anywhere else (it'll make part of images transparent if it contains this color).
Make sure to have a way of closing the form. (and moving it if needed).

Is it reasonable to use OpenGL for desktop applications?

I've been writing a small desktop gadget-type application that displays scrolling text along the bottom of the screen (Similar to the old CNN news ticker), however the performance of GDI is just unsatisfactory (As high as 8-12% on a quad core and 20% on a single core) even after I've attempted to clean out bottlenecks.
I was considering using OpenGL instead to render everything, but I don't know if that is a reasonable option to require users to have hardware acceleration for a tiny app like this.
Does anybody have any input on this?
If you're comfortable with using OpenGL and your intended users are happy with the additional dependencies that OpenGL brings then I say go for it. :)
In terms of staying with GDI, I'd make sure you're rendering the text a few times as possible (through such techniques as rendering to bitmap and just scrolling that instead).
If neither one of those two options sounds appealing then there's always DirectX.
You could write the app in WPF and let WPF handle the acceleration for you (it's backed by DirectX).
I wouldn't want to install open gl for a program like that. You say that you "attempted" to eliminate the bottlenecks, but it does not sound like you succeeded. Like lzcd mentioned, there are other ways to scroll text than to repaint it constantly. Why not just draw to a bitmap and scroll that?

Categories

Resources