0

I am working on a little program that starts taking pictures in the moment you click on a button. Also it can be ended earlier clicking another button.

The little bug that I am having is that I use a timer to process each time you go throw it since you hit the start button in a 1000ms interval, the problem comes when the first process finishes, the next process you start will duplicate the value of a progressbar x2 forever until you close the app.

namespace Fotos
{
    public partial class Fotos : Form
    {
        private static string Path = @"C:\Fotos\";
        //private static string Agua = @"C:\Marca de Agua\";
        private bool HayDispositivos, terminado;
        private string nombre;
        private int i = 0, j = 0, z = 0, eleccion;
        private FilterInfoCollection MisDispositivos;
        private VideoCaptureDevice miWebcam;
        private MagickImageCollection gif = new MagickImageCollection();

        public Fotos()
        {
            InitializeComponent();
        }
        private ImageCodecInfo GetEncoder(ImageFormat format)
        {
            ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();
            foreach (ImageCodecInfo codec in codecs)
            {
                if (codec.FormatID == format.Guid)
                {
                    return codec;
                }
            }
            return null;
        }
        private void Creador()
        {
            CreacionGif cg = new CreacionGif(gif, nombre);
            cg.ShowDialog();
        }
        private void MarcaAgua(PictureBox picturebox1)
        {
            RectangleF angulo = new RectangleF(1350, 975, 535, 90); //rectf for My Text
            using (Graphics g = Graphics.FromImage(picturebox1.Image))
            {
                //g.DrawRectangle(new Pen(Color.Red, 2), 655, 460, 535, 90); 
                g.SmoothingMode = SmoothingMode.AntiAlias;
                g.InterpolationMode = InterpolationMode.HighQualityBicubic;
                g.PixelOffsetMode = PixelOffsetMode.HighQuality;
                StringFormat sf = new StringFormat();
                sf.Alignment = StringAlignment.Center;
                sf.LineAlignment = StringAlignment.Center;
                g.DrawString(DateTime.Now.ToString(), new Font("Tahoma", 32, FontStyle.Bold), Brushes.White, angulo, sf);

                EncoderParameters myEncoderParameters = new EncoderParameters(1);
                ImageCodecInfo jpgEncoder = GetEncoder(ImageFormat.Jpeg);
                Encoder myEncoder =  Encoder.Quality;
                EncoderParameter myEncoderParameter = new EncoderParameter(myEncoder, 30L);
                myEncoderParameters.Param[0] = myEncoderParameter;

                if (progressBar1.Value == 0)
                {
                    j = 0;
                }
                picturebox1.Image.Save(Path + textBoxNombreFoto.Text + "_" + i + ".jpg", jpgEncoder, myEncoderParameters);
                gif.Add(Path + textBoxNombreFoto.Text + "_" + i + ".jpg");
                gif[j].AnimationDelay = 200;
                j++;

                g.Dispose();
                sf.Dispose();
                
                /*  using (Image image = pictureBox1.Image)
                    using (Image watermarkImage = Image.FromFile(Agua +"fecha.jpg"))
                    using (Graphics imageGraphics = Graphics.FromImage(image))
                    using (TextureBrush watermarkBrush = new TextureBrush(watermarkImage))
                    {
                        int x = (image.Width / 2 - watermarkImage.Width / 2);
                        int y = (image.Height / 2 - watermarkImage.Height / 2);
                        watermarkBrush.TranslateTransform(x, y);
                        imageGraphics.FillRectangle(watermarkBrush, new Rectangle(new Point(x, y), new Size(watermarkImage.Width + 1, watermarkImage.Height)));
                        image.Save(Path + i +".jpg");*/
            }
        }

        private void Form_Load(object sender, EventArgs e)
        {
            CargaDispositivos();
        }

        public void CargaDispositivos()
        {
            MisDispositivos = new FilterInfoCollection(FilterCategory.VideoInputDevice);
            if (MisDispositivos.Count > 0)
            {
                HayDispositivos = true;
                for (int i = 0; i < MisDispositivos.Count; i++)
                    comboBox1.Items.Add(MisDispositivos[i].Name.ToString());
                comboBox1.Text = MisDispositivos[0].Name.ToString();
            }
            else HayDispositivos = false;
        }

        private void CerrarWebcam()
        {
            if (miWebcam != null && miWebcam.IsRunning)
            {
                miWebcam.SignalToStop();
                miWebcam = null;
            }
        } 
        private void Capturando(object sender, NewFrameEventArgs eventArgs)
        {
            if(terminado == false)
            {
                Bitmap Imagen = (Bitmap)eventArgs.Frame.Clone();
                pictureBox1.Image = Imagen;
            }
        }
        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            CerrarWebcam();
        }
        private void foto_Click(object sender, EventArgs e)
        {
            if (miWebcam != null && miWebcam.IsRunning && (radioButton1.Checked == true || radioButton2.Checked == true) && textBoxNombreFoto.TextLength > 0)
            {
                timer1.Enabled = true;
                timer1.Start();
                timer1.Interval = 1000;
                timer1.Tick += new EventHandler(timer1_Tick);
                terminado = false;

                if(radioButton1.Checked == true)
                {
                    eleccion = 18;
                    progressBar1.Maximum = 1800;
                }
                else
                {
                    eleccion = 36;
                    progressBar1.Maximum = 3600;
                }
            }
            else
            {
                MessageBox.Show("Por favor revisa que todos los campos estén rellenos");
            }
        }

        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            CerrarWebcam();
            int i = comboBox1.SelectedIndex;
            string nombreVideo = MisDispositivos[i].MonikerString;
            miWebcam = new VideoCaptureDevice(nombreVideo);
            miWebcam.NewFrame += new NewFrameEventHandler(Capturando);
            miWebcam.Start();
        }
        private void finFoto_Click(object sender, EventArgs e)
        {
            MarcaAgua(pictureBox1);
            terminado = true;
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            if (progressBar1.Value % 30 == 0 && progressBar1.Value <= eleccion && terminado != true || progressBar1.Value == 0)
            {
                miWebcam.NewFrame += new NewFrameEventHandler(Capturando);
                MarcaAgua(pictureBox1);

                z++;
            }
            if (progressBar1.Value < eleccion && terminado != true)
            {
                progressBar1.Value++;
                i++;
            }
            textBoxTiempo.Text = progressBar1.Value.ToString();
            textBoxTiempo.Update();

            if ((terminado == true || progressBar1.Value >= eleccion) &&  i!=0)
            {
                timer1.Stop();
                timer1.Dispose();
                progressBar1.Dispose();
                progressBar1.Value = 0;

                nombre = textBoxNombreFoto.Text;
                Creador();

                i = 0;
                MessageBox.Show("Proceso Terminado con Éxito");
            }
        }
Thomas Weller
  • 55,411
  • 20
  • 125
  • 222
Gorben
  • 1
  • 2
  • 1
    Thanks for your question. Please remove as much code as possible without making the bug disappear. Create a copy of your project first. We call this a [mre]. It should e.g. be possible to remove the commented code. And potentially you can rename some methods to be English, so it's easier for us to understand what they shall do. – Thomas Weller Jul 06 '21 at 12:01
  • Don't use `g.Dispose();` when using it in a `using` block. It will call the Dispose method twice – Jeroen van Langen Jul 06 '21 at 12:23
  • Thank you for your advice @ThomasWeller I will next make that to perform better in coding and fix more issues. – Gorben Jul 06 '21 at 12:27
  • @JeroenvanLangen It have corrected it but it still does the same. Anyways thanks for the advice – Gorben Jul 06 '21 at 12:32
  • I noticed this in you code: `progressBar1.Dispose(); progressBar1.Value = 0`. You shouldn't access disposed objects. I recommend creating a small simple application where you try to use/reuse the progressbar. – Jeroen van Langen Jul 06 '21 at 12:36
  • Sorry, I am trying to improve my knowledge in c# and Windows Forms and I might have done bad programming decisions. I have putted away disposed objects. The problem I have it might be due to some redundant repetition on code or due to some error of that kind – Gorben Jul 06 '21 at 12:42

0 Answers0