sorry for my bad english. I am new here and to C# also.
I need help with screen capturing a area of the Form that contains image in PictureBox and text in TextBox. Everything is fine except that the saved image of screenshot does not contain the image from PictureBox and the text from TextBox. What am I doing wrong?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
namespace WindowsFormsApplication1
{
public partial class ID_Editor_Form : Form
{
Image File;
int TogMove; int MValX; int MValY;
public ID_Editor_Form()
{
InitializeComponent();
}
private void button2_Click(object sender, EventArgs e)
{
this.Close();
}
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
TogMove = 1; MValX = e.X; MValY = e.Y;
}
private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
TogMove = 0;
}
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (TogMove == 1)
{
this.SetDesktopLocation(MousePosition.X - MValX, MousePosition.Y - MValY);
}
}
OpenFileDialog BrowseID = new OpenFileDialog();
private void button3_Click(object sender, EventArgs e)
{
BrowseID.Filter = "JPG|*.jpg|JPEG|*.jpeg|PNG|*.png|All Files|*.*";
if (BrowseID.ShowDialog() == DialogResult.OK)
{
File = Image.FromFile(BrowseID.FileName);
pictureBox2.Image = File;
}
}
private void button1_Click(object sender, EventArgs e)
{
Bitmap bitmap = new Bitmap(this.Width, this.Height - 48);
DrawToBitmap(bitmap, new Rectangle(0, 0, bitmap.Width, bitmap.Height));
bitmap.Save("C:\\Users\\ROBO\\Desktop\\Screen.png", ImageFormat.Png);
MessageBox.Show("Saved Completed");
}
}
}
Related
I am quite new #. I have found a code for canny edge detection. It also contains some face detection. Only face detection is working but when i add canny, it is the same. Filtering is not working.
What is wrong in the code?
Also, i am getting warning for "int mode". I guess it is the source of the my problem.
Thanks for advance.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using AForge;
using AForge.Imaging;
using AForge.Imaging.Filters;
using AForge.Video;
using AForge.Video.DirectShow;
using System.Drawing.Imaging;
using System.IO;
using Emgu.CV;
using Emgu.CV.Structure;
namespace yüztanıma
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
Bitmap video;
private FilterInfoCollection filter;
private VideoCaptureDevice device;
int mode;
private void Form1_Load(object sender, EventArgs e)
{
filter = new FilterInfoCollection(FilterCategory.VideoInputDevice);
foreach (FilterInfo device in filter)
cboDevice.Items.Add(device.Name);
cboDevice.SelectedIndex = 0;
device = new VideoCaptureDevice();
}
private void btnDetect_Click(object sender, EventArgs e)
{
device = new VideoCaptureDevice(filter[cboDevice.SelectedIndex].MonikerString);
device.NewFrame += Device_NewFrame;
device.Start();
}
static readonly CascadeClassifier cascadeClassifier = new CascadeClassifier("haarcascade_frontalface_alt_tree.xml");
private void Device_NewFrame(object sender, NewFrameEventArgs eventArgs)
{
Bitmap bitmap = (Bitmap)eventArgs.Frame.Clone();
Image<Bgr, byte> grayImage = new Image<Bgr, byte>(bitmap);
Rectangle[] rectangles = cascadeClassifier.DetectMultiScale(grayImage, 1.2, 1);
foreach (Rectangle rectangle in rectangles)
{
using (Graphics graphics = Graphics.FromImage(bitmap))
{
using (Pen pen = new Pen(Color.Red, 5))
{
graphics.DrawRectangle(pen, rectangle);
}
}
}
pic.Image = bitmap;
}
private void Device_NewFrame2(object sender, NewFrameEventArgs eventArgs)
{
if (device.IsRunning == true)
device.Start();
video = (Bitmap)eventArgs.Frame.Clone();
Bitmap video2 = (Bitmap)eventArgs.Frame.Clone();
if (mode == 1)
{
Grayscale gray = new Grayscale(0.2125, 0.7154, 0.0721);
Bitmap video3 = gray.Apply(video2);
CannyEdgeDetector canny = new CannyEdgeDetector(0, 70);
canny.ApplyInPlace(video3);
pic.Image = video3;
}
pic.Image = video;
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (device.IsRunning)
device.Stop();
}
private void btnStop_Click(object sender, EventArgs e)
{
if (device.IsRunning == true)
device.Stop();
}
}
}
maybe i need a timer ?
i want that before the image is saved or after saved but to display the images one by one.
now it's just doing the loop so it's not showing the designer at all until the loop will end.
using Accord.Video.FFMPEG;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using static System.Net.Mime.MediaTypeNames;
namespace Extract_Frames
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
backgroundWorker1.RunWorkerAsync();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
using (var vFReader = new VideoFileReader())
{
vFReader.Open(#"C:\Users\Chocolade 1972\Downloads\MyVid.mp4");
for (int i = 0; i < vFReader.FrameCount; i++)
{
Bitmap bmpBaseOriginal = vFReader.ReadVideoFrame();
//bmpBaseOriginal.Save(#"d:\frames\frame" + i + ".bmp");
pictureBox1.Image = bmpBaseOriginal;
//bmpBaseOriginal.Dispose();
}
vFReader.Close();
}
}
}
}
It's working for while but after some images it's throwing exception on the line :
pictureBox1.Image = bmpBaseOriginal;
the exception say the object is in use.
System.InvalidOperationException: 'Object is currently in use
Your code should probably be something like this:
private readonly Queue<Image> images = new Queue<Image>();
private void Form1_Load(object sender, EventArgs e)
{
backgroundWorker1.RunWorkerAsync();
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
using (var vFReader = new VideoFileReader())
{
vFReader.Open(#"C:\Users\Chocolade 1972\Downloads\MyVid.mp4");
for (var i = 0; i < vFReader.FrameCount; i++)
{
images.Enqueue(vFReader.ReadVideoFrame());
}
// Not sure that this would be required as it might happen implicitly at the end of the 'using' block.
vFReader.Close();
}
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
pictureBox1.Image = images.Dequeue();
timer1.Start();
}
private void timer1_Tick(object sender, EventArgs e)
{
pictureBox1.Image.Dispose();
var image = images.Dequeue();
pictureBox1.Image = image;
if (images.Count == 0)
{
timer1.Stop();
}
}
All the Images are added to a queue and then dequeued one by one. The first one is displayed as soon as the loading has completed and the rest will be displayed at regular intervals. This code displayed each Image once and then destroys and discards it. If you want to display them all again when you reach the last then you can use a different type of collection and wrap back to the beginning when you get to the end.
EDIT:
I may have misunderstood a little what you were asking for. This code should display the Images as they're generated:
private void Form1_Load(object sender, EventArgs e)
{
backgroundWorker1.RunWorkerAsync();
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
using (var vFReader = new VideoFileReader())
{
vFReader.Open(#"C:\Users\Chocolade 1972\Downloads\MyVid.mp4");
for (var i = 0; i < vFReader.FrameCount; i++)
{
backgroundWorker1.ReportProgress(0, vFReader.ReadVideoFrame());
}
// Not sure that this would be required as it might happen implicitly at the end of the 'using' block.
vFReader.Close();
}
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
pictureBox1.Image?.Dispose();
pictureBox1.Image = (Image)e.UserState;
}
You can ditch the Timer and the Queue. My only concern is that this may lead to an OutOfMemoryException. If it does, you can call explicitly call GC.Collect intermittently, e.g. every 100 frames.
I am still new at programming, I code as a hobby :)
I wanted to make a MJPEG streaming aplication with an option to record a video and save it on computer when it detects a moving. So far i've managed to get stream to videosourceplayer in WPF, but it seems that i can't manage to get the information whether moving is detected or not. What am i doing wrong? i've tried many things ( commented ). but it seems that i can't compare float MotionDetected to limited (in my case 0.02). my label5 simply doesnt change.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using AForge.Vision.Motion;
using AForge.Video;
using AForge.Video.DirectShow;
using Accord.Video.FFMPEG;
using System.Globalization;
using AForge.Controls;
namespace AnotherAForge
{
public partial class Form1 : Form
{
MotionDetector Detector;
float f;
float MotionDetected;
int frames;
private VideoFileWriter _writer;
private MJPEGStream stream = new MJPEGStream("link to the cam i can't share");
int uporabimotiondetection = 0;
private IVideoSource _videoSource;
public Form1()
{
InitializeComponent();
}
Form form1 = new Form();
public void videoSourcePlayer1_NewFrame(object sender, ref Bitmap image)
{
if (uporabimotiondetection == 1)
{
MotionDetected = Detector.ProcessFrame(image);
//if (label5.InvokeRequired) {
// label5.Text = NivelDeDeteccion.ToString();
//}
//if (Detector.ProcessFrame(image) > 0.02)
//{
// label5.Text = "1";
//}
}
frames++;
}
private void alarm() {
label2.Text = MotionDetected.ToString();
}
private void button1_Click(object sender, EventArgs e)
{
//VideoStream.NewFrame += VideoStream_NewFrame;
//VideoStream.NewFrame += new NewFrameEventHandler(ProcessNewFrame);
stream.Start();
//stream.NewFrame += Stream_NewFrame;
//videoSourcePlayer1.NewFrame += videoSourcePlayer1_NewFrame;
videoSourcePlayer1.VideoSource = stream;
timer1.Enabled = true;
timer1.Start();
timer2.Start();
//pictureBox1.Image = image;
GC.Collect();
}
private void Form1_Load(object sender, EventArgs e)
{
Detector = new MotionDetector(new TwoFramesDifferenceDetector(),new MotionAreaHighlighting());
MotionDetected = 0;
}
private void timer1_Tick(object sender, EventArgs e)
{
// textBox1.Text = NivelDeDeteccion.ToString();
label3.Text = frames.ToString() + " frames";
label2.Text = MotionDetected.ToString();
if (MotionDetected <= 0.02 && MotionDetected >= 0)
{
label5.Text = "1";
}
else {
label5.Text = "0";
}
}
private void button2_Click(object sender, EventArgs e)
{
Console.Beep();
}
int time;
private void timer2_Tick(object sender, EventArgs e)
{
time++;
label4.Text = time.ToString();
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
stream.Stop();
}
private void button3_Click(object sender, EventArgs e)
{
stream.Stop();
}
private void checkBox2_CheckedChanged(object sender, EventArgs e)
{
if (checkBox2.Checked == true)
{
uporabimotiondetection = 1;
}
else {
uporabimotiondetection = 0;
}
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
//textBox1.Text = string.Format("{0:0.00000}", textBox1.Text);
//float motionlevel = float.Parse(MotionDetected);
//float a = 1;
//textBox2.Text = a.ToString();
//float b = MotionDetected / 100;
//textBox1.Text = b.ToString();
//double limiter = Convert.ToDouble("0,02");
//textBox2.Text = limiter.ToString();
//if (MotionDetected < (0.02f / 1000))
//{
// label5.Text = "gibanje";
//}
//else
//{
// label5.Text = "ni gibanja!";
//}
}
}
}
I am working on a MS paint like program that is programmed entirely in c#. It's very basic, but I have stumbled upon a problem. So I saw another SO post regarding MS paint mock ups. It was about how to save the end result as a .bmp file. I tried using the solutions and answers provided and it worked.
The file saved. However when it saved, it only saved the blank panel ( im making a forms app) . I have only seen one SO post that deals with this issue but I couldn't incorporate to allow the user to interact. The following is my code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Paint
{
public partial class Form1 : Form
{
Graphics g;
Pen p = new Pen(Color.Black, 1);
Point sp = new Point(0, 0);
Point ep = new Point(0, 0);
int k = 0;
public Form1()
{
InitializeComponent();
}
private void pictureBox2_Click(object sender, EventArgs e)
{
p.Color = red.BackColor;
default1.BackColor = red.BackColor;
}
private void blue_Click(object sender, EventArgs e)
{
p.Color = blue.BackColor;
default1.BackColor = blue.BackColor;
}
private void green_Click(object sender, EventArgs e)
{
p.Color = green.BackColor;
default1.BackColor = green.BackColor;
}
private void panel2_MouseDown(object sender, MouseEventArgs e)
{
sp = e.Location;
if (e.Button == MouseButtons.Left)
k = 1;
}
private void panel2_MouseUp(object sender, MouseEventArgs e)
{
k = 0;
}
private void panel2_MouseMove(object sender, MouseEventArgs e)
{
if (k == 1)
{
ep = e.Location;
g = panel2.CreateGraphics();
g.DrawLine(p, sp, ep);
}
sp = ep;
}
private void panel2_MouseLeave(object sender, EventArgs e)
{
k = 0; }
private void panel2_Paint(object sender, PaintEventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
SaveFileDialog dialog = new SaveFileDialog();
if (dialog.ShowDialog() == DialogResult.OK)
{
int width = Convert.ToInt32(panel2.Width);
int height = Convert.ToInt32(panel2.Height);
Bitmap bmp = new Bitmap(width, height);
panel2.DrawToBitmap(bmp, new Rectangle(0, 0, width, height));
bmp.Save(dialog.FileName, System.Drawing.Imaging.ImageFormat.Bmp);
}
}
}
}
So my question is... How do I Succesfully save a .bmp image in my c# forms app , as in how do i not make it save blank. Thanks in advance :)
edit
So I have tried the first answer and also im trying the ideas suggested by the individual in the comments and some how, instead of just saving a blank canvas. the application literally just saves a black image. Here is the code I ended up with. Where did I go wrong?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Paint
{
public partial class Form1 : Form
{
Graphics g;
Graphics h;
Pen p = new Pen(Color.Black, 1);
Point sp = new Point(0, 0);
Point ep = new Point(0, 0);
int k = 0;
Bitmap bmp =null;
public Form1()
{
InitializeComponent();
}
private void pictureBox2_Click(object sender, EventArgs e)
{
p.Color = red.BackColor;
default1.BackColor = red.BackColor;
}
private void blue_Click(object sender, EventArgs e)
{
p.Color = blue.BackColor;
default1.BackColor = blue.BackColor;
}
private void green_Click(object sender, EventArgs e)
{
p.Color = green.BackColor;
default1.BackColor = green.BackColor;
}
private void panel2_MouseDown(object sender, MouseEventArgs e)
{
sp = e.Location;
if (e.Button == MouseButtons.Left)
k = 1;
}
private void panel2_MouseUp(object sender, MouseEventArgs e)
{
k = 0;
}
private void panel2_MouseMove(object sender, MouseEventArgs e)
{
if (k == 1)
{
ep = e.Location;
int width = Convert.ToInt32(panel2.Width);
int height = Convert.ToInt32(panel2.Height);
Bitmap bmp = new Bitmap(width, height);
g = Graphics.FromImage(bmp);
g.DrawLine(p, sp, ep);
h = panel2.CreateGraphics();
h.DrawLine(p, sp, ep);
}
sp = ep;
}
private void panel2_MouseLeave(object sender, EventArgs e)
{
k = 0; }
private void panel2_Paint(object sender, PaintEventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
SaveFileDialog dialog = new SaveFileDialog();
if (dialog.ShowDialog() == DialogResult.OK)
{
/*
Bitmap bmp = Bitmap.FromHbitmap(panel2.CreateGraphics().GetHdc());
panel2.DrawToBitmap(bmp, new Rectangle(0, 0, width, height));*/
int width = panel2.Width;
int height = Convert.ToInt32(panel2.Height);
if (bmp == null)
bmp = new Bitmap(width, height);
bmp.Save(dialog.FileName, System.Drawing.Imaging.ImageFormat.Jpeg);
}
}
}
}
Here is a revised version, pretty much what I told you in the comments..:
public partial class Form2 : Form
{
Graphics g;
Graphics h;
Pen p = new Pen(Color.Black, 1);
Point sp = new Point(0, 0);
Point ep = new Point(0, 0);
int k = 0;
Bitmap bmp =null;
public Form2()
{
InitializeComponent();
bmp = new Bitmap(panel2.ClientSize.Width, panel2.ClientSize.Height);
g = Graphics.FromImage(bmp);
g.Clear(panel2.BackColor);
}
private void pictureBox2_Click(object sender, EventArgs e)
{
p.Color = red.BackColor;
default1.BackColor = red.BackColor;
}
private void color_Click(object sender, EventArgs e)
{
Control ctl = sender as Control;
p.Color = ctl.BackColor;
default1.BackColor = ctl.BackColor;
}
private void panel2_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
ep = e.Location;
g.DrawLine(p, sp, ep);
h = panel2.CreateGraphics();
h.DrawLine(p, sp, ep);
}
sp = ep;
}
private void panel2_MouseDown(object sender, MouseEventArgs e)
{
sp = e.Location;
}
private void button1_Click(object sender, EventArgs e)
{
SaveFileDialog dialog = new SaveFileDialog();
if (dialog.ShowDialog() == DialogResult.OK)
{
bmp.Save(dialog.FileName, System.Drawing.Imaging.ImageFormat.Jpeg);
}
}
}
A few notes:
I mapped all the clicks of the palette control into one.
I have eliminated the flag k by doing the button test in the move.
I have kept the cached Graphics g; this is usually not recommended, but as we keep drawing into one and the same bitmap is is ok.
I have remove all duplicate declaration of the bitmap bmp.
I don't know what the picturebox does, so I didn't touch the code.
Drawbacks of the soution:
Since you don''t keep track of all the moves you can't do a good undo.
Since all lines are drawn separately you can't get good results with broader and/or semi-transparent Pens because the overlapping endpoints will look bad.
For a better solution of simple doodeling see here and after you have studied it you can tackle the even better solution, which will allow you to use all sort of drawing tools here..
Use Graphics.GetHdc Method and save it like this:
Bitmap bitMap = Bitmap.FromHbitmap(g.GetHdc());
bitMap.Save(dialog.FileName, System.Drawing.Imaging.ImageFormat.Bmp);
I am trying to open a .jpg in Windows Form Application, draw a rectangle on it and save it with the rectangle.
In the following code I can load an .jpg and draw a rectangle to the pictureBox, but cannot save the .jpg with the rectangle. Someone knows the problem?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace EditScreen
{
public partial class Form1 : Form
{
Rectangle mRect;
Image mainimage;
Bitmap newBitmap;
Graphics g;
Boolean opened = false;
OpenFileDialog ofd = new OpenFileDialog();
SaveFileDialog sfd = new SaveFileDialog();
public Form1()
{
InitializeComponent();
this.DoubleBuffered = true;
}
private void button1_Click(object sender, EventArgs e)
{
DialogResult dr = ofd.ShowDialog();
if (dr == DialogResult.OK)
{
mainimage = Image.FromFile(ofd.FileName);
newBitmap = new Bitmap(ofd.FileName);
pictureBox1.Image = mainimage;
opened = true;
}
}
private void button2_Click(object sender, EventArgs e)
{
DialogResult dr = sfd.ShowDialog();
if (opened)
{
mainimage.Save(sfd.FileName);
}
}
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
mRect = new Rectangle(e.X, e.Y, 0, 0);
pictureBox1.Invalidate();
}
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
mRect = new Rectangle(mRect.Left, mRect.Top, e.X - mRect.Left, e.Y - mRect.Top);
pictureBox1.Invalidate();
}
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
using (Pen pen = new Pen(Color.Red, 2))
{
Graphics g = e.Graphics;
g.DrawRectangle(pen, mRect);
}
}
}
}
I heard that I have to paint on the bitmap but when I do this I dont know how to use the PaintEventArgs. Can you give me a example for my code to save it with the drawings?