Is there any method / API allow calling something like CopyFromScreenAtDepth
I try to capture a preview of GUI below active window
then blur it to achieve something like Aero glass / OS X frosted glass blur effect
I have tried many workaround
Set the Form opacity to 0 then capture and setting back to 1, this cause my form blinking.
Make the Form background Blue with same transparent key, this will work at first time but GUI won't updating, so if I call this.Update() it will update the GUI, but cause blinking too.
My code:
private void MyForm_Load(object sender, EventArgs e) {
Timer timer1 = new Timer();
timer1.Tick += new EventHandler(UpdateBackground);
timer1.Interval = 100; // in miliseconds
timer1.Start();
}
private void UpdateBackground(object sender, EventArgs e)
{
this.BackgroundImage = null;
Bitmap myImage = new Bitmap(this.Width, this.Height);
using (Graphics g = Graphics.FromImage(myImage))
{
this.Update();
g.CopyFromScreen(new Point(this.Location.X, this.Location.Y), Point.Empty, new Size(this.Width, this.Height));
}
ImageTools.FastBlur(myImage, 4);
this.BackgroundImage = myImage;
}
There is no such CopyFromScreenAtDepth() method call for Windows.
The best you can do is to use the Windows Magnification API for C++.
There are a TONs of drawback using it, like not having control over the Window position and size, limited capabilities, to none at all, at having both copy of screen below form and being able to have other controls, and the WOW64 problem when using a 32bits application with the API under 64bits OS...
I know it's an old question, but since it's a valid question with no answer so far, I thought it would be fair to answer it.
There are also other questions like this one around (which doesn't have answer either, and may be called duplicates...)
Related
I have an existing C# winforms app with live videostreams from 4 ip cameras via VLC.net (rtsp) and we take every 100ms a snapshot to analize. This is working fine. Now we like to do this instead of VLC.net with FFmpeg to have more possibilities with the (faster) captured frame. I have already a working ffmpeg wrapper sending every frame as bitmap via an event. Then I have a class "FmpegVideoWindow" inherits from PictureBox, here we listen for incoming frames and draw them on the picturebox. So instead of using the vlc-control in the form we use now a picturebox :
private void ffMpegWrapper_NewFrame1(object sender, NewFrameEventArgs e)
{
if (e != null)
{
try
{
using (Bitmap bm = new Bitmap(e.Frame))
{
frame = (Bitmap)bm.Clone();
}
}
catch
{
}
}
Invalidate();
}
protected override void OnPaint(PaintEventArgs pe)
{
base.OnPaint(pe);
if (frame != null)
{
pe.Graphics.DrawImage(frame, 0, 0, this.Width, this.Height);
//todo : disposing frame
}
}
This is working ok to see the cameras live, they have #25fps and a D1 resolution 704*576.
The problem is that every time we have other processing like opening a (settings)form, or analyzing the snapshot, the picture in the picturebox is freezing for a short time. The same program with VLC.net was never a problem.
The Ffmpeg process is done in another thread. Why does the VLC.net control running smooth in the GUI thread, and this new approach not? And what can we do to fix it? The analyzing is also done in another thread, writing the results from the analyzer to the database is done in the GUI thread. And I don't like to change that because with VLC.net it was also not needed to do that.
Thank you in advance.
I'm trying to make an animation for my C# program. There's a space rocket that ascends 8 pixels vertically with a timer interval of 25ms. I've managed to make the animation but since the picturebox's background (I've used for the rocket) is set to transparent it flickers the form's background image everytime it moves. What can I do to prevent it?
The code I've used for timer tick :
pictureBox1.Top -= 8;
P.S: I've tried to change the picturebox with panel, slow downed the rocket and timer but nothing seemed to change.
Well i haven't tried it myself now.
There needs to be a render event which you can hook to and make manipulations to your UI which would render smoothly.
Control.Paint
Try something like these :
private void Form1_Load(object sender, System.EventArgs e)
{
pictureBox1.Paint += new System.Windows.Forms.PaintEventHandler(this.pictureBox1_Paint);
}
private void pictureBox1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
pictureBox1.Top -= 8;
}
Again this isn't tested and i haven't developed any thing in winforms for ages.
But that's the direction you should go for to render things smoothly.
That double buffered thing mentioned above is also a factor in some cases.
but this is mainly the way to do it.
I am very new to c# and windows form.
What I am trying is to add a PictureBox to a windows form and display an animated .gif image before I display the data in the form.
Here is the code for the PictureBox :
private System.Windows.Forms.PictureBox pictureBox1;
//
// pictureBox1
//
this.pictureBox1.BackColor = System.Drawing.SystemColors.AppWorkspace;
this.pictureBox1.Image = ((System.Drawing.Image)(resources.GetObject("pictureBox1.Image")));
this.pictureBox1.Location = new System.Drawing.Point(374, 442);
this.pictureBox1.Name = "pictureBox1";
this.pictureBox1.Size = new System.Drawing.Size(16, 16);
this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize;
this.pictureBox1.TabIndex = 19;
this.pictureBox1.TabStop = false;
this.pictureBox1.Visible = false;
Now, on a button click the gif image should be loaded in the picture box . The code for that goes like this :
private void scanButton_Click(object sender, EventArgs e)
{
pictureBox1.Visible = true;
pictureBox1.Refresh();
}
Now, when I click the button "Scan Button", the image becomes visible,but the animation is not working.
Please can anyone help me what is happening here ?
Thanks!
For your .gif animation to work, your main (UI) thread should be free. If you are performing any process on main thread then you will not get animation effect.
From your question, it seems like you are performing Scanning operation on click of button. That may be the problem.
To get rid of this problem, you will have to make sure that your main thread is free and any operation (like Scanning) should be on separate thread.
Just assign the path to the image in ImageLocation.
pictureBox1.ImageLocation = "C:\\throbber.gif";
The PictureBox will understand that it's an animated image and play it. Disabling the PictureBox or the Form will stop the animation from playing.
If you really need to use picture box you can iterate over a collection of images. But i strongly recommend using WebBrowser (mind it is basically IE)
This should help you with all animations using windows forms
Simple animation using C#/Windows Forms
I have tried to create a custom border less form for my application. I decided that it had to be resizable, so I put 8 panels on its sides (4 corners, 4 sides actually) and created code which will resize my form when called. Like, for example:
private void E_MouseDown(object sender, MouseEventArgs e)
{
Active = true;
}
private void East_MouseMove(object sender, MouseEventArgs e)
{
if (Active)
{
this.Size = new Size(this.Width + e.Location.X, this.Height);
this.Refresh();
}
}
private void E_MouseUp(object sender, MouseEventArgs e)
{
Active = false;
}
Unfortunately, the resizing is slow, overloads the CPU and performs visual glitches even with double buffering for the form turned on. I have quite a bit of controls on my form. But what I have noticed is the fact that when I switch to a standard border (like Sizable), and DWM handles the window chrome, resizing is perfect. No glitches, stuttering and flicker. So I came to wonder, how does Windows manage to do? Is there a way to simulate what it is doing via the 8 panels? I hate when it flickers and it halts my project for no reason. The fact is that I worked all day long to mimic the Visual Studio 2013 window chrome and nearly suceeded, there is just this annoying problem... Can you help, please?
Thanks.
I have a borderless form which has the following code:
public partial class Splash : Form
{
bool painted = false;
public Splash()
{
InitializeComponent();
Opacity = 0;
}
protected override void OnPaint(PaintEventArgs e)
{
//
}
protected override void OnPaintBackground(PaintEventArgs e)
{
if (painted)
return;
Graphics gfx = e.Graphics;
gfx.CopyFromScreen(new Point(Bounds.Left, Bounds.Top),
Point.Empty, Bounds.Size);
gfx.DrawImage(Properties.Resources.Splash, e.ClipRectangle);
Opacity = 100;
painted = true;
}
}
This works quite well on my Windows 7 machine, but in Windows XP it shows garbage (presumably whatever misaligned stuff is in the framebuffer) instead of the splash image. I can sometimes make out highly distorted remnants of old explorer windows, etc inside the garbage.
Strange thing is, I run identical code in a different program which has the same sort of 24-bit PNG and that works fine on the XP machine.
Any idea why this might be happening?
Solution:
Add Bitmap b; after the bool painted = false; line, and change the OnPaintBackground to:
protected override void OnPaintBackground(PaintEventArgs e)
{
if (!painted)
{
b = new Bitmap(Width, Height);
Graphics g = Graphics.FromImage(b);
g.CopyFromScreen(new Point(Bounds.Left, Bounds.Top),
Point.Empty, Bounds.Size);
g.DrawImage(Properties.Resources.Splash, e.ClipRectangle);
Opacity = 100;
painted = true;
g.Dispose();
}
Graphics gfx = e.Graphics;
gfx.DrawImage(b, new Point(0, 0));
gfx.Dispose();
}
I think this is because you not refreshing the form after you painted him once. Win XP stores not any graphic content of windows, he just notifies them to paint themselves. Your OnPaint and OnPaintBackground functions should always refresh the window.
I do not understand why you don't use the BackgroundImage property, along with Opacity. You can set the image to be stretched, zoomed, etc. Did you want to show an effect?
Have you considered using a form with .BorderStyle set to None with a .TransparencyKey set? It should mimic the effect you are trying to get without the hassle of the CopyFromScreen call.
edited based on comments
I found some example source code that does the per pixel alpha blending you want, but it is far more complex and involves pInvoke. For reference you can find it here. http://www.codeproject.com/KB/GDI-plus/perpxalpha_sharp.aspx
I think that Win7 stores graphic content of windows and redraws them automatically. You can see the difference when a window is not responding- in WinXP he will not be refreshed, and in Win7 he will look OK. And also the window preview when you hover over the taskbar, and the "form growing" effect when a form appears.
I writing this in a seperated answer because i don't know how to add a comment in this site...