How can i keep adding images to pictureBox1 when cropping and adding items to the listBox1 if the flag saveRectangles is false?

Chocolade 536 Reputation points
2022-12-31T07:39:22.47+00:00

This is a link to the winforms project from my onedrive:

https://1drv.ms/u/s!AmVw2eqP6FhB4h01pNXIMlqdZJk_?e=wSGaRx

using Newtonsoft.Json;  
using Ookii.Dialogs.WinForms;  
using System;  
using System.Collections.Generic;  
using System.ComponentModel;  
using System.Data;  
using System.Drawing;  
using System.Drawing.Drawing2D;  
using System.Drawing.Imaging;  
using System.IO;  
using System.Linq;  
using System.Security.Cryptography;  
using System.Text;  
using System.Threading.Tasks;  
using System.Windows.Forms;  
using static System.Windows.Forms.VisualStyles.VisualStyleElement;  
using static System.Windows.Forms.VisualStyles.VisualStyleElement.ProgressBar;  
using static System.Windows.Forms.VisualStyles.VisualStyleElement.Window;  
  
namespace Image_Crop  
{  
    public partial class Form1 : Form  
    {  
        Rectangle rect;  
        int pixelsCounter = 0;  
        Color SelectedColor = Color.LightGreen;  
        List<DrawingRectangle> DrawingRects = new List<DrawingRectangle>();  
        Bitmap rectImage;  
        int saveRectanglesCounter = 1;  
        bool drawBorder = true;  
        bool clearRectangles = true;  
        bool saveRectangles = true;  
        //bool drawnNewRectangle = false; // To think how to work with this flag bool variable  
        // where to use it how and how to solce this problem !!!!!  
        string rectangleName;  
        Dictionary<string, string> FileList = new Dictionary<string, string>();  
        string selectedPath;  
        int x, y;  
        private bool crop = false;  
  
        public Form1()  
        {  
            InitializeComponent();  
  
            textBox1.Text = Properties.Settings.Default.ImageToCropFolder;  
            textBox2.Text = Properties.Settings.Default.CroppedImagesFolder;  
  
            selectedPath = textBox2.Text;  
  
            if (textBox1.Text != "")  
            {  
                Bitmap bmp = new Bitmap(Image.FromFile(textBox1.Text),  
                    pictureBox2.Width, pictureBox2.Height);  
                pictureBox2.Image = bmp;  
            }  
              
            checkBoxDrawBorder.Checked = true;  
            checkBoxClearRectangles.Checked = true;  
            checkBoxSaveRectangles.Checked = true;  
  
            if (selectedPath != "" && selectedPath != null)  
            {  
                if (System.IO.File.Exists(Path.Combine(selectedPath, "rectangles.txt")))  
                {  
                    string g = System.IO.File.ReadAllText(Path.Combine(selectedPath, "rectangles.txt"));  
                    g = g.Remove(0, 32);  
                      
                    FileList = JsonConvert.DeserializeObject<Dictionary<string, string>>(g);  
                    listBox1.DataSource = FileList.Keys.ToList();  
                    label2.Text = listBox1.Items.Count.ToString();  
                    listBox1.SelectedIndex = listBox1.Items.Count - 1;  
                }  
                else  
                {  
                    label2.Text = "0";  
                }  
            }  
            else  
            {  
                label2.Text = "0";  
            }  
  
            if ((selectedPath != "" && selectedPath != null) && textBox1.Text != "")  
            {  
                crop = true;  
            }  
            else  
            {  
                crop = false;  
            }  
        }  
  
        public class DrawingRectangle  
        {  
            public Rectangle Rect => new Rectangle(Location, Size);  
            public Size Size { get; set; }  
            public Point Location { get; set; }  
            public Control Owner { get; set; }  
            public Point StartPosition { get; set; }  
            public Color DrawingcColor { get; set; } = Color.LightGreen;  
            public float PenSize { get; set; } = 3f;  
        }  
  
        private void Form1_Load(object sender, EventArgs e)  
        {  
  
        }  
  
        private void pictureBox2_MouseDown(object sender, MouseEventArgs e)  
        {  
            if (e.Button != MouseButtons.Left || crop == false) return;  
  
            x = 0;  
            y = 0;  
  
            if (pictureBox2.Image != null && selectedPath != null)  
            {  
                if ((x >= 0 && x <= pictureBox2.Image.Size.Width) && (y >= 0 && y <= pictureBox2.Image.Size.Height))  
                {  
                    DrawingRects.Add(new DrawingRectangle()  
                    {  
                        Location = e.Location,  
                        Size = Size.Empty,  
                        StartPosition = e.Location,  
                        Owner = (Control)sender,  
                        DrawingcColor = SelectedColor  
                    });  
                }  
            }  
        }  
  
        private void pictureBox2_MouseMove(object sender, MouseEventArgs e)  
        {  
            int X = e.X;  
            int Y = e.Y;  
  
            if (e.Button != MouseButtons.Left || crop == false) return;  
  
  
            if ((X >= 0 && X <= pictureBox2.Width) && (Y >= 0 && Y <= pictureBox2.Height))  
            {  
                if (pictureBox2.Image != null && selectedPath != null && DrawingRects.Count > 0)  
                {  
                    if ((x >= 0 && x <= pictureBox2.Image.Size.Width) && (y >= 0 && y <= pictureBox2.Image.Size.Height))  
                    {  
                        x = e.X;  
                        y = e.Y;  
  
                        var dr = DrawingRects[DrawingRects.Count - 1];  
                        if (e.Y < dr.StartPosition.Y) { dr.Location = new Point(dr.Rect.Location.X, e.Y); }  
                        if (e.X < dr.StartPosition.X) { dr.Location = new Point(e.X, dr.Rect.Location.Y); }  
  
                        dr.Size = new Size(Math.Abs(dr.StartPosition.X - e.X), Math.Abs(dr.StartPosition.Y - e.Y));  
                        pictureBox2.Invalidate();  
                    }  
                }  
            }  
  
        }  
  
        int count = 0;  
        private void pictureBox2_MouseUp(object sender, MouseEventArgs e)  
        {  
            if (e.Button != MouseButtons.Left || crop == false) return;  
  
            if (DrawingRects.Count > 0 && pictureBox2.Image != null && selectedPath != "")  
            {  
                if ((x >= 0 && x <= pictureBox2.Image.Size.Width) && (y >= 0 && y <= pictureBox2.Image.Size.Height))  
                {  
                    var dr = DrawingRects.Last();  
                    if (dr.Rect.Width > 0 && dr.Rect.Height > 0)  
                    {  
                        rectImage = cropAtRect((Bitmap)pictureBox2.Image, dr.Rect);  
  
                        if (saveRectangles)  
                        {  
                            count++;  
                            rectangleName = GetNextName(Path.Combine(selectedPath, "Rectangle"), ".bmp");  
                            FileList.Add($"{dr.Location}, {dr.Size}", rectangleName);  
                            string json = JsonConvert.SerializeObject(  
        FileList,  
        Formatting.Indented  
    );  
                            using (StreamWriter sw = new StreamWriter(Path.Combine(selectedPath, "rectangles.txt"), false))  
                            {  
                                sw.WriteLine("Total number of rectangles: " + count + Environment.NewLine);  
                                sw.Write(json);  
                                sw.Close();  
                            }  
  
                            rectImage.Save(rectangleName);  
                            saveRectanglesCounter++;  
                        }  
  
                        pixelsCounter = rect.Width * rect.Height;  
                        pictureBox1.Invalidate();  
                        listBox1.DataSource = FileList.Keys.ToList();  
                        listBox1.SelectedIndex = listBox1.Items.Count - 1;  
  
                        pictureBox2.Focus();  
                        Graphics g = Graphics.FromImage(this.pictureBox1.Image);  
                        g.Clear(this.pictureBox1.BackColor);  
                    }  
                }  
                else  
                {  
                    if (clearRectangles)  
                    {  
                        DrawingRects.Clear();  
                        pictureBox2.Invalidate();  
                    }  
  
                    x = 0;  
                    y = 0;  
                }  
            }  
        }  
  
        string GetNextName(string baseName, string extension)  
        {  
            int counter = 1;  
            string nextName = baseName + counter + extension;  
            while (System.IO.File.Exists(nextName))  
            {  
                counter++;  
                nextName = baseName + counter + extension;  
            }  
            return nextName;  
        }  
  
        private void pictureBox2_Paint(object sender, PaintEventArgs e)  
        {  
            if (drawBorder)  
            {  
                ControlPaint.DrawBorder(e.Graphics, pictureBox2.ClientRectangle, Color.Red, ButtonBorderStyle.Solid);  
            }  
  
            if (pictureBox2.Image != null && selectedPath != null && DrawingRects.Count > 0)  
            {  
                DrawShapes(e.Graphics);  
            }  
        }  
  
        private void pictureBox1_Paint(object sender, PaintEventArgs e)  
        {  
            if (drawBorder)  
            {  
                ControlPaint.DrawBorder(e.Graphics, pictureBox1.ClientRectangle, Color.Red, ButtonBorderStyle.Solid);  
            }  
  
            if (rectImage != null && DrawingRects.Count > 0)  
            {  
                var dr = DrawingRects.Last();  
                e.Graphics.DrawImage(rectImage, dr.Rect);  
  
                if (clearRectangles)  
                {  
                    DrawingRects.Clear();  
                    pictureBox2.Invalidate();  
                }  
            }  
        }  
  
        private void DrawShapes(Graphics g)  
        {  
            if (DrawingRects.Count == 0) return;  
            g.SmoothingMode = SmoothingMode.AntiAlias;  
            foreach (var dr in DrawingRects)  
            {  
                if (dr.Rect.Width > 0 && dr.Rect.Height > 0)  
                {  
                    using (Pen pen = new Pen(dr.DrawingcColor, dr.PenSize))  
                    {  
                        g.DrawRectangle(pen, dr.Rect);  
                    };  
                }  
            }  
        }  
  
        public Bitmap cropAtRect(Bitmap b, Rectangle r)  
        {  
            Bitmap nb = new Bitmap(r.Width, r.Height);  
            using (Graphics g = Graphics.FromImage(nb))  
            {  
                g.DrawImage(b, -r.X, -r.Y);  
                return nb;  
            }  
        }  
  
        private void checkBoxDrawBorder_CheckedChanged(object sender, EventArgs e)  
        {  
            if (checkBoxDrawBorder.Checked)  
            {  
                drawBorder = true;  
            }  
            else  
            {  
                drawBorder = false;  
            }  
  
            pictureBox1.Invalidate();  
            pictureBox2.Invalidate();  
        }  
  
        private void checkBoxClearRectangles_CheckedChanged(object sender, EventArgs e)  
        {  
            if (checkBoxClearRectangles.Checked)  
            {  
                clearRectangles = true;  
            }  
            else  
            {  
                clearRectangles = false;  
            }  
  
            pictureBox2.Invalidate();  
        }  
  
        private void checkBoxSaveRectangles_CheckedChanged(object sender, EventArgs e)  
        {  
            if(checkBoxSaveRectangles.Checked)  
            {  
                saveRectangles = true;  
            }  
            else  
            {  
                saveRectangles = false;  
            }  
        }  
  
        private void listBox1_SelectedIndexChanged(object sender, EventArgs e)  
        {  
            var item = ((ListBox)sender).SelectedItem;  
            var val = FileList[(string)item];  
            pictureBox1.Image = System.Drawing.Image.FromFile(val);  
        }  
  
        private void button1_Click(object sender, EventArgs e)  
        {  
            VistaOpenFileDialog dialog = new VistaOpenFileDialog();  
            {  
                dialog.Filter = "Images (*.jpg, *.bmp, *.gif)|*.jpg;*.bmp;*.gif";  
            };  
  
            if (dialog.ShowDialog() == DialogResult.OK)  
            {  
                textBox1.Text = dialog.FileName;  
  
                Properties.Settings.Default.ImageToCropFolder = dialog.FileName;  
                Properties.Settings.Default.Save();  
  
                Bitmap bmp = new Bitmap(Image.FromFile(dialog.FileName),  
                    pictureBox2.Width, pictureBox2.Height);  
                pictureBox2.Image = bmp;  
  
                if(textBox1.Text != "" && textBox2.Text != "")  
                {  
                    crop = true;  
                }  
            }  
        }  
  
        private void button2_Click(object sender, EventArgs e)  
        {  
            VistaFolderBrowserDialog dialog = new VistaFolderBrowserDialog();  
  
            if (dialog.ShowDialog() == DialogResult.OK)  
            {  
                textBox2.Text = dialog.SelectedPath;  
                selectedPath = dialog.SelectedPath;  
  
                Properties.Settings.Default.CroppedImagesFolder = selectedPath;  
                Properties.Settings.Default.Save();  
  
                if (textBox1.Text != "" && textBox2.Text != "")  
                {  
                    crop = true;  
                }  
            }  
        }  
    }  
}  

The problem is in the mouse up event i can't find the logic with the saving flag saveRectangles.

this is the saving part in the mouse up

if (saveRectangles)  
                        {  
                            count++;  
                            rectangleName = GetNextName(Path.Combine(selectedPath, "Rectangle"), ".bmp");  
                            FileList.Add($"{dr.Location}, {dr.Size}", rectangleName);  
                            string json = JsonConvert.SerializeObject(  
        FileList,  
        Formatting.Indented  
    );  
                            using (StreamWriter sw = new StreamWriter(Path.Combine(selectedPath, "rectangles.txt"), false))  
                            {  
                                sw.WriteLine("Total number of rectangles: " + count + Environment.NewLine);  
                                sw.Write(json);  
                                sw.Close();  
                            }  
  
                            rectImage.Save(rectangleName);  
                            saveRectanglesCounter++;  
                        }  

if the checkBox checkBoxSaveRectangles is not checked when running the application and the folder in textBox1 is empty there are no saved images yet on the hard disk then it will throw exception at the line 201 in the MouseUp event :

Graphics g = Graphics.FromImage(this.pictureBox1.Image);  

because the image in pictureBox1 is null.

but in that case i still want it to crop images and add the images information as items to the listBox just not to save it to the hard disk.

i think that rectImage variable is also used in the pictureBox1 paint event.

anyway the goal is to be able to keep cropping even if the saving checkbox not checked and the there are no saved images in the cropped images folder.

Developer technologies Windows Forms
Developer technologies C#
{count} votes

Accepted answer
  1. TechLife 246 Reputation points
    2023-01-01T00:44:10.373+00:00
    1. First, you need to create a new DrawingRectangle object when the user clicks and drags the mouse on pictureBox2. You can do this in the pictureBox2_MouseDown event handler.
    2. In the pictureBox2_MouseMove event handler, you can update the Location and Size properties of the DrawingRectangle object as the user moves the mouse.
    3. In the pictureBox2_MouseUp event handler, you can add the DrawingRectangle object to the DrawingRects list.
    4. In the pictureBox2_Paint event handler, you can draw all the rectangles in the DrawingRects list on pictureBox2.
    5. If the saveRectangles flag is false, you can skip the step of saving the rectangles to a file and adding them to the listBox1 control.
    6. You can keep repeating these steps every time the user crops a new region on pictureBox2.

    Here is some sample code that shows how you can implement these steps:

    private void pictureBox2_MouseDown(object sender, MouseEventArgs e)  
    {  
        if (e.Button == MouseButtons.Left)  
        {  
            // Create a new DrawingRectangle object and set its StartPosition property  
            DrawingRectangle rect = new DrawingRectangle();  
            rect.StartPosition = e.Location;  
        }  
    }  
      
    private void pictureBox2_MouseMove(object sender, MouseEventArgs e)  
    {  
        if (e.Button == MouseButtons.Left)  
        {  
            // Update the Location and Size properties of the DrawingRectangle object  
            int width = e.X - rect.StartPosition.X;  
            int height = e.Y - rect.StartPosition.Y;  
            rect.Location = new Point(rect.StartPosition.X, rect.StartPosition.Y);  
            rect.Size = new Size(width, height);  
      
            // Redraw pictureBox2 to show the updated DrawingRectangle  
            pictureBox2.Invalidate();  
        }  
    }  
      
    private void pictureBox2_MouseUp(object sender, MouseEventArgs e)  
    {  
        if (e.Button == MouseButtons.Left)  
        {  
            // Add the DrawingRectangle object to the DrawingRects list  
            DrawingRects.Add(rect);  
      
            // If saveRectangles is true, save the rectangles to a file and add them to listBox1  
            if (saveRectangles)  
            {  
                // Save the rectangles to a file  
                SaveRectanglesToFile();  
      
                // Add the rectangles to listBox1  
                UpdateListBox();  
            }  
        }  
    }  
      
    private void pictureBox2_Paint(object sender, PaintEventArgs e)  
    {  
        // Draw all the rectangles in the DrawingRects list on pictureBox2  
        foreach (DrawingRectangle rect in DrawingRects)  
        {  
            e.Graphics.DrawRectangle(Pens.LightGreen, rect.Rect);  
      
    
    1 person found this answer helpful.
    0 comments No comments

0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.