I have a windows forms application written in C# which uses embedded Windows Media Player (AxInterop.WMPLib.dll and WMPLib.dll) to play some video files. Now I need to add an option to capture image from video on button click. If I set the windowless option to true, I am able to capture an image of a video, but when I set the windowless option to true I don't see a video image on some computers. Without the windowless option I only get a black screen with this code:
System.Drawing.Image ret = null;
try{
Bitmap bitmap = new Bitmap(wmPlayer.Width-26, wmPlayer.Height-66);
{
Graphics g = Graphics.FromImage(bitmap);
{
Graphics gg = wmPlayer.CreateGraphics();
{
this.BringToFront();
g.CopyFromScreen(
wmPlayer.PointToScreen(
new System.Drawing.Point()).X+13,
wmPlayer.PointToScreen(
new System.Drawing.Point()).Y,
0, 0,
new System.Drawing.Size(
wmPlayer.Width-26,
wmPlayer.Height-66)
);
}
}
using (MemoryStream ms = new MemoryStream()){
bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
ret = System.Drawing.Image.FromStream(ms);
ret.Save(#"C:\\WMP_capture.png");
pictureBox1.Image=ret;
}
}
bitmap.Dispose();
}catch (Exception){ }
How can I capture a frame (snapshot) from a video playing in embedded Windows Media Player without the windowless option in C#?
Or is there any other video player for C# windows forms that can be easily implemented and that supports capture functionality.
Hope this code work for you
if (!string.IsNullOrEmpty(axWindowsMediaPlayer1.URL)){
axWindowsMediaPlayer1.Ctlcontrols.pause();
System.Drawing.Image ret = null;
try
{
// take picture BEFORE saveFileDialog pops up!!
Bitmap bitmap = new Bitmap(axWindowsMediaPlayer1.Width, axWindowsMediaPlayer1.Height);
{
Graphics g = Graphics.FromImage(bitmap);
{
Graphics gg = axWindowsMediaPlayer1.CreateGraphics();
{
//timerTakePicFromVideo.Start();
this.BringToFront();
g.CopyFromScreen(
axWindowsMediaPlayer1.PointToScreen(
new System.Drawing.Point()).X,
axWindowsMediaPlayer1.PointToScreen(
new System.Drawing.Point()).Y,
0, 0,
new System.Drawing.Size(
axWindowsMediaPlayer1.Width,
axWindowsMediaPlayer1.Height)
);
}
}
// afterwards save bitmap file if user wants to
if (saveFileDialog1.ShowDialog() == DialogResult.OK)
{
using (MemoryStream ms = new MemoryStream())
{
bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
ret = System.Drawing.Image.FromStream(ms);
ret.Save(saveFileDialog1.FileName);
}
}
}
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
}
One more demo for you : http://www.codeproject.com/Articles/34663/DirectShow-Examples-for-Using-SampleGrabber-for-Gr
Related
I am currently working on my first WPF project to make cards for a card game and save them into a folder as a PNG. Right now I am using the method explained in this other answer I found. Here is the code I'm using:
private void saveCard()
{
Rect bounds = VisualTreeHelper.GetDescendantBounds(cardArea);
double dpi = 96d;
RenderTargetBitmap rtb = new RenderTargetBitmap((int)bounds.Width, (int)bounds.Height, dpi, dpi, System.Windows.Media.PixelFormats.Default);
DrawingVisual dv = new DrawingVisual();
using (DrawingContext dc = dv.RenderOpen())
{
VisualBrush vb = new VisualBrush(cardArea);
dc.DrawRectangle(vb, null, new Rect(new Point(), bounds.Size));
}
rtb.Render(dv);
BitmapEncoder pngEncoder = new PngBitmapEncoder();
pngEncoder.Frames.Add(BitmapFrame.Create(rtb));
try
{
System.IO.MemoryStream ms = new System.IO.MemoryStream();
pngEncoder.Save(ms);
ms.Close();
System.IO.File.WriteAllBytes(System.AppDomain.CurrentDomain.BaseDirectory + "/Heroes/" + HeroName.Content + ".png", ms.ToArray());
}
catch (Exception err)
{
MessageBox.Show(err.ToString(), "Error", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
It works fine, but I noticed that the saved pictures look "pixelated". This is especially noticeable when compared to the one in the canvas, or even a screenshot.
Here is an example.
I checked the resolution of both and they had the same dimensions. What am I doing wrong? Is there anything I can do to fix it? Should I save the picture under another file type?
Please let me know.
I'm c# begginer.I used wpf image control to show image from my camera. It's work normally in winform pictureBox but not in WPF image control. It's all blank! And I'm sure the data stream exist.
The icImagingControl1 is the control of my camera SDK.
It's can return image data in many forms. Like Intptr,Byte,Bitmap.
I want load data in image control from memory.
And the function would be triggered everytime the camera snap.
Here is my code.
private void icImagingControl1_ImageAvailable(object sender, XXX.Imaging.ICImagingControl.ImageAvailableEventArgs e)
{
XXX.Imaging.ImageBuffer CurrentBuffer = null;
CurrentBuffer = icImagingControl1.ImageBuffers[e.bufferIndex];
try
{
using (MemoryStream memory = new MemoryStream())
{
CurrentBuffer.Bitmap.Save(memory, ImageFormat.Bmp);
memory.Position = 0;
BitmapImage bitmapImage = new BitmapImage();
bitmapImage.BeginInit();
bitmapImage.StreamSource = memory;
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
bitmapImage.EndInit();
image1.Source = bitmapImage;
}
}
catch (Exception ex)
{
System.Diagnostics.Trace.WriteLine(ex.Message);
}
}
Hope anyone could help me.
I try to receive a desktop screen capture from my PC using WPF (Client and server side WPF)
here is my code
private void ViewReceivedImage(byte[] buffer)
{
try
{
using (MemoryStream memoryStream = new MemoryStream(buffer))
{
BitmapImage imageSource = new BitmapImage();
imageSource.BeginInit();
imageSource.StreamSource = memoryStream;
imageSource.EndInit();
// Assign the Source property of your image
MyImage.Source = imageSource;
}
//MemoryStream ms = new MemoryStream(buffer);
//BitmapImage bi = new BitmapImage();
//bi.SetSource = ms;
//MyImage.Source = bi;
//ms.Close();
}
catch (Exception) { }
finally
{
StartReceiving();
}
}
The commented line above are for Windows phone app, I have already tested it and it works with WP8(Client Side), I have the problem only on WPF Client Side.
WPF Server Side and WP8 Client Side works
WPF Client Side not working but connection is successful
this method sends the image
void StartSending()
{
while (!stop)
try
{
System.Drawing.Image oldimage = scr.Get_Resized_Image(wToCompare, hToCompare, scr.GetDesktopBitmapBytes());
//Thread.Sleep(1);
System.Drawing.Image newimage = scr.Get_Resized_Image(wToCompare, hToCompare, scr.GetDesktopBitmapBytes());
byte[] buffer = scr.GetDesktop_ResizedBytes(wToSend, hToSend);
//float difference = scr.difference(newimage, oldimage);
//if (difference >= 1)
//{
SenderSocket.Send(buffer);
//}
}
catch (Exception) { }
}
and this Get_Resized_Image
public Image Get_Resized_Image(int w, int h, byte[] image)
{
MemoryStream ms = new MemoryStream(image);
Image bt = Image.FromStream(ms);
try
{
Size sizing = new Size(w, h);
bt = new System.Drawing.Bitmap(bt, sizing);
}
catch (Exception) { }
return bt;
}
edited
this is the output
I cannot export MS Chart (from WPF toolkit) to PNG. I following step from different forums, but after everything, my PNG is completely black. What am I doing wrong?
private void export_graf_Click(object sender, RoutedEventArgs e)
{
if (mcChart.Series[0] == null)
{
MessageBox.Show("there is nothing to export");
}
else
{
RenderTargetBitmap renderBitmap = new RenderTargetBitmap((int)mcChart.ActualWidth, (int)mcChart.ActualHeight, 95d, 95d, PixelFormats.Pbgra32);
renderBitmap.Render(mcChart);
Microsoft.Win32.SaveFileDialog uloz_obr = new Microsoft.Win32.SaveFileDialog();
uloz_obr.FileName = "Graf";
uloz_obr.DefaultExt = "png";
Nullable<bool> result = uloz_obr.ShowDialog();
if (result == true)
{
string obr_cesta = uloz_obr.FileName; //cesta k souboru
using (FileStream outStream = new FileStream(obr_cesta, FileMode.Create))
{
PngBitmapEncoder encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(renderBitmap));
encoder.Save(outStream);
}
}
I think you are encountering a layout issue. The RenderTargetBitmap class works on the visual layer, which includes offsets and transforms inherited from its visual parents. You should isolate the visual element when rendering it to a BitmapFrame. You can also specify a background color without affecting your window's visual tree, unless you want a transparent background. The PNG format supports alpha transparency and some image viewers display transparent pixels as black.
The default dpi for WPF is 96. I'm not sure why you specified 95. This isn't a zero bound index or anything like that. The sample below uses 96dpi.
private void export_graf_Click(object sender, RoutedEventArgs e)
{
if (mcChart.Series[0] == null)
{
MessageBox.Show("there is nothing to export");
}
else
{
Rect bounds = VisualTreeHelper.GetDescendantBounds(mcChart);
RenderTargetBitmap renderBitmap = new RenderTargetBitmap((int)bounds.Width, (int)bounds.Height, 96, 96, PixelFormats.Pbgra32);
DrawingVisual isolatedVisual = new DrawingVisual();
using (DrawingContext drawing = isolatedVisual.RenderOpen())
{
drawing.DrawRectangle(Brushes.White, null, new Rect(new Point(), bounds.Size)); // Optional Background
drawing.DrawRectangle(new VisualBrush(mcChart), null, new Rect(new Point(), bounds.Size));
}
renderBitmap.Render(isolatedVisual);
Microsoft.Win32.SaveFileDialog uloz_obr = new Microsoft.Win32.SaveFileDialog();
uloz_obr.FileName = "Graf";
uloz_obr.DefaultExt = "png";
Nullable<bool> result = uloz_obr.ShowDialog();
if (result == true)
{
string obr_cesta = uloz_obr.FileName;
using (FileStream outStream = new FileStream(obr_cesta, FileMode.Create))
{
PngBitmapEncoder encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(renderBitmap));
encoder.Save(outStream);
}
}
}
}
How can I build video from stream image (only image without sound) in C#?
Here is some code of my application:
static int ii = 1;
public void drawBitmap(byte[] data)
{
MemoryStream ms = new MemoryStream(data);
try
{
Bitmap b = new Bitmap(ms);
b.Save(#"c:\test\" + (ii++) + ".jpg");
Image i = (Image)b;
pictureBox1.Image = i;
ii++;
}
catch (Exception e)
{
}
}
I used the wrapper mentioned above, like this:
private static void hejHopp()
{
//http://www.codeproject.com/Articles/7388/A-Simple-C-Wrapper-for-the-AviFile-Library
//myReadyNAS device, got files via FTP from my webcam
var jpgFileList = Directory.EnumerateFiles(sourcePath,"*.jpg");
//load the first image
Bitmap bitmap = (Bitmap)Image.FromFile(jpgFileList.First());
//create a new AVI file
AviManager aviManager = new AviManager(sourcePath + "\\tada.avi", false);
//add a new video stream and one frame to the new file
//set IsCompressed = false
VideoStream aviStream = aviManager.AddVideoStream(false, 2, bitmap);
jpgFileList.Skip(1).ToList().ForEach(file =>
{
bitmap = (Bitmap)Bitmap.FromFile(file);
aviStream.AddFrame(bitmap);
bitmap.Dispose();
});
aviManager.Close();
}
You might want to take a look at this thread:
http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/f23caf50-85a9-4074-8328-176c8bcc393e/
Same question. Some answers.
More is also available here:
http://www.codeproject.com/Articles/7388/A-Simple-C-Wrapper-for-the-AviFile-Library