Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / WinForms, .Net Framework Новый топик    Ответить
 Zoom  [new]
ferzmikk
Member

Откуда:
Сообщений: 2213
Здравствуйте!

Есть windows Form. На форме только Panel. Форма при загрузки открывает изображение и роликом мыши можно менять zoom. И если мышкой нажать на Panel, то изображение восстанавливается.
+C#
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

namespace TestZoom2
{
    public partial class Form1 : Form
    {        
        Image image; //Исходное изображение
        Image imageZoom; //Изображение после Zoom
        double zoom = 1.0; //Последний zoom
        double Stride = 0.005;

        public Form1()
        {
            InitializeComponent();            
            this.MaximizeBox = false;
            this.MinimizeBox = false;
        }

        private void Form1_Load(object sender, EventArgs e)
        {            
            this.FormBorderStyle = FormBorderStyle.FixedDialog;

            image = Image.FromFile("C:\\Users\\Acer\\Desktop\\image1.jpg");            

            pictureBox1 = new PictureBox();
            pictureBox1.Name = "pictureBox1";
            pictureBox1.SizeMode = PictureBoxSizeMode.AutoSize;            
            pictureBox1.Image = image;

            panel1.AutoScroll = true;
            panel1.Controls.Add(pictureBox1);            
            pictureBox1.MouseWheel += new MouseEventHandler(pictureBox1_MouseWheel);
            //pictureBox1.MouseHover += new System.EventHandler(pictureBox1_MouseHover);
            pictureBox1.Image = image;
            imageZoom = image;

            pictureBox1.Focus();
        }

        private void pictureBox1_MouseWheel(object sender, MouseEventArgs e)
        {
            if (pictureBox1.Image != null)
            {
                if (e.Delta < 0)
                {
                    zoom = zoom * (1 + Stride);
                }
                else if (e.Delta > 0)
                {
                    zoom = zoom * (1 - Stride);                    
                }

                Bitmap bmp = new Bitmap(imageZoom,
                                        Convert.ToInt32(pictureBox1.Width * zoom),
                                        Convert.ToInt32(pictureBox1.Height * zoom));
                Graphics g = Graphics.FromImage(bmp);
                g.InterpolationMode = InterpolationMode.Default;
                imageZoom = bmp;

                pictureBox1.Width = (int)Math.Round(pictureBox1.Image.Width * zoom);
                pictureBox1.Height = (int)Math.Round(pictureBox1.Image.Height * zoom);

                pictureBox1.Image = bmp;                
            }
        }

        /*private void pictureBox1_MouseHover(object sender, EventArgs e)
        {
            pictureBox1.Focus();
        }*/

        //Восстановление изображения
        private void panel1_MouseDown(object sender, MouseEventArgs e)
        {
            pictureBox1.Image = image;
            imageZoom = image;
            zoom = 1.0;
            //pictureBox1.Focus();
        }
    }
}
Программа работает, но будто с опозданием. Крутишь ролик в один сдвиг в одну сторону - меняется изображение в соответствующую сторону. Дальше крутишь - также норм. Но потом, если крутить в другую сторону ролика, то не меняет направление и дальше изменяет размер как раньше, и чуть позже изменять в нужную сторону. Будто работает с опозданием.

Скажите, почему так происходит и как это исправить?
1 фев 21, 16:02    [22272644]     Ответить | Цитировать Сообщить модератору
 Re: Zoom  [new]
felix_ff
Member

Откуда: Moscow
Сообщений: 1731
ferzmikk,

+

Вам принципиально использовать только winforms?

Работа с изображением в разы удобнее в WPF
1 фев 21, 19:18    [22272811]     Ответить | Цитировать Сообщить модератору
 Re: Zoom  [new]
ferzmikk
Member

Откуда:
Сообщений: 2213
felix_ff,

Можно и в WPF. Учитывая, что на форме отдельно на button накладываю bmp рядом с текстом, то тут не особо удобно.
1 фев 21, 19:23    [22272816]     Ответить | Цитировать Сообщить модератору
 Re: Zoom  [new]
Cat2
Member

Откуда: Petroskoi, Karjala
Сообщений: 145742
felix_ff
ferzmikk,

+

Вам принципиально использовать только winforms?

Работа с изображением в разы удобнее в WPF

Библиотеки одни и те же. Нет особого смыла.
2 фев 21, 10:41    [22273075]     Ответить | Цитировать Сообщить модератору
 Re: Zoom  [new]
Cat2
Member

Откуда: Petroskoi, Karjala
Сообщений: 145742
ferzmikk,

Изменения размеров надо делать не от текущего размера, а от исходного


Bitmap bmp = new Bitmap(imageZoom,
                                        Convert.ToInt32(image.Width * zoom),
                                        Convert.ToInt32(image.Height * zoom));


На вашем месте я бы менял не размер рисунка, а размер PictureBox в режиме PictureBoxSizeMode.Zoom
2 фев 21, 10:47    [22273079]     Ответить | Цитировать Сообщить модератору
 Re: Zoom  [new]
Сон Веры Павловны
Member

Откуда:
Сообщений: 6154
Cat2
Библиотеки одни и те же. Нет особого смыла.

Это с чего бы вдруг?
2 фев 21, 11:11    [22273090]     Ответить | Цитировать Сообщить модератору
 Re: Zoom  [new]
Cat2
Member

Откуда: Petroskoi, Karjala
Сообщений: 145742
Примерно так

private void Form1_Load(object sender, EventArgs e)
        {
            this.FormBorderStyle = FormBorderStyle.FixedDialog;

            image = Image.FromFile(@"F:\inetpub\wwwroot\wlk\2020-12\img_7504-1000.jpg");
            //pictureBox1 = new PictureBox();
            //pictureBox1.Name = "pictureBox1";
            pictureBox1.SizeMode = PictureBoxSizeMode.Zoom;
            
            pictureBox1.Width = image.Width;
            pictureBox1.Height = image.Height;

            panel1.AutoScroll = true;
            panel1.Controls.Add(pictureBox1);
            pictureBox1.MouseWheel += new MouseEventHandler(pictureBox1_MouseWheel);
            pictureBox1.Image = image;
            pictureBox1.Focus();
        }

        private void pictureBox1_MouseWheel(object sender, MouseEventArgs e)
        {
          
            if (pictureBox1.Image != null)
            {
                zoom *=  (1 + Stride * Math.Sign(e.Delta));
                pictureBox1.Width =Convert.ToInt32( image.Width * zoom);
                pictureBox1.Height = Convert.ToInt32(image.Height * zoom);
            }
        }
2 фев 21, 11:11    [22273091]     Ответить | Цитировать Сообщить модератору
 Re: Zoom  [new]
Cat2
Member

Откуда: Petroskoi, Karjala
Сообщений: 145742
Сон Веры Павловны
Cat2
Библиотеки одни и те же. Нет особого смыла.

Это с чего бы вдруг?

Выигрыша в производительности не будет, а зачем иначе огород городить?
2 фев 21, 11:12    [22273093]     Ответить | Цитировать Сообщить модератору
 Re: Zoom  [new]
ferzmikk
Member

Откуда:
Сообщений: 2213
Cat2
Примерно так
Получилось! Намного лучше работает zoom теперь.

Только вот один момент есть. Когда увеличиваешь изображение, где позже появляется вертикальный ползунок и потом когда обратно крутишь колесо мыши, то сначала перемещает ползунок вниз и только потом уменьшается размер.

Скажите, как сделать так, чтобы прокрутка колеса мыши не влияло на прокрутку ползунка?
2 фев 21, 11:42    [22273111]     Ответить | Цитировать Сообщить модератору
 Re: Zoom  [new]
Roman Mejtes
Member

Откуда: г. Пермь
Сообщений: 4159
ferzmikk,

заблокируй прокрутку колеса на уровне scrollbox'а
2 фев 21, 11:51    [22273118]     Ответить | Цитировать Сообщить модератору
 Re: Zoom  [new]
ferzmikk
Member

Откуда:
Сообщений: 2213
Roman Mejtes
ferzmikk,

заблокируй прокрутку колеса на уровне scrollbox'а
Получилось так
 private void pictureBox1_MouseWheel(object sender, MouseEventArgs e)
        {
            if (pictureBox1.Image != null)
            {
                zoom *= (1 + Stride * Math.Sign(e.Delta));
                pictureBox1.Width = Convert.ToInt32(image.Width * zoom);
                pictureBox1.Height = Convert.ToInt32(image.Height * zoom);
                ((HandledMouseEventArgs)e).Handled = true;
            }
        }
2 фев 21, 12:00    [22273123]     Ответить | Цитировать Сообщить модератору
 Re: Zoom  [new]
felix_ff
Member

Откуда: Moscow
Сообщений: 1731
ferzmikk,

в WPF это выглядело бы так:
+ xaml

<Window x:Class="Zoom.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Zoom"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800" MouseWheel="Window_MouseWheel">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="24"/>
        </Grid.RowDefinitions>
        <Image x:Name="img" Grid.Row="0" Source="3d bar chart.bmp" RenderTransformOrigin="0.5,0.5" >
            <Image.RenderTransform>
                <TransformGroup>
                    <ScaleTransform ScaleX="{Binding Value,ElementName=zoomer}" ScaleY="{Binding Value,ElementName=zoomer}"/>
                </TransformGroup>
            </Image.RenderTransform>
        </Image>
        <Slider x:Name="zoomer" Grid.Row="1" Minimum="1" Maximum="100"/>
    </Grid>

</Window>


+ codebehind

using System;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media.Imaging;
namespace Zoom
{
    public partial class MainWindow : Window
    {      
        public MainWindow()
        {
            InitializeComponent();
            MouseButtonEventHandler handler = Image_MouseLeftButtonDown;
            img.AddHandler(UIElement.MouseLeftButtonDownEvent, handler, true);
        }

        private void Image_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (e.ClickCount == 2)
            {
                var dialog = new Microsoft.Win32.OpenFileDialog();
                var dr = dialog.ShowDialog();
                if (dr.HasValue && dr.Value)
                {
                    BitmapImage bmp = new BitmapImage(new Uri(dialog.FileName));
                    img.Source = bmp;
                    
                }
            }
        }

        private void Window_MouseWheel(object sender, MouseWheelEventArgs e)
        {
            zoomer.Value += e.Delta * 0.01;
        }
    }
}

2 фев 21, 16:56    [22273374]     Ответить | Цитировать Сообщить модератору
 Re: Zoom  [new]
ferzmikk
Member

Откуда:
Сообщений: 2213
Cat2, Roman Mejtes, felix_ff,

Спасибо!
2 фев 21, 21:12    [22273488]     Ответить | Цитировать Сообщить модератору
Все форумы / WinForms, .Net Framework Ответить