как сделать масштабирование изображения с помощью колёсика мыши в позицию где находится мышка
вот что у меня есть на данный момент но оно вообще не работает и как сделать приближение изображения как это сделано в других растровых редакторах таких как paint.net у меня идей вообще нету надеюсь кто ни будь сможет помочь. Хотелось бы узнать как сделать приближение и отдаление от изображения и что бы появлялись полосы прокрутки что бы можно было перемещаться или перемещаться с помощью зажатой левой кнопки мыши+ctrl.
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.Globalization;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace ArtEdit
{
public partial class ArtEdit : Form
{
public ArtEdit()
{
InitializeComponent();
pictureBox1.Paint += pictureBox1_Paint;
pictureBox1.MouseMove += pictureBox1_MouseMove;
pictureBox1.MouseUp += PictureBox_MouseUp;
pictureBox1.MouseDown += PictureBox_MouseDown;
pictureBox1.MouseWheel += pictureBox1_MouseWheel;
SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.UserPaint, true);
SetStyle(ControlStyles.ResizeRedraw | ControlStyles.OptimizedDoubleBuffer, true);
this.Width = 1600;
this.Height = 850;
var bitmap = new Bitmap(pictureBox1.Width, pictureBox1.Height);
pictureBox1.Image = bitmap;
g = Graphics.FromImage(bitmap);
g.Clear(Color.White);
// Пример инициализации переменной DrawPlace
DrawPlace = new int[Width, Height, 3]; // 3 - для хранения значений R, G, B
// новое
// Настраиваем AutoScroll для формы
this.AutoScroll = true;
this.WindowState = FormWindowState.Maximized;
}
#region Variables
// Int
int penWidth; // размер инструментов рисования
private int newWidth; // Новая ширина изображения
private int newHeight; // Новая высота изображения
private int Height2; // Высота изображения
private int Width2; // Ширина изображения
private int[,,] DrawPlace; // Массив для хранения пикселей изображения
private int ClickNum = 1;
private int DrawIndex = -1;
// Bool
private bool active_drawing = false;
private bool isMouseDown = false;
// Point
private Point mouseOffset;
Point orig;
// List
private List<Entities.Line> lines = new List<Entities.Line>();
private List<Entities.Point> points = new List<Entities.Point>();
private List<Entities.Circle> circles = new List<Entities.Circle>();
private List<Entities.Ellipse> ellipses = new List<Entities.Ellipse>();
// Vector
private Vector firstPoint;
private Vector secondPoint;
private Vector currentPosition;
//
public static Bitmap image;
public static string full_name_of_image = "\0";
public static UInt32[,] pixel;
// float
private float Xscroll;
private float Yscroll;
private float ScaleFactor = 1.0f;
private float x1,x2,y1,y2;
//
bool paint = false;
Point px, py;
int index = -1;
Pen erase = new Pen(Color.White, 10); //стерка
int x, y, sX,sY, cX, cY;
Pen p = new Pen(Color.Black, 1);
//PictureBox
private PictureBox pictureBox;
//Graphics
Graphics g;
#endregion
#region Открытие ToolStripMenuItem
private void открытьToolStripMenuItem_Click(object sender, EventArgs e)
{
OpenFileDialog open_dialog = new OpenFileDialog();
open_dialog.Filter = "Image Files(*.BMP;*.JPG;*.GIF;*.PNG)|*.BMP;*.JPG;*.GIF;*.PNG|All files (*.*)|*.*";
if (open_dialog.ShowDialog() == DialogResult.OK)
{
try
{
ClearDrawings();
full_name_of_image = open_dialog.FileName;
image = new Bitmap(open_dialog.FileName);
this.pictureBox1.SizeMode = PictureBoxSizeMode.Zoom; // это я закоментировал
pictureBox1.Size = GetZoomedSize(image.Size, pictureBox1.ClientSize);
pictureBox1.Image = image;
CenterPictureBox();
pictureBox1.Invalidate();
// инициализация графического обьекта
g = Graphics.FromImage(image);
// Получение матрицы с пикселями
pixel = new UInt32[image.Height, image.Width];
for (int y = 0; y < image.Height; y++)
for (int x = 0; x < image.Width; x++)
pixel[y, x] = (UInt32)(image.GetPixel(x, y).ToArgb());
}
catch
{
full_name_of_image = "\0";
DialogResult rezult = MessageBox.Show("Невозможно открыть выбранный файл",
"Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
private Size GetZoomedSize(Size imageSize, Size pictureBoxSize)
{
Size resultSize = imageSize;
float ratioX = (float)pictureBoxSize.Width / imageSize.Width;
float ratioY = (float)pictureBoxSize.Height / imageSize.Height;
float ratio = Math.Min(ratioX, ratioY);
resultSize.Width = (int)(imageSize.Width * ratio);
resultSize.Height = (int)(imageSize.Height * ratio);
return resultSize;
}
private void CenterPictureBox()
{
if (pictureBox1.Image != null)
{
// Центрируем PictureBox относительно panel1
pictureBox1.Location = new Point(
(panel2.ClientSize.Width - pictureBox1.Width) / 2,
(panel2.ClientSize.Height - pictureBox1.Height) / 2
);
// Убедитесь, что PictureBox не выходит за пределы panel1
if (pictureBox1.Left < 0) pictureBox1.Left = 0;
if (pictureBox1.Top < 0) pictureBox1.Top = 0;
}
}
#endregion
#region Сохранение ToolStripMenuItem
private void сохранитьToolStripMenuItem_Click(object sender, EventArgs e)
{
if (pictureBox1.Image != null)
{
SaveFileDialog saveFileDialog = new SaveFileDialog();
saveFileDialog.Filter = "JPeg Image|*.jpg|Bitmap Image|*.bmp|Gif Image|*.gif|PNG Image|*.png";
saveFileDialog.Title = "Выберите путь для сохраенения изображения";
saveFileDialog.ShowDialog();
if (saveFileDialog.FileName != "")
{
Bitmap newImage = (Bitmap)pictureBox1.Image;
using (System.IO.FileStream fs = (System.IO.FileStream)saveFileDialog.OpenFile())
{
switch (saveFileDialog.FilterIndex)
{
case 1:
newImage.Save(fs, System.Drawing.Imaging.ImageFormat.Jpeg);
break;
case 2:
newImage.Save(fs, System.Drawing.Imaging.ImageFormat.Bmp);
break;
case 3:
newImage.Save(fs, System.Drawing.Imaging.ImageFormat.Gif);
break;
case 4:
newImage.Save(fs, System.Drawing.Imaging.ImageFormat.Png);
break;
}
}
MessageBox.Show("Изображение сохранено");
}
}
}
#endregion
#region MouseMove
void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
coordinate.Text = string.Format("{0}, {1}", e.Location.X, e.Location.Y);
if (paint && e.Button == MouseButtons.Left)
{
if (index == 1 || index == 2)
{
if (e.X < 0 || e.Y < 0 || e.X >= pictureBox1.Width || e.Y >= pictureBox1.Height)
return; // Ограничение координат
px = e.Location;
Pen p = new Pen(index == 1 ? Color.Black : Color.White, penWidth);
Point scaledStart = TranslateZoomMousePosition(py.X, py.Y);
Point scaledEnd = TranslateZoomMousePosition(px.X, px.Y);
g.DrawLine(p, scaledStart, scaledEnd);
py = px;
pictureBox1.Refresh();
}
x = e.X;
y = e.Y;
pictureBox1.Invalidate(); // Вызов перерисовки для отображения текущей фигуры
}
x1 = e.Location.X;
x2 = pictureBox1.ClientSize.Width - x1;
y1 = e.Location.Y;
y2 = pictureBox1.ClientSize.Height - y1;
pictureBox1.Refresh();
}
#endregion " MouseWheel "
private void pictureBox1_MouseWheel(object sender, MouseEventArgs e)
{
float cx = pictureBox1.ClientSize.Width / 2.0f;
float cy = pictureBox1.ClientSize.Height / 2.0f;
float w = (x1 < cx) ? Math.Min(x1, x2) * 2.0f : Math.Max(x1, x2) * 2.0f;
float h = (y1 < cy) ? Math.Max(y1, y2) * 2.0f : Math.Min(y1, y2) * 2.0f;
float scale = (e.Delta < 0) ? 1 / 1.25f : 1.25f;
ScaleFactor *= scale;
float width = w * scale;
float height = h * scale;
float wl = (w - width) / 2;
float hl = (h - height) / 2;
Xscroll = Xscroll * scale - Pixel_To_Mn(wl);
Yscroll = Yscroll * scale - Pixel_To_Mn(hl);
/*SetScrollBarValues();*/
pictureBox1.Invalidate();
}
private float Pixel_To_Mn(float pixel)
{
return pixel * 25.4f / DPI;
}