Загрузка данных


using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        // Для Lab5_4 (вывод графики на экран поверх окон через WinAPI)
        [DllImport("user32.dll")]
        public static extern IntPtr GetDC(IntPtr hwnd);

        [DllImport("user32.dll")]
        public static extern void ReleaseDC(IntPtr hwnd, IntPtr dc);

        // Инструменты рисования (дом заменен на FruitBasket - корзину с фруктами и овощами, + Selection для обрезки 5.2.6)
        enum Tool { Pencil, Line, Rectangle, Ellipse, FruitBasket, Selection }
        Tool currentTool = Tool.Pencil;

        // Графические объекты и переменные холста
        Bitmap Img1, Img2;
        Graphics gr;
        Point p1, p2;
        Pen pen1;
        Brush brush1;
        Color currentColor = Color.Black;
        bool isPressed = false;
        bool fillMode = false;

        // Для выделения области и обрезки (п. 5.2.6)
        Rectangle selRect = new Rectangle(0, 0, 0, 0);
        Pen selPen;

        // Настраиваемые параметры варианта (вместо этажей и окон -> ярусы и количество плодов в ряду)
        int fruitRows = 3;      // Ярусов фруктов/овощей
        int fruitsPerRow = 3;   // Плодов в одном ряду
        float scaleFactor = 1.0f;
        string currentFileName = "";

        // Элементы интерфейса (создаются программно)
        MenuStrip menuStrip1;
        ToolStrip toolStrip1;
        Panel canvasPanel;
        Panel rightPanel;
        PictureBox pictureBox1;
        StatusStrip statusStrip1;
        ToolStripStatusLabel statusScaleLabel;

        ToolStripButton btnPencil, btnLine, btnRect, btnEllipse, btnFill, btnFruits, btnColor, btnSave, btnClear;
        TrackBar trackScale;
        NumericUpDown numRows, numFruitsPerRow;
        OpenFileDialog openFileDialog1;
        SaveFileDialog saveFileDialog1;
        ColorDialog colorDialog1;

        public Form1()
        {
            InitializeComponent();

            pen1 = new Pen(currentColor, 2f);
            brush1 = new SolidBrush(currentColor);

            selPen = new Pen(Brushes.Blue, 1.2f);
            selPen.DashStyle = DashStyle.Dash;

            BuildInterface();
            InitCanvas(800, 550);
        }

        // ====================================================================
        // 1. ПРОГРАММНАЯ СБОРКА ИНТЕРФЕЙСА (Меню "Файл" + "Правка", Панели)
        // ====================================================================
        private void BuildInterface()
        {
            openFileDialog1 = new OpenFileDialog
            {
                Filter = "Все файлы|*.*|Рисунки BMP|*.bmp|Рисунки JPEG|*.jpg|Рисунки PNG|*.png",
                FileName = ""
            };

            saveFileDialog1 = new SaveFileDialog
            {
                Filter = "Рисунки PNG|*.png|Рисунки JPEG|*.jpg|Рисунки BMP|*.bmp",
                DefaultExt = "png"
            };

            colorDialog1 = new ColorDialog { Color = currentColor };

            // --- ВЕРХНЕЕ МЕНЮ: "Файл" и "Правка" ---
            menuStrip1 = new MenuStrip();

            // 1. Меню "Файл"
            ToolStripMenuItem fileMenu = new ToolStripMenuItem("Файл");
            fileMenu.DropDownItems.Add("Создать (Чистый холст)", null, (s, e) => ClearCanvas());
            fileMenu.DropDownItems.Add("Открыть...", null, MenuOpen_Click);
            fileMenu.DropDownItems.Add("Сохранить", null, MenuSave_Click);
            fileMenu.DropDownItems.Add("Сохранить как...", null, MenuSaveAs_Click);
            fileMenu.DropDownItems.Add("Сохранить как на компоненте (5.2.5)", null, MenuSaveAsComponent_Click);
            fileMenu.DropDownItems.Add(new ToolStripSeparator());
            fileMenu.DropDownItems.Add("Выход", null, (s, e) => Close());

            // 2. Меню "Правка" (справа от "Файл" со всеми функциями Lab5_1 - Lab5_4)
            ToolStripMenuItem editMenu = new ToolStripMenuItem("Правка");
            editMenu.DropDownItems.Add("Перерисовать холст (Lab5_1)", null, (s, e) => pictureBox1.Refresh());
            editMenu.DropDownItems.Add(new ToolStripSeparator());
            editMenu.DropDownItems.Add("Поворот на 180° и отражение по Y (5.2.1)", null, EditRotate180_Click);
            editMenu.DropDownItems.Add("Поворот на 90° по часовой (5.2.1)", null, EditRotate90_Click);
            editMenu.DropDownItems.Add("Масштабировать: уменьшить в 2 раза с рамкой (5.2.2)", null, EditScaleHalf_Click);
            editMenu.DropDownItems.Add(new ToolStripSeparator());
            editMenu.DropDownItems.Add("Сделать выбранный цвет прозрачным (5.2.3)", null, EditMakeTransparent_Click);
            editMenu.DropDownItems.Add("Фильтр: уменьшить синий цвет попиксельно (5.2.4)", null, EditFilterBlue_Click);
            editMenu.DropDownItems.Add("Фильтр: оттенки серого ColorMatrix (5.2.4)", null, EditGrayscale_Click);
            editMenu.DropDownItems.Add(new ToolStripSeparator());
            editMenu.DropDownItems.Add("Инструмент: Выделить рамкой (5.2.6)", null, (s, e) => SelectTool(Tool.Selection));
            editMenu.DropDownItems.Add("Обрезать по выделенной области (5.2.6)", null, EditCropSelection_Click);
            editMenu.DropDownItems.Add(new ToolStripSeparator());
            editMenu.DropDownItems.Add("Отрисовать на экране поверх окон (Lab5_4)", null, EditDrawOnDesktop_Click);

            menuStrip1.Items.Add(fileMenu);
            menuStrip1.Items.Add(editMenu);

            // --- ПАНЕЛЬ ИНСТРУМЕНТОВ (ToolStrip) ---
            toolStrip1 = new ToolStrip();

            btnPencil = CreateToolBtn("Карандаш", DrawIcon("pencil"), (s, e) => SelectTool(Tool.Pencil), true);
            btnLine = CreateToolBtn("Линия", DrawIcon("line"), (s, e) => SelectTool(Tool.Line));
            btnRect = CreateToolBtn("Прямоугольник", DrawIcon("rect"), (s, e) => SelectTool(Tool.Rectangle));
            btnEllipse = CreateToolBtn("Эллипс", DrawIcon("ellipse"), (s, e) => SelectTool(Tool.Ellipse));

            btnFill = new ToolStripButton
            {
                ToolTipText = "Режим заливки фигур",
                Image = DrawIcon("fill"),
                CheckOnClick = true
            };
            btnFill.CheckedChanged += (s, e) => fillMode = btnFill.Checked;

            // Кнопка рисования овощей и фруктов (вместо Дома)
            btnFruits = CreateToolBtn("Корзина с овощами и фруктами", DrawIcon("fruits"), (s, e) => SelectTool(Tool.FruitBasket));

            btnColor = new ToolStripButton { ToolTipText = "Выбрать цвет", Image = DrawIcon("color") };
            btnColor.Click += BtnColor_Click;

            btnSave = new ToolStripButton { ToolTipText = "Сохранить рисунок", Image = DrawIcon("save") };
            btnSave.Click += MenuSaveAs_Click;

            btnClear = new ToolStripButton { ToolTipText = "Очистить холст", Image = DrawIcon("clear") };
            btnClear.Click += (s, e) => ClearCanvas();

            toolStrip1.Items.AddRange(new ToolStripItem[] {
                btnPencil, btnLine, btnRect, btnEllipse, btnFill, btnFruits,
                new ToolStripSeparator(),
                btnColor, btnSave, btnClear
            });

            // --- ПРАВАЯ ПАНЕЛЬ НАСТРОЕК (Масштаб + Ярусы фруктов + Плодов в ряду) ---
            rightPanel = new Panel
            {
                Dock = DockStyle.Right,
                Width = 190,
                BackColor = Color.FromArgb(240, 240, 240),
                BorderStyle = BorderStyle.FixedSingle
            };

            Label lblScale = new Label { Text = "Масштаб:", Location = new Point(15, 20), AutoSize = true };
            trackScale = new TrackBar
            {
                Location = new Point(10, 40),
                Width = 165,
                Minimum = 50,
                Maximum = 200,
                Value = 100,
                TickFrequency = 25
            };
            trackScale.Scroll += TrackScale_Scroll;

            Label lblRows = new Label { Text = "Ярусов фруктов:", Location = new Point(15, 100), AutoSize = true };
            numRows = new NumericUpDown
            {
                Location = new Point(15, 122),
                Width = 120,
                Minimum = 1,
                Maximum = 5,
                Value = 3
            };
            numRows.ValueChanged += (s, e) => fruitRows = (int)numRows.Value;

            Label lblPerRow = new Label { Text = "Плодов в ряду:", Location = new Point(15, 160), AutoSize = true };
            numFruitsPerRow = new NumericUpDown
            {
                Location = new Point(15, 182),
                Width = 120,
                Minimum = 1,
                Maximum = 8,
                Value = 3
            };
            numFruitsPerRow.ValueChanged += (s, e) => fruitsPerRow = (int)numFruitsPerRow.Value;

            rightPanel.Controls.AddRange(new Control[] { lblScale, trackScale, lblRows, numRows, lblPerRow, numFruitsPerRow });

            // --- НИЖНЯЯ СТРОКА СОСТОЯНИЯ ---
            statusStrip1 = new StatusStrip();
            statusScaleLabel = new ToolStripStatusLabel("Масштаб: 100% | Инструмент: Карандаш");
            statusStrip1.Items.Add(statusScaleLabel);

            // --- ЦЕНТРАЛЬНАЯ ПАНЕЛЬ С ПРОКРУТКОЙ И PICTUREBOX ---
            canvasPanel = new Panel
            {
                Dock = DockStyle.Fill,
                AutoScroll = true,
                BackColor = Color.LightGray
            };

            pictureBox1 = new PictureBox
            {
                Location = new Point(0, 0),
                SizeMode = PictureBoxSizeMode.AutoSize,
                BackColor = Color.White
            };
            pictureBox1.MouseDown += PictureBox1_MouseDown;
            pictureBox1.MouseMove += PictureBox1_MouseMove;
            pictureBox1.MouseUp += PictureBox1_MouseUp;
            pictureBox1.Paint += PictureBox1_Paint;

            canvasPanel.Controls.Add(pictureBox1);

            // Добавляем все элементы на форму в правильном порядке Dock
            this.Controls.Add(canvasPanel);
            this.Controls.Add(rightPanel);
            this.Controls.Add(toolStrip1);
            this.Controls.Add(menuStrip1);
            this.Controls.Add(statusStrip1);
            this.MainMenuStrip = menuStrip1;
        }

        private ToolStripButton CreateToolBtn(string tooltip, Image icon, EventHandler onClick, bool isChecked = false)
        {
            var btn = new ToolStripButton
            {
                ToolTipText = tooltip,
                Image = icon,
                Checked = isChecked
            };
            btn.Click += onClick;
            return btn;
        }

        private void SelectTool(Tool tool)
        {
            currentTool = tool;
            btnPencil.Checked = (tool == Tool.Pencil);
            btnLine.Checked = (tool == Tool.Line);
            btnRect.Checked = (tool == Tool.Rectangle);
            btnEllipse.Checked = (tool == Tool.Ellipse);
            btnFruits.Checked = (tool == Tool.FruitBasket);

            string toolName = tool == Tool.FruitBasket ? "Овощи и фрукты" :
                              tool == Tool.Selection ? "Выделение рамкой" : tool.ToString();
            statusScaleLabel.Text = $"Масштаб: {(int)(scaleFactor * 100)}% | Инструмент: {toolName}";
        }

        // Генерация аккуратных иконок для кнопок на панели инструментов
        private Bitmap DrawIcon(string type)
        {
            Bitmap bmp = new Bitmap(20, 20);
            using (Graphics g = Graphics.FromImage(bmp))
            {
                g.SmoothingMode = SmoothingMode.AntiAlias;
                Pen p = new Pen(Color.Black, 1.8f);
                switch (type)
                {
                    case "pencil":
                        g.DrawLine(new Pen(Color.DarkOrange, 3f), 3, 16, 15, 4);
                        g.FillPolygon(Brushes.Black, new Point[] { new Point(2, 18), new Point(6, 16), new Point(4, 14) });
                        break;
                    case "line":
                        g.DrawLine(p, 3, 16, 16, 3);
                        break;
                    case "rect":
                        g.DrawRectangle(p, 3, 4, 13, 11);
                        break;
                    case "ellipse":
                        g.DrawEllipse(p, 2, 4, 15, 11);
                        break;
                    case "fill":
                        g.FillRectangle(Brushes.RoyalBlue, 4, 4, 12, 12);
                        g.DrawRectangle(p, 4, 4, 12, 12);
                        break;
                    case "fruits":
                        // Иконка спелого яблока с зеленым листком (вместо домика)
                        g.FillEllipse(Brushes.Crimson, 3, 5, 13, 12);
                        g.DrawEllipse(new Pen(Color.DarkRed, 1.2f), 3, 5, 13, 12);
                        g.DrawLine(new Pen(Color.SaddleBrown, 2f), 9, 5, 10, 1);
                        g.FillEllipse(Brushes.ForestGreen, 10, 2, 6, 4);
                        break;
                    case "color":
                        g.FillRectangle(Brushes.MediumSeaGreen, 2, 2, 5, 15);
                        g.FillRectangle(Brushes.Gold, 7, 2, 5, 15);
                        g.FillRectangle(Brushes.Tomato, 12, 2, 5, 15);
                        break;
                    case "save":
                        g.DrawRectangle(p, 3, 3, 13, 13);
                        g.FillRectangle(Brushes.DimGray, 6, 3, 7, 5);
                        g.DrawRectangle(p, 6, 10, 7, 6);
                        break;
                    case "clear":
                        Pen redPen = new Pen(Color.Crimson, 2f);
                        g.DrawRectangle(redPen, 3, 3, 13, 13);
                        g.DrawLine(redPen, 3, 3, 16, 16);
                        g.DrawLine(redPen, 16, 3, 3, 16);
                        break;
                }
            }
            return bmp;
        }

        // ====================================================================
        // 2. ХОЛСТ И РИСОВАНИЕ ФИГУР + КОРЗИНА С ОВОЩАМИ И ФРУКТАМИ
        // ====================================================================
        private void InitCanvas(int width, int height)
        {
            Img1 = new Bitmap(width, height);
            using (Graphics g = Graphics.FromImage(Img1))
            {
                g.Clear(Color.White);
            }
            pictureBox1.Image = Img1;
            selRect = new Rectangle(0, 0, 0, 0);
        }

        private void ClearCanvas()
        {
            InitCanvas(Math.Max(800, canvasPanel.ClientSize.Width), Math.Max(550, canvasPanel.ClientSize.Height));
        }

        private void PictureBox1_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button != MouseButtons.Left) return;
            isPressed = true;
            p1 = e.Location;

            if (currentTool == Tool.Selection)
            {
                selRect = new Rectangle(p1.X, p1.Y, 0, 0);
            }
        }

        private void PictureBox1_MouseMove(object sender, MouseEventArgs e)
        {
            if (!isPressed) return;
            p2 = e.Location;

            if (currentTool == Tool.Selection)
            {
                selRect = GetNormalizedRect(p1, p2);
                pictureBox1.Invalidate();
                return;
            }

            if (currentTool == Tool.Pencil)
            {
                using (Graphics g = Graphics.FromImage(Img1))
                {
                    g.SmoothingMode = SmoothingMode.AntiAlias;
                    g.DrawLine(pen1, p1, p2);
                }
                p1 = p2;
                pictureBox1.Image = Img1;
                pictureBox1.Invalidate();
                return;
            }

            // Для остальных фигур и корзины с фруктами рисуем на буферном изображении Img2
            Img2 = new Bitmap(Img1);
            using (Graphics g = Graphics.FromImage(Img2))
            {
                g.SmoothingMode = SmoothingMode.AntiAlias;
                DrawSelectedShape(g, p1, p2);
            }
            pictureBox1.Image = Img2;
            pictureBox1.Invalidate();
        }

        private void PictureBox1_MouseUp(object sender, MouseEventArgs e)
        {
            if (!isPressed) return;
            isPressed = false;
            p2 = e.Location;

            if (currentTool == Tool.Selection)
            {
                selRect = GetNormalizedRect(p1, p2);
                pictureBox1.Invalidate();
                return;
            }

            if (currentTool != Tool.Pencil)
            {
                using (Graphics g = Graphics.FromImage(Img1))
                {
                    g.SmoothingMode = SmoothingMode.AntiAlias;
                    DrawSelectedShape(g, p1, p2);
                }
                pictureBox1.Image = Img1;
            }
            pictureBox1.Invalidate();
        }

        private void PictureBox1_Paint(object sender, PaintEventArgs e)
        {
            // Отрисовка рамки выделения для п. 5.2.6
            if (selRect.Width > 0 && selRect.Height > 0)
            {
                e.Graphics.DrawRectangle(isPressed ? selPen : Pens.Black, selRect);
            }
        }

        private void DrawSelectedShape(Graphics g, Point pt1, Point pt2)
        {
            Rectangle rect = GetNormalizedRect(pt1, pt2);

            switch (currentTool)
            {
                case Tool.Line:
                    g.DrawLine(pen1, pt1, pt2);
                    break;

                case Tool.Rectangle:
                    if (fillMode) g.FillRectangle(brush1, rect);
                    g.DrawRectangle(pen1, rect);
                    break;

                case Tool.Ellipse:
                    if (fillMode) g.FillEllipse(brush1, rect);
                    g.DrawEllipse(pen1, rect);
                    break;

                case Tool.FruitBasket:
                    // Если просто кликнули мышкой без растягивания — задаем стандартный размер корзины
                    if (rect.Width < 30 || rect.Height < 30)
                    {
                        int defW = (int)(130 * scaleFactor);
                        int defH = (int)(110 * scaleFactor);
                        rect = new Rectangle(pt1.X - defW / 2, pt1.Y - defH / 2, defW, defH);
                    }
                    DrawFruitAndVeggieBasket(g, rect, fruitRows, fruitsPerRow);
                    break;
            }
        }

        // Отрисовка корзины с овощами и фруктами (с двумя параметрами: ярусы и число плодов в ряду)
        private void DrawFruitAndVeggieBasket(Graphics g, Rectangle bounds, int rows, int countPerRow)
        {
            int x = bounds.X;
            int y = bounds.Y;
            int w = bounds.Width;
            int h = bounds.Height;

            // Нижняя половина области — плетеная корзина, верхняя — ярусы овощей и фруктов
            int basketTop = y + (int)(h * 0.52f);
            int basketBottom = y + h;
            int basketHeight = Math.Max(15, basketBottom - basketTop);

            // 1. Сначала рисуем ярусы плодов (яблоки, груши/апельсины, морковки с ботвой)
            int fruitZoneHeight = Math.Max(20, basketTop - y);
            int rowStep = Math.Max(10, fruitZoneHeight / Math.Max(1, rows));
            int itemWidth = Math.Max(12, (w - 16) / Math.Max(1, countPerRow));
            int itemDiameter = Math.Min(itemWidth, rowStep + 10);

            for (int r = 0; r < rows; r++)
            {
                // Нижний ярус лежит прямо у края корзины, следующие — выше
                int itemY = basketTop - (r + 1) * (rowStep * 3 / 4) - itemDiameter / 4;

                for (int c = 0; c < countPerRow; c++)
                {
                    int itemX = x + 8 + c * itemWidth + (itemWidth - itemDiameter) / 2;
                    Rectangle itemRect = new Rectangle(itemX, itemY, itemDiameter, itemDiameter);

                    int type = (r + c) % 3; // Чередуем: 0 - яблоко, 1 - морковь, 2 - апельсин/помидор

                    if (type == 0) // Яблоко с веточкой и листочком
                    {
                        if (fillMode) g.FillEllipse(Brushes.Crimson, itemRect);
                        else g.FillEllipse(Brushes.White, itemRect);

                        g.DrawEllipse(pen1, itemRect);
                        // Черенок и листик
                        int midX = itemX + itemDiameter / 2;
                        g.DrawLine(pen1, midX, itemY, midX + 2, itemY - 6);
                        g.FillEllipse(Brushes.ForestGreen, midX + 1, itemY - 6, 7, 4);
                        g.DrawEllipse(Pens.DarkGreen, midX + 1, itemY - 6, 7, 4);
                    }
                    else if (type == 1) // Морковка с зеленой ботвой
                    {
                        Point[] carrotPts = new Point[]
                        {
                            new Point(itemX + 2, itemY + 2),
                            new Point(itemX + itemDiameter - 2, itemY + 2),
                            new Point(itemX + itemDiameter / 2, itemY + itemDiameter + 4)
                        };
                        if (fillMode) g.FillPolygon(Brushes.DarkOrange, carrotPts);
                        else g.FillPolygon(Brushes.White, carrotPts);

                        g.DrawPolygon(pen1, carrotPts);
                        // Зеленая ботва морковки сверху
                        int midX = itemX + itemDiameter / 2;
                        Pen greenPen = new Pen(Color.ForestGreen, 1.5f);
                        g.DrawLine(greenPen, midX, itemY + 2, midX - 5, itemY - 6);
                        g.DrawLine(greenPen, midX, itemY + 2, midX, itemY - 7);
                        g.DrawLine(greenPen, midX, itemY + 2, midX + 5, itemY - 6);
                    }
                    else // Спелый апельсин / томат с чашелистиком
                    {
                        if (fillMode) g.FillEllipse(Brushes.Gold, itemRect);
                        else g.FillEllipse(Brushes.White, itemRect);

                        g.DrawEllipse(pen1, itemRect);
                        int midX = itemX + itemDiameter / 2;
                        g.DrawLine(pen1, midX - 3, itemY + 2, midX + 3, itemY + 2);
                        g.DrawLine(pen1, midX, itemY - 2, midX, itemY + 4);
                    }
                }
            }

            // 2. Рисуем саму корзину (трапеция с ободком и плетеной сеточкой) поверх нижнего края плодов
            Point[] basketPoly = new Point[]
            {
                new Point(x, basketTop),
                new Point(x + w, basketTop),
                new Point(x + (int)(w * 0.82f), basketBottom),
                new Point(x + (int)(w * 0.18f), basketBottom)
            };

            if (fillMode)
                g.FillPolygon(Brushes.BurlyWood, basketPoly);
            else
                g.FillPolygon(Brushes.White, basketPoly);

            g.DrawPolygon(pen1, basketPoly);

            // Ободок корзины
            Rectangle rimRect = new Rectangle(x - 3, basketTop - 4, w + 6, 8);
            if (fillMode) g.FillRectangle(Brushes.Peru, rimRect);
            else g.FillRectangle(Brushes.White, rimRect);
            g.DrawRectangle(pen1, rimRect);

            // Горизонтальные полосы плетения корзины
            for (int i = 1; i <= 2; i++)
            {
                int lineY = basketTop + (basketHeight * i) / 3;
                float ratio = (float)i / 3f;
                int leftX = x + (int)(w * 0.18f * ratio);
                int rightX = x + w - (int)(w * 0.18f * ratio);
                g.DrawLine(pen1, leftX, lineY, rightX, lineY);
            }

            // Вертикальные ребра корзины
            for (int i = 1; i <= 3; i++)
            {
                int topX = x + (w * i) / 4;
                int botX = x + (int)(w * 0.18f) + ((int)(w * 0.64f) * i) / 4;
                g.DrawLine(pen1, topX, basketTop + 4, botX, basketBottom);
            }
        }

        private Rectangle GetNormalizedRect(Point pt1, Point pt2)
        {
            return new Rectangle(
                Math.Min(pt1.X, pt2.X),
                Math.Min(pt1.Y, pt2.Y),
                Math.Abs(pt2.X - pt1.X),
                Math.Abs(pt2.Y - pt1.Y));
        }

        // ====================================================================
        // 3. ОБРАБОТЧИКИ МЕНЮ "ФАЙЛ"
        // ====================================================================
        private void MenuOpen_Click(object sender, EventArgs e)
        {
            if (openFileDialog1.ShowDialog() == DialogResult.OK && !string.IsNullOrWhiteSpace(openFileDialog1.FileName))
            {
                try
                {
                    using (FileStream fs = new FileStream(openFileDialog1.FileName, FileMode.Open, FileAccess.Read, FileShare.Inheritable))
                    {
                        Image loaded = Image.FromStream(fs);
                        Img1 = new Bitmap(loaded);
                        pictureBox1.Image = Img1;
                        currentFileName = openFileDialog1.FileName;
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message + "\nНе удалось открыть файл", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                }
            }
        }

        private void MenuSave_Click(object sender, EventArgs e)
        {
            if (pictureBox1.Image == null) return;
            if (string.IsNullOrEmpty(currentFileName))
            {
                MenuSaveAs_Click(sender, e);
                return;
            }
            try
            {
                Bitmap bmp = new Bitmap(pictureBox1.Image);
                bmp.Save(currentFileName);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message + "\nНе удалось сохранить файл", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            }
        }

        private void MenuSaveAs_Click(object sender, EventArgs e)
        {
            if (pictureBox1.Image == null) return;
            if (saveFileDialog1.ShowDialog() == DialogResult.OK)
            {
                currentFileName = saveFileDialog1.FileName;
                MenuSave_Click(sender, e);
            }
        }

        // 5.2.5. Сохранить рисунок так, как он выглядит при растягивании на компоненте
        private void MenuSaveAsComponent_Click(object sender, EventArgs e)
        {
            if (pictureBox1.Image == null) return;

            pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
            pictureBox1.Dock = DockStyle.Fill;

            Bitmap bitmap1 = new Bitmap(pictureBox1.Image);
            Bitmap bitmap2 = new Bitmap(pictureBox1.Width, pictureBox1.Height);

            using (Graphics g = Graphics.FromImage(bitmap2))
            {
                g.InterpolationMode = InterpolationMode.Bicubic;
                g.DrawImage(bitmap1, new Rectangle(0, 0, bitmap2.Width, bitmap2.Height));
            }

            pictureBox1.Image = bitmap2;
            MenuSaveAs_Click(this, e);

            pictureBox1.SizeMode = PictureBoxSizeMode.AutoSize;
            pictureBox1.Dock = DockStyle.None;
            pictureBox1.Image = bitmap1;
        }

        // ====================================================================
        // 4. ОБРАБОТЧИКИ МЕНЮ "ПРАВКА" (Все функции Lab5_2 и Lab5_4)
        // ====================================================================

        // 5.2.1. Поворот на 180 градусов и отражение
        private void EditRotate180_Click(object sender, EventArgs e)
        {
            if (pictureBox1.Image == null) return;
            Img1 = new Bitmap(pictureBox1.Image);
            Img1.RotateFlip(RotateFlipType.Rotate180FlipY);
            pictureBox1.Image = Img1;
        }

        private void EditRotate90_Click(object sender, EventArgs e)
        {
            if (pictureBox1.Image == null) return;
            Img1 = new Bitmap(pictureBox1.Image);
            Img1.RotateFlip(RotateFlipType.Rotate90FlipNone);
            pictureBox1.Image = Img1;
        }

        // 5.2.2. Программное уменьшение в 2 раза с красной рамкой
        private void EditScaleHalf_Click(object sender, EventArgs e)
        {
            if (pictureBox1.Image == null) return;
            Bitmap bitmap1 = new Bitmap(pictureBox1.Image);
            if (bitmap1.Width < 4 || bitmap1.Height < 4) return;

            using (Graphics Gr1 = Graphics.FromImage(bitmap1))
            {
                Bitmap bitmap2 = new Bitmap(bitmap1.Width / 2, bitmap1.Height / 2, Gr1);
                using (Graphics Gr2 = Graphics.FromImage(bitmap2))
                {
                    Rectangle compressionRect = new Rectangle(0, 0, bitmap1.Width / 2, bitmap1.Height / 2);
                    Gr2.DrawImage(bitmap1, compressionRect);
                    Gr2.DrawRectangle(Pens.Red, 0, 0, bitmap2.Width - 1, bitmap2.Height - 1);
                }
                Img1 = bitmap2;
                pictureBox1.Image = Img1;
            }
        }

        // 5.2.3. Сделать выбранный в диалоге цвет прозрачным
        private void EditMakeTransparent_Click(object sender, EventArgs e)
        {
            if (pictureBox1.Image == null) return;
            Bitmap bitmap1 = new Bitmap(pictureBox1.Image);
            if (colorDialog1.ShowDialog() == DialogResult.OK)
            {
                bitmap1.MakeTransparent(colorDialog1.Color);
                Img1 = bitmap1;
                pictureBox1.Image = Img1;
            }
        }

        // 5.2.4 (Часть 1). Попиксельная фильтрация синего цвета
        private void EditFilterBlue_Click(object sender, EventArgs e)
        {
            if (pictureBox1.Image == null) return;
            Bitmap bitmap1 = new Bitmap(pictureBox1.Image);
            for (int x = 0; x < bitmap1.Width; x++)
            {
                for (int y = 0; y < bitmap1.Height; y++)
                {
                    Color c = bitmap1.GetPixel(x, y);
                    if (c.R > 250 && c.G > 250 && c.B > 250) continue;
                    bitmap1.SetPixel(x, y, Color.FromArgb(c.R, c.G, c.B / 2));
                }
            }
            Img1 = bitmap1;
            pictureBox1.Image = Img1;
        }

        // 5.2.4 (Часть 2). Оттенки серого через ColorMatrix
        private void EditGrayscale_Click(object sender, EventArgs e)
        {
            if (pictureBox1.Image == null) return;
            Bitmap bitmap1 = new Bitmap(pictureBox1.Image);
            Bitmap bitmap2 = new Bitmap(bitmap1.Width, bitmap1.Height);

            using (Graphics g = Graphics.FromImage(bitmap2))
            {
                float[][] Map = {
                    new float[] {0.30f, 0.30f, 0.30f, 0.00f, 0.00f },
                    new float[] {0.59f, 0.59f, 0.59f, 0.00f, 0.00f },
                    new float[] {0.11f, 0.11f, 0.11f, 0.00f, 0.00f },
                    new float[] {0.00f, 0.00f, 0.00f, 1.00f, 0.00f },
                    new float[] {0.00f, 0.00f, 0.00f, 0.00f, 1.00f }
                };
                ColorMatrix grayMatrix = new ColorMatrix(Map);
                ImageAttributes attributes = new ImageAttributes();
                attributes.SetColorMatrix(grayMatrix);

                Rectangle rect = new Rectangle(0, 0, bitmap1.Width, bitmap1.Height);
                g.DrawImage(bitmap1, rect, 0, 0, bitmap1.Width, bitmap1.Height, GraphicsUnit.Pixel, attributes);
            }
            Img1 = bitmap2;
            pictureBox1.Image = Img1;
        }

        // 5.2.6. Обрезка изображения по выделенной рамке selRect
        private void EditCropSelection_Click(object sender, EventArgs e)
        {
            if (pictureBox1.Image == null) return;
            if (selRect.Width <= 0 || selRect.Height <= 0)
            {
                MessageBox.Show("Сначала выделите область на холсте (Правка -> Инструмент: Выделить рамкой)!",
                    "Подсказка", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }

            Bitmap bitmap1 = new Bitmap(pictureBox1.Image);
            Bitmap bitmap2 = new Bitmap(selRect.Width, selRect.Height);
            using (Graphics g = Graphics.FromImage(bitmap2))
            {
                g.DrawImage(bitmap1, 0, 0, selRect, GraphicsUnit.Pixel);
            }
            Img1 = bitmap2;
            pictureBox1.Image = Img1;
            selRect = new Rectangle(0, 0, 0, 0);
            pictureBox1.Invalidate();
        }

        // Lab5_4. Отрисовка в контексте экрана Windows поверх всех окон
        private void EditDrawOnDesktop_Click(object sender, EventArgs e)
        {
            IntPtr desktopPtr = GetDC(IntPtr.Zero);
            using (Graphics g = Graphics.FromHdc(desktopPtr))
            {
                Pen[] pens = { Pens.Red, Pens.Yellow, Pens.Green };
                Brush[] brushes = { Brushes.Red, Brushes.Yellow, Brushes.Green };
                int width = (this.ClientSize.Width - 1) / 2;
                int height = (this.ClientSize.Height - 1) / 2;

                for (int i = 0; i < 3; i++)
                {
                    g.DrawRectangle(pens[i], i * width / 2, i * height / 2, width / 2, height / 2);
                    g.FillEllipse(brushes[i], i * width / 2, i * height / 2, width / 2, height / 2);
                }
                g.DrawLine(pens[2], 0, 0, width, height);
            }
            ReleaseDC(IntPtr.Zero, desktopPtr);
        }

        // ====================================================================
        // 5. ДОПОЛНИТЕЛЬНЫЕ НАСТРОЙКИ (Выбор цвета и ползунок Масштаба)
        // ====================================================================
        private void BtnColor_Click(object sender, EventArgs e)
        {
            if (colorDialog1.ShowDialog() == DialogResult.OK)
            {
                currentColor = colorDialog1.Color;
                pen1.Color = currentColor;
                brush1 = new SolidBrush(currentColor);
            }
        }

        private void TrackScale_Scroll(object sender, EventArgs e)
        {
            scaleFactor = trackScale.Value / 100f;
            statusScaleLabel.Text = $"Масштаб: {trackScale.Value}% | Инструмент: {currentTool}";
        }
    }
}