2014/5/7

Capture image by moving your mouse or setting the x,y-coordinate


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Windows.Forms;
using System.Reflection;
using System.IO;



namespace CupImage
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            string strFilename = "";
            OpenFileDialog dlgOpen = null;
            try
            {
                dlgOpen = new OpenFileDialog();
                dlgOpen.Filter = "All Image Files(*.*)|*.*";
                if (dlgOpen.ShowDialog() == DialogResult.OK)
                {
                    if (dlgOpen.FileName == "") return;
                    strFilename = dlgOpen.FileName;
                    pbxOriImage.Image = Image.FromFile(strFilename);
                    this.SetImageSizeMode(pbxOriImage);                  
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Unknown Image Format(" + strFilename + ")\r\n" + ex.Message , "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                if (dlgOpen != null)
                    dlgOpen.Dispose();
                dlgOpen = null;
            }
        }


        private void button2_Click(object sender, EventArgs e)
        {
            SaveFileDialog dlgSave = new SaveFileDialog();

            if (dlgSave.ShowDialog() == DialogResult.OK)
            {
                pbxCutImage.Image.Save(dlgSave.FileName);
            }
        }

        private void button3_Click(object sender, EventArgs e)
        {
            SaveImage(Convert.ToInt32(textBox1.Text), Convert.ToInt32(textBox2.Text), Convert.ToInt32(textBox3.Text), Convert.ToInt32(textBox4.Text));
        }
       
        private void SetImageSizeMode(PictureBox pImage)
        {
            if (pImage == null) return;
            Image imgResult = pImage.Image;
            if (imgResult != null)
            {
                //控制圖片顯示方式
                if (imgResult.Width > pImage.Width || imgResult.Height > pImage.Height)
                {
                    pImage.SizeMode = PictureBoxSizeMode.Zoom;
                }
                else
                {
                    pImage.SizeMode = PictureBoxSizeMode.CenterImage;
                }
            }
        }

       
        Point fPtStart;                     //開始位置矩形的位置
        bool fHaveImage = false;            //是否有圖片
        Point fPtFirst;                     //滑鼠按下去的位置
        Point fPtSecond;                    //滑鼠当前位置

       
        private void pbxOriImage_MouseDown(object sender, MouseEventArgs e)
        {
            this.Cursor = Cursors.Cross;
            fPtFirst = new Point(e.X, e.Y);
            fPtStart = new Point(e.X, e.Y);
            if ((sender as PictureBox).Image != null)
            {
                this.fHaveImage = true;
            }
            else
            {
                this.fHaveImage = false;
            }
        }

        private void pbxOriImage_MouseMove(object sender, MouseEventArgs e)
        {
            if (this.Cursor == Cursors.Cross)
            {
                fPtSecond = new Point(e.X, e.Y);


                if ((fPtSecond.X - fPtFirst.X) > 0 && (fPtSecond.Y - fPtFirst.Y) > 0)
                {
                    //滑鼠目前位置於按下去位置的右下角
                    fPtStart = new Point(fPtFirst.X, fPtFirst.Y);
                }
                else if ((fPtSecond.X - fPtFirst.X) > 0 && (fPtSecond.Y - fPtFirst.Y) < 0)
                {
                    //滑鼠目前位置於按下去位置的右上角
                    fPtStart = new Point(fPtFirst.X, fPtSecond.Y);
                }
                else if ((fPtSecond.X - fPtFirst.X) < 0 && (fPtSecond.Y - fPtFirst.Y) > 0)
                {
                    //滑鼠目前位置於按下去位置的左下角
                    fPtStart = new Point(fPtSecond.X, fPtFirst.Y);
                }
                else
                {
                    //滑鼠目前位置於按下去位置的左上角
                    fPtStart = new Point(fPtSecond.X, fPtSecond.Y);
                }              
                pbxOriImage.Invalidate();       //移動時繪制圖形框
            }
        }

       
        private void pbxOriImage_MouseUp(object sender, MouseEventArgs e)
        {
            if (this.fHaveImage == false) return;
            try
            {
                fPtSecond = new Point(e.X, e.Y);
                if ((fPtSecond.X - fPtFirst.X) > 0 && (fPtSecond.Y - fPtFirst.Y) > 0)
                {
                    //滑鼠目前位置於按下去位置的右下角
                    fPtStart = new Point(fPtFirst.X, fPtFirst.Y);
                }
                else if ((fPtSecond.X - fPtFirst.X) > 0 && (fPtSecond.Y - fPtFirst.Y) < 0)
                {
                    //滑鼠目前位置於按下去位置的右上角
                    fPtStart = new Point(fPtFirst.X, fPtSecond.Y);
                }
                else if ((fPtSecond.X - fPtFirst.X) < 0 && (fPtSecond.Y - fPtFirst.Y) > 0)
                {
                    //滑鼠目前位置於按下去位置的左下角
                    fPtStart = new Point(fPtSecond.X, fPtFirst.Y);
                }
                else
                {
                    //滑鼠目前位置於按下去位置的左上角
                    fPtStart = new Point(fPtSecond.X, fPtSecond.Y);
                }

                Rectangle rectDisplay = this.GetPictureDisplaySize(pbxOriImage);        //圖片實際顯示的大小


                int Width = Math.Abs((fPtSecond.X - fPtFirst.X));
                int Height = Math.Abs((fPtSecond.Y - fPtFirst.Y));

                double dWRate = pbxOriImage.Image.Width / (double)rectDisplay.Width;    //縮放比例:寬
                double dHRate = pbxOriImage.Image.Height / (double)rectDisplay.Height;  //縮放比例:高

                int intRealWidth = (int)(dWRate * Width);           //實際需要截取的圖片寬度
                int intRealHeight = (int)(dHRate * Height);         //實際需要截取的圖片高度

                int intRealX = (int)((fPtStart.X - rectDisplay.X) * dWRate); //實際的X坐標
                int intRealY = (int)((fPtStart.Y - rectDisplay.Y) * dHRate); //實際的Y坐標

                Bitmap bmpDest = new Bitmap(intRealWidth, intRealHeight, PixelFormat.Format32bppRgb);       //目標圖片大小

                Graphics g = Graphics.FromImage(bmpDest);               //創建GDI

                Rectangle rectDest = new Rectangle(0, 0, intRealWidth, intRealHeight);
                Rectangle rectSource = new Rectangle(intRealX,intRealY, intRealWidth, intRealHeight);

                g.DrawImage(pbxOriImage.Image, rectDest, rectSource, GraphicsUnit.Pixel);               //繪圖

                pbxCutImage.Image = (Image)bmpDest;

                g.Dispose();

                SetImageSizeMode(pbxCutImage);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            { this.Cursor = Cursors.Default; }          
        }

     
        public Rectangle GetPictureDisplaySize(PictureBox pbxImage)
        {
            if (pbxImage != null)
            {
                PropertyInfo ppiImageRect = pbxImage.GetType().GetProperty("ImageRectangle", BindingFlags.Instance | BindingFlags.NonPublic);
                return (Rectangle)ppiImageRect.GetValue(pbxImage, null);
            }
            return new Rectangle(0, 0, 1, 1);
        }

        public void SaveImage(int x, int y, int a, int b)
        {
            if (pbxOriImage.Image == null) return;
            fPtFirst.X = x > pbxOriImage.Width?pbxOriImage.Width:x;
            fPtFirst.Y = y > pbxOriImage.Height?pbxOriImage.Height:y;
            fPtSecond.X = x + a > pbxOriImage.Width ? pbxOriImage.Width : x+a;
            fPtSecond.Y = y + b > pbxOriImage.Height ? pbxOriImage.Height : y+b;
            fPtStart.X = x > pbxOriImage.Width ? pbxOriImage.Width : x;
            fPtStart.Y = y > pbxOriImage.Height ? pbxOriImage.Height : y;

            Rectangle rectDisplay = this.GetPictureDisplaySize(pbxOriImage);        //圖片實際顯示的大小


            int Width = Math.Abs((fPtSecond.X - fPtFirst.X));
            int Height = Math.Abs((fPtSecond.Y - fPtFirst.Y));

            double dWRate = pbxOriImage.Image.Width / (double)rectDisplay.Width;    //縮放比例:寬
            double dHRate = pbxOriImage.Image.Height / (double)rectDisplay.Height;  //縮放比例:高

            int intRealWidth = (int)(dWRate * Width);           //實際需要截取的圖片寬度
            int intRealHeight = (int)(dHRate * Height);         //實際需要截取的圖片高度

            int intRealX = (int)((fPtStart.X - rectDisplay.X) * dWRate); //實際的X坐標
            int intRealY = (int)((fPtStart.Y - rectDisplay.Y) * dHRate); //實際的Y坐標

            Bitmap bmpDest = new Bitmap(intRealWidth, intRealHeight, PixelFormat.Format32bppRgb);       //目標圖片大小

            Graphics g = Graphics.FromImage(bmpDest);               //創建GDI

            Rectangle rectDest = new Rectangle(0, 0, intRealWidth, intRealHeight);
            Rectangle rectSource = new Rectangle(intRealX, intRealY, intRealWidth, intRealHeight);

            g.DrawImage(pbxOriImage.Image, rectDest, rectSource, GraphicsUnit.Pixel);               //繪圖

            pbxCutImage.Image = (Image)bmpDest;

            g.Dispose();

            SetImageSizeMode(pbxCutImage);
        }
        private void pbxOriImage_Paint(object sender, PaintEventArgs e)
        {
            int intWidth = 0;
            int intHeight = 0;
            if (this.fHaveImage == true)
            {
                Pen p = new Pen(Color.Black, 1);
                p.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;

                intWidth = Math.Abs(fPtFirst.X - fPtSecond.X);
                intHeight = Math.Abs(fPtFirst.Y - fPtSecond.Y);                        

                Rectangle rectDraw = new Rectangle(fPtStart, new Size(intWidth, intHeight));
                e.Graphics.DrawRectangle(p, rectDraw);
            }
        }
     
       
      }
 }

沒有留言:

張貼留言