首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > C# >

在一块空间中鼠标中键平移缩放图像

2012-12-20 
【分享】在一块空间中鼠标中键平移缩放图像按照国际惯例效果图:下载地址http://download.csdn.net/detail/cr

【分享】在一块空间中鼠标中键平移缩放图像
按照国际惯例   效果图:

下载地址
http://download.csdn.net/detail/crystal_lz/4696976

这几天 一朋友问我 在一个逻辑空间中操作图像的问题
干脆 就搞了一个例子 这里只是部分基本功能
鼠标中键点下平移图像
鼠标中键滚动的时候 根据鼠标的位置缩放图像

图像右上角对应的是 鼠标当前位置 
在picturebox上的坐标 和 在空间中的画布的坐标系中的一个虚拟的坐标

图像中间两条粗的线 就是在空间中的一个虚拟的坐标系

然后左上角显示的是 
缩放比
空间坐标系原点坐标位置对应在设备上面的坐标
pictrueBox左上角的位置在 空间坐标系中的坐标
pictrueBox右下角的位置在 空间坐标系中的坐标
当前pictrueBox显示的空间中的内容的大小

本来觉得 这东西没必要发上来的 但是想着反正都做了 估计有人需要 就发上来分享了
[最优解释]
收藏了
[其他解释]
挺好的,放大后图像画质怎么样??
[其他解释]
不得不说句 下载了几个录制gif的工具 没一个顺手的 也不知道平时大家录制gif用的都是啥软件
当时本想着 干脆以后要用自己写一个 仔细一想自己写一个估计也好不到哪去 顶多加上一些自己的习惯
[其他解释]
忘了贴代码了 反正也就一百多行
有啥写的不对的地方还请包涵


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace ImageScale
{
    public partial class Form1 : Form
    {
        public Form1() {
            InitializeComponent();
            this.StartPosition = FormStartPosition.CenterScreen;
            this.pictureBox1.BorderStyle = BorderStyle.FixedSingle;
            this.pictureBox1.BackColor = Color.DarkGray;
            this.pictureBox1.MouseWheel += new MouseEventHandler(pictureBox1_MouseWheel);
        }

        Bitmap m_bmp;               //画布中的图像
        Point m_ptCanvas;           //画布原点在设备上的坐标
        Point m_ptCanvasBuf;        //重置画布坐标计算时用的临时变量
        Point m_ptBmp;              //图像位于画布坐标系中的坐标
        float m_nScale = 1.0F;      //缩放比例

        Point m_ptMouseDown;        //鼠标点下是在设备坐标上的坐标

        string m_strMousePt;        //鼠标当前位置对应的坐标

        private void Form1_Load(object sender, EventArgs e) {
            m_bmp = GetScreen();
            //初始化 坐标
            m_ptCanvas = new Point(pictureBox1.Width / 2, pictureBox1.Height / 2);


            m_ptBmp = new Point(-(m_bmp.Width / 2), -(m_bmp.Height / 2));
        }
        //获取屏幕图像
        public Bitmap GetScreen() {
            Bitmap bmp = new Bitmap(Screen.PrimaryScreen.Bounds.Width,
                Screen.PrimaryScreen.Bounds.Height);
            using (Graphics g = Graphics.FromImage(bmp)) {
                g.CopyFromScreen(0, 0, 0, 0, bmp.Size);
            }
            return bmp;
        }
        //重绘图像
        private void pictureBox1_Paint(object sender, PaintEventArgs e) {
            Graphics g = e.Graphics;
            g.TranslateTransform(m_ptCanvas.X, m_ptCanvas.Y);       //设置坐标偏移
            g.ScaleTransform(m_nScale, m_nScale);                   //设置缩放比
            g.DrawImage(m_bmp, m_ptBmp);                            //绘制图像

            g.ResetTransform();                                     //重置坐标系
            Pen p = new Pen(Color.Cyan, 3);
            g.DrawLine(p, 0, m_ptCanvas.Y, pictureBox1.Width, m_ptCanvas.Y);
            g.DrawLine(p, m_ptCanvas.X, 0, m_ptCanvas.X, pictureBox1.Height);
            p.Dispose();
            //绘制网格线
            float nIncrement = (50 * m_nScale);             //网格间的间隔 根据比例绘制
            for (float x = m_ptCanvas.X; x > 0; x -= nIncrement)
                g.DrawLine(Pens.Cyan, x, 0, x, pictureBox1.Height);
            for (float x = m_ptCanvas.X; x < pictureBox1.Width; x += nIncrement)
                g.DrawLine(Pens.Cyan, x, 0, x, pictureBox1.Height);


            for (float y = m_ptCanvas.Y; y > 0; y -= nIncrement)
                g.DrawLine(Pens.Cyan, 0, y, pictureBox1.Width, y);
            for (float y = m_ptCanvas.Y; y < pictureBox1.Width; y += nIncrement)
                g.DrawLine(Pens.Cyan, 0, y, pictureBox1.Width, y);
            //计算屏幕左上角 和 右下角 对应画布上的坐标
            Size szTemp = pictureBox1.Size - (Size)m_ptCanvas;
            PointF ptCanvasOnShowRectLT = new PointF(
                -m_ptCanvas.X / m_nScale, -m_ptCanvas.Y / m_nScale);
            PointF ptCanvasOnShowRectRB = new PointF(
                szTemp.Width / m_nScale, szTemp.Height / m_nScale);
            //显示文字信息
            string strDraw = "Scale: " + m_nScale.ToString("F1") +
                "\nOrigin: " + m_ptCanvas.ToString() +
                "\nLT: " + Point.Round(ptCanvasOnShowRectLT).ToString() +
                "\nRB: " + Point.Round(ptCanvasOnShowRectRB).ToString() +
                "\n" + ((Size)Point.Round(ptCanvasOnShowRectRB)
                - (Size)Point.Round(ptCanvasOnShowRectLT)).ToString();
            Size strSize = TextRenderer.MeasureText(strDraw, this.Font);
            //绘制文字信息
            SolidBrush sb = new SolidBrush(Color.FromArgb(125, 0, 0, 0));
            g.FillRectangle(sb, 0, 0, strSize.Width, strSize.Height);
            g.DrawString(strDraw, this.Font, Brushes.Yellow, 0, 0);
            strSize = TextRenderer.MeasureText(m_strMousePt, this.Font);
            g.FillRectangle(sb, pictureBox1.Width - strSize.Width, 0, strSize.Width, strSize.Height);
            g.DrawString(m_strMousePt, this.Font, Brushes.Yellow, pictureBox1.Width - strSize.Width, 0);
            sb.Dispose();


        }

        private void pictureBox1_MouseDown(object sender, MouseEventArgs e) {
            if (e.Button == MouseButtons.Middle) {      //如果中键点下    初始化计算要用的临时数据
                m_ptMouseDown = e.Location;
                m_ptCanvasBuf = m_ptCanvas;
            }
            pictureBox1.Focus();
        }
        //平移图像
        private void pictureBox1_MouseMove(object sender, MouseEventArgs e) {
            if (e.Button == MouseButtons.Middle) {      //移动过程中 中键点下 重置画布坐标系
                //我总感觉这样写不妥 但却是方便计算  如果多次这样搞的话 还是重载操作符吧
                m_ptCanvas = (Point)((Size)m_ptCanvasBuf + ((Size)e.Location - (Size)m_ptMouseDown));
                pictureBox1.Invalidate();
            }
            //计算 右上角显示的坐标信息
            SizeF szSub = (Size)e.Location - (Size)m_ptCanvas;  //计算鼠标当前点对应画布中的坐标
            szSub.Width /= m_nScale;
            szSub.Height /= m_nScale;
            Size sz = TextRenderer.MeasureText(m_strMousePt, this.Font);    //获取上一次的区域并重绘
            pictureBox1.Invalidate(new Rectangle(pictureBox1.Width - sz.Width, 0, sz.Width, sz.Height));
            m_strMousePt = e.Location.ToString() + "\n" + ((Point)(szSub.ToSize())).ToString();
            sz = TextRenderer.MeasureText(m_strMousePt, this.Font);         //绘制新的区域
            pictureBox1.Invalidate(new Rectangle(pictureBox1.Width - sz.Width, 0, sz.Width, sz.Height));
        }
        //缩放图像
        private void pictureBox1_MouseWheel(object sender, MouseEventArgs e) {
            if (m_nScale <= 0.3 && e.Delta <= 0) return;        //缩小下线
            if (m_nScale >= 4.9 && e.Delta >= 0) return;        //放大上线


            //获取 当前点到画布坐标原点的距离
            SizeF szSub = (Size)m_ptCanvas - (Size)e.Location;
            //当前的距离差除以缩放比还原到未缩放长度
            float tempX = szSub.Width / m_nScale;           //这里
            float tempY = szSub.Height / m_nScale;          //将画布比例
            //还原上一次的偏移                               //按照当前缩放比还原到
            m_ptCanvas.X -= (int)(szSub.Width - tempX);     //没有缩放
            m_ptCanvas.Y -= (int)(szSub.Height - tempY);    //的状态
            //重置距离差为  未缩放状态                       
            szSub.Width = tempX;
            szSub.Height = tempY;
            m_nScale += e.Delta > 0 ? 0.2F : -0.2F;
            //重新计算 缩放并 重置画布原点坐标
            m_ptCanvas.X += (int)(szSub.Width * m_nScale - szSub.Width);
            m_ptCanvas.Y += (int)(szSub.Height * m_nScale - szSub.Height);
            pictureBox1.Invalidate();
        }
    }
}


[其他解释]
该回复于2012-10-29 09:14:44被版主删除
[其他解释]
引用:
挺好的,放大后图像画质怎么样??

= =!、、中间那个图像 就是一个摆设而已   
这东西 的主要意义 不在于 操作中间那个图 而是 整个虚拟的空间
一般 这样的程序 是在空间绘制图形用的    这里 只是搭建了一个虚拟空间而已 中间的图只是为了呈现空间的变化的
[其他解释]
做的很精彩,有点3DMAX的意思

热点排行