Сделать зум при наведении мышкой на PictureBox [Доработка]
Начнём с кода:
private void PictureBox_MouseEnter(object sender, EventArgs e)
{
PictureBox pb = sender as PictureBox;
zoomedForm = new Form();
zoomedForm.FormBorderStyle = FormBorderStyle.None;
zoomedForm.StartPosition = FormStartPosition.Manual;
zoomedForm.ShowInTaskbar = false;
zoomedForm.Size = new Size(300, 300); // Размер всплывающего окна
zoomedForm.TopMost = true;
zoomedPictureBox = new PictureBox();
zoomedPictureBox.SizeMode = PictureBoxSizeMode.Zoom;
zoomedPictureBox.Dock = DockStyle.Fill;
zoomedForm.Controls.Add(zoomedPictureBox);
zoomedForm.Show();
}
private void PictureBox_MouseMove(object sender, MouseEventArgs e)
{
UpdateZoomedImage();
}
private void PictureBox_MouseLeave(object sender, EventArgs e)
{
if (zoomedForm != null)
{
zoomedForm.Close();
zoomedForm.Dispose();
}
}
private void UpdateZoomedImage()
{
if (zoomedForm != null)
{
PictureBox pb = mainPictureBox;
// Получение текущих координат мыши на экране
Point mouseLocation = Control.MousePosition;
// Вычисление масштабного коэффициента для корректного отображения увеличенной части изображения
float scaleX = (float)pb.Image.Width / pb.ClientSize.Width;
float scaleY = (float)pb.Image.Height / pb.ClientSize.Height;
// Определение координат увеличенной части изображения с учетом масштабирования
int zoomedWidth = (int)(pb.Width * 0.10 * scaleX);
int zoomedHeight = (int)(pb.Height * 0.10 * scaleY);
int zoomedX = (int)((mouseLocation.X - pb.PointToScreen(Point.Empty).X - zoomedWidth / 2) * scaleX);
int zoomedY = (int)((mouseLocation.Y - pb.PointToScreen(Point.Empty).Y - zoomedHeight / 2) * scaleY);
// Создание нового Bitmap для увеличенной части изображения
Bitmap zoomedImage = new Bitmap(zoomedWidth, zoomedHeight);
using (Graphics g = Graphics.FromImage(zoomedImage))
{
g.DrawImage(pb.Image, new Rectangle(Point.Empty, zoomedImage.Size), zoomedX, zoomedY, zoomedWidth, zoomedHeight, GraphicsUnit.Pixel);
}
// Установка увеличенной части изображения в PictureBox на всплывающем окне
zoomedPictureBox.Image = zoomedImage;
// Получение текущего экрана, на котором находится курсор мыши
Screen currentScreen = Screen.FromPoint(mouseLocation);
// Установка положения всплывающего окна
int zoomedPictureBoxWidth = zoomedPictureBox.Image.Width * 2;
int zoomedPictureBoxHeight = zoomedPictureBox.Image.Height * 2;
Point newLocation = new Point(mouseLocation.X + 20, mouseLocation.Y - zoomedPictureBoxHeight - 40);
if (newLocation.X + zoomedForm.Width > currentScreen.Bounds.Right) // При достижении правого края экрана
newLocation.X = currentScreen.Bounds.Right - zoomedForm.Width;
if (newLocation.Y < currentScreen.Bounds.Top) // При достижении верхнего края экрана
newLocation.Y = currentScreen.Bounds.Top;
if (newLocation.Y + zoomedPictureBoxHeight > currentScreen.Bounds.Bottom) // При достижении нижнего края экрана
newLocation.Y = currentScreen.Bounds.Bottom - zoomedPictureBoxHeight;
// Установка положения всплывающего окна
zoomedForm.Location = newLocation;
// Установка размеров формы в соответствии с размерами увеличенной части изображения, решает проблему с белыми полями (т.к zoomedPictureBox.SizeMode = PictureBoxSizeMode.Zoom;)
zoomedForm.Size = new Size(zoomedPictureBoxWidth, zoomedPictureBoxHeight);
}
}
Я реализовал функцию зума при наведении мышкой на picturebox. Рядом с мышкой появляется новая форма (zoomedForm) и уже в ней отрисовывается приближенное изображение, всё работает хорошо но есть проблема: При изменении размеров формы (PictureBox внутри формы в состоянии dock - fill) picturebox конечно-же меняет размеры и логика приближения ломается т.е мышка в одном месте а зазумленая область (в zoomForm) уже в другом месте.
Проще говоря рассинхрон координат фактического места откуда должно быть зазумлено изображение и фактического местоположения мыши. Как можно решить данную проблему?