如何将图像绘制到pictureBox?

时间:2013-05-20 07:08:15

标签: c# winforms

Form1的顶部,我有:

Bitmap bitmap;

在构造函数中:

bitmap = (Bitmap)sc.CaptureScreen();

创建100个屏幕截图:

for (int i = 0; i < 100; i++)
{
    bitmap.Save(@"D:\ffmpegtorun\ffmpeg-20130509-git-13cb6ed-win32-static\bin\Screenshots\" + "Screenshot" + i.ToString("D6") + ".Jpg", ImageFormat.Jpeg);
}

将屏幕截图放到pictureBox1

pictureBox1.Image =  bitmap = new Bitmap(@"D:\ffmpegtorun\ffmpeg-20130509-git-13cb6ed-win32-static\bin\Screenshots\Screenshot000000.jpg");

然后在我正在做的pictureBox1绘画事件中:

private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
    int width = pictureBox1.Width;
    int height = pictureBox1.Height;

    // Draw the image with no shrinking or stretching.
    e.Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
    e.Graphics.DrawImage(
                bitmap,
                new Rectangle(0, 0, width, height),  // destination rectangle  
                0,
                0,           // upper-left corner of source rectangle
                width,       // width of source rectangle
                height,      // height of source rectangle
                GraphicsUnit.Pixel,
                null);

}

这是截图类,它截取屏幕截图:

using System;
using System.Runtime.InteropServices;
using System.Drawing;
using System.Drawing.Imaging;
namespace ScreenShotDemo
{
    /// <summary>
    /// Provides functions to capture the entire screen, or a particular window, and save it to a file.
    /// </summary>
    public class ScreenCapture
    {
        /// <summary>
        /// Creates an Image object containing a screen shot of the entire desktop
        /// </summary>
        /// <returns></returns>
        public Image CaptureScreen()
        {
            return CaptureWindow(User32.GetDesktopWindow());
        }
        /// <summary>
        /// Creates an Image object containing a screen shot of a specific window
        /// </summary>
        /// <param name="handle">The handle to the window. (In windows forms, this is obtained by the Handle property)</param>
        /// <returns></returns>
        public Image CaptureWindow(IntPtr handle)
        {
            // get te hDC of the target window
            IntPtr hdcSrc = User32.GetWindowDC(handle);
            // get the size
            User32.RECT windowRect = new User32.RECT();
            User32.GetWindowRect(handle, ref windowRect);
            int width = windowRect.right - windowRect.left;
            int height = windowRect.bottom - windowRect.top;
            // create a device context we can copy to
            IntPtr hdcDest = GDI32.CreateCompatibleDC(hdcSrc);
            // create a bitmap we can copy it to,
            // using GetDeviceCaps to get the width/height
            IntPtr hBitmap = GDI32.CreateCompatibleBitmap(hdcSrc, width, height);
            // select the bitmap object
            IntPtr hOld = GDI32.SelectObject(hdcDest, hBitmap);
            // bitblt over
            GDI32.BitBlt(hdcDest, 0, 0, width, height, hdcSrc, 0, 0, GDI32.SRCCOPY);
            // restore selection
            GDI32.SelectObject(hdcDest, hOld);
            // clean up 
            GDI32.DeleteDC(hdcDest);
            User32.ReleaseDC(handle, hdcSrc);
            // get a .NET image object for it
            Image img = Image.FromHbitmap(hBitmap);
            // free up the Bitmap object
            GDI32.DeleteObject(hBitmap);
            return img;
        }
        /// <summary>
        /// Captures a screen shot of a specific window, and saves it to a file
        /// </summary>
        /// <param name="handle"></param>
        /// <param name="filename"></param>
        /// <param name="format"></param>
        public void CaptureWindowToFile(IntPtr handle, string filename, ImageFormat format)
        {
            Image img = CaptureWindow(handle);
            img.Save(filename, format);
        }
        /// <summary>
        /// Captures a screen shot of the entire desktop, and saves it to a file
        /// </summary>
        /// <param name="filename"></param>
        /// <param name="format"></param>
        public void CaptureScreenToFile(string filename, ImageFormat format)
        {
            Image img = CaptureScreen();
            img.Save(filename, format);
        }

        /// <summary>
        /// Helper class containing Gdi32 API functions
        /// </summary>
        private class GDI32
        {

            public const int SRCCOPY = 0x00CC0020; // BitBlt dwRop parameter
            [DllImport("gdi32.dll")]
            public static extern bool BitBlt(IntPtr hObject, int nXDest, int nYDest,
                int nWidth, int nHeight, IntPtr hObjectSource,
                int nXSrc, int nYSrc, int dwRop);
            [DllImport("gdi32.dll")]
            public static extern IntPtr CreateCompatibleBitmap(IntPtr hDC, int nWidth,
                int nHeight);
            [DllImport("gdi32.dll")]
            public static extern IntPtr CreateCompatibleDC(IntPtr hDC);
            [DllImport("gdi32.dll")]
            public static extern bool DeleteDC(IntPtr hDC);
            [DllImport("gdi32.dll")]
            public static extern bool DeleteObject(IntPtr hObject);
            [DllImport("gdi32.dll")]
            public static extern IntPtr SelectObject(IntPtr hDC, IntPtr hObject);
        }

        /// <summary>
        /// Helper class containing User32 API functions
        /// </summary>
        private class User32
        {
            [StructLayout(LayoutKind.Sequential)]
            public struct RECT
            {
                public int left;
                public int top;
                public int right;
                public int bottom;
            }
            [DllImport("user32.dll")]
            public static extern IntPtr GetDesktopWindow();
            [DllImport("user32.dll")]
            public static extern IntPtr GetWindowDC(IntPtr hWnd);
            [DllImport("user32.dll")]
            public static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDC);
            [DllImport("user32.dll")]
            public static extern IntPtr GetWindowRect(IntPtr hWnd, ref RECT rect);
        }
    }
}

结果如下:

https://skydrive.live.com/redir?resid=EB1C71C44C3976D5!270&authkey=!ANAKzbwJI-3TQqE

图片不适合pictureBox。

但如果我用放大镜玻璃移动它现在的pictureBox我看到它平滑但图像不适合pictureBox:

https://skydrive.live.com/redir?resid=EB1C71C44C3976D5!271&authkey=!ALizvsyxrMuyVTk

这是放大镜玻璃表格代码:

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

namespace Magnifier20070401
{
    public partial class MagnifierForm : Form
    {
        private bool _doMove;

        public MagnifierForm()
        {
            InitializeComponent();

            _doMove = true;
            FormBorderStyle = FormBorderStyle.None;
            ShowInTaskbar = false;
            TopMost = true;
            Width = 150;
            Height = 150;
            GraphicsPath gp = new GraphicsPath();
            gp.AddEllipse(ClientRectangle);
            Region = new Region(gp);
            mTimer = new Timer();
            mTimer.Enabled = true;
            mTimer.Interval = 20;
            mTimer.Tick += new EventHandler(HandleTimer);
            mScreenImage = new Bitmap(Screen.PrimaryScreen.Bounds.Width,
                                     Screen.PrimaryScreen.Bounds.Height);
            mStartPoint = new Point(500, 500);
            mTargetPoint = new Point(500, 500);
            speed = 0.35F;
            zoom = 3.0F;
            hidecursor = false;
            hue = 30;
        }

        public MagnifierForm(bool MoveTheGlass, bool InTaskBar, int MagnifierWidth, int MagnifierHeight, Point MagnifierStartPoint, float SpeedFactor, float ChangeZoom, bool HideMouseCursor, float AdjustHue)
        {
            InitializeComponent();

            FormBorderStyle = FormBorderStyle.None;
            TopMost = true;
            GraphicsPath gp = new GraphicsPath();
            gp.AddEllipse(ClientRectangle);
            Region = new Region(gp);
            mTimer = new Timer();
            mTimer.Enabled = true;
            mTimer.Interval = 20;
            mTimer.Tick += new EventHandler(HandleTimer);
            mScreenImage = new Bitmap(Screen.PrimaryScreen.Bounds.Width,
                                     Screen.PrimaryScreen.Bounds.Height);

            _doMove = MoveTheGlass;
            ShowInTaskbar = InTaskBar;
            Width = MagnifierWidth;
            Height = MagnifierHeight;
            mStartPoint = MagnifierStartPoint;
            mTargetPoint = MagnifierStartPoint;
            speed = SpeedFactor;
            zoom = ChangeZoom;
            hidecursor = HideMouseCursor;
            hue = AdjustHue;
        }

        protected override void OnShown(EventArgs e)
        {
            RepositionAndShow();
        }

        private delegate void RepositionAndShowDelegate();

        private void RepositionAndShow()
        {
            if (InvokeRequired)
            {
                Invoke(new RepositionAndShowDelegate(RepositionAndShow));
            }
            else
            {
                Graphics g = Graphics.FromImage(mScreenImage);
                g.CopyFromScreen(0, 0, 0, 0, new Size(mScreenImage.Width, mScreenImage.Height));
                HSLAdjust.BitmapFunctions bf = new HSLAdjust.BitmapFunctions((Bitmap)mScreenImage);
                bf.Hue(hue);
                bf.Dispose();
                g.Dispose();

                if (hidecursor == true)
                {
                    Cursor.Hide();
                }
                else
                {
                    Cursor = Cursors.Cross;
                }
                Capture = true;
                mCurrentPoint = Cursor.Position;
                Show(); // to add here the bool of the Mouse Cursor to hide or not to hide
            }
        }

        void HandleTimer(object sender, EventArgs e)
        {
            float dx = speed * (mTargetPoint.X - mCurrentPoint.X);
            float dy = speed * (mTargetPoint.Y - mCurrentPoint.Y);

            if (mFirstTime)
            {
                mFirstTime = false;

                mCurrentPoint.X = mTargetPoint.X;
                mCurrentPoint.Y = mTargetPoint.Y;

                Left = (int)mCurrentPoint.X - Width / 2;
                Top = (int)mCurrentPoint.Y - Height / 2;

                return;
            }

            mCurrentPoint.X += dx;
            mCurrentPoint.Y += dy;

            if (Math.Abs(dx) < 1 && Math.Abs(dy) < 1)
            {
                mTimer.Enabled = false;
            }
            else
            {
                // Update location
                Left = (int)mCurrentPoint.X - Width / 2;
                Top = (int)mCurrentPoint.Y - Height / 2;
                mLastMagnifierPosition = new Point((int)mCurrentPoint.X, (int)mCurrentPoint.Y);
            }

            Refresh();
        }


        protected override void OnMouseDown(MouseEventArgs e)
        {
            mOffset = new Point(Width / 2 - e.X, Height / 2 - e.Y);
            mCurrentPoint = PointToScreen(new Point(e.X + mOffset.X, e.Y + mOffset.Y));
            mTargetPoint = mCurrentPoint;
            mTimer.Enabled = true;

        }

        protected override void OnMouseMove(MouseEventArgs e)
        {
            if (_doMove == true)
            {
                mTargetPoint = PointToScreen(new Point(e.X + mOffset.X, e.Y + mOffset.Y));
                mTimer.Enabled = true;
            }

        }

        protected override void OnPaintBackground(PaintEventArgs e)
        {
            /*if (mConfiguration.DoubleBuffered)
            {
                // Do not paint background (required for double buffering)!
            }
            else
            {
                base.OnPaintBackground(e);
            }*/
            base.OnPaintBackground(e);
        }

        protected override void  OnPaint(PaintEventArgs e)
        {
            if (mBufferImage == null)
            {
                mBufferImage = new Bitmap(Width, Height);
            }
            Graphics bufferGrf = Graphics.FromImage(mBufferImage);

            Graphics g;

            /*if (mConfiguration.DoubleBuffered)
            {
                g = bufferGrf;
            }
            else
            {*/
                g = e.Graphics;
            //}

            if (mScreenImage != null)
            {
                Rectangle dest = new Rectangle(0, 0, Width, Height);
                int w = (int)(Width / zoom);//mConfiguration.ZoomFactor);
                int h = (int)(Height / zoom);//mConfiguration.ZoomFactor);
                int x = Left - w / 2 + Width / 2;
                int y = Top - h / 2 + Height / 2;

                g.DrawImage(
                    mScreenImage,
                    dest,
                    x, y,
                    w, h,
                    GraphicsUnit.Pixel);
            }
                e.Graphics.DrawImage(mBufferImage, 0, 0, Width, Height);      
        }


        //--- Data Members ---
        #region Data Members
        private bool hidecursor;
        private float zoom;
        private float hue;
        private float speed;
        private Timer mTimer;
        private Image mBufferImage = null;
        private Image mScreenImage = null;
        private Point mStartPoint;
        private PointF mTargetPoint;
        private PointF mCurrentPoint;
        private Point mOffset;
        private bool mFirstTime = true;
        private static Point mLastMagnifierPosition = Cursor.Position;
        #endregion


        // New code \\

        protected override void OnMouseEnter(EventArgs e)
        {
            base.OnMouseEnter(e);

            Point pt = Control.MousePosition;
            int eX = pt.X - this.Left;
            int eY = pt.Y - this.Top;

            mOffset = new Point(0, 0);
            mCurrentPoint = PointToScreen(new Point(eX + mOffset.X, eY + mOffset.Y));
            mTargetPoint = mCurrentPoint;
            mTimer.Enabled = true;
            this.Capture = true;
        }

        protected override void OnMouseLeave(EventArgs e)
        {
            base.OnMouseLeave(e);

            if (_doMove)
            {
                Left = (int)mCurrentPoint.X - Width / 2;
                Top = (int)mCurrentPoint.Y - Height / 2;
            }
        }

        protected override void OnMouseClick(MouseEventArgs e)
        {
            base.OnMouseClick(e);
            if (_doMove == true)
            {
                _doMove = false;
            }
            else
            {
                _doMove = true;
            }
        }
    }
}

2 个答案:

答案 0 :(得分:1)

您可以使用sizemode的picturebox属性。

或者将图像转换为bytearray并使用您预定义的尺寸或您想要的图像尺寸创建新图像。

答案 1 :(得分:1)

您可以将e.Graphics.InterpolationMode设为InterpolationMode.HighQualityBicubic 所以使用这一行:

e.Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
在绘制图像之前

。这使图像平滑。

不要忘记:

using System.Drawing.Drawing2D;

修改
而不是使用它:

int width = bitmap.Width;
int height = bitmap.Height;

使用:

int width = pictureBox1.Width;
int height = pictureBox1.Height;

将绘制的位图大小调整为PictureBox的大小。

编辑#2:
您必须使用DrawImage方法的不同重载:

e.Graphics.DrawImage(bitmap, new Rectangle(0, 0, width, height));