C#实现图片的缩放

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
//====================================================
//| Downloaded From                                  |
//| Visual C# Kicks - http://www.vcskicks.com/       |
//| License - http://www.vcskicks.com/license.html   |
//====================================================
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;

namespace ImageZoom
{
    public partial class Form1 : Form
    {
        private Rectangle selectedArea;
        private Image loadedImage;
        private Image thumbnail;
        private Color selectionColor;

        public Form1()
        {
            InitializeComponent();

            //the zoom area in the thumbnail
            selectedArea = new Rectangle(0, 0, 40, 20);
        }

        private void btnOpen_Click(object sender, EventArgs e)
        {
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                if (loadedImage != null)
                {
                    loadedImage.Dispose();
                    thumbnail.Dispose();
                }
                try
                {
                    loadedImage = Image.FromFile(openFileDialog1.FileName);

                    //Get a contrasting color for the image selection marker
                    using (Bitmap bmp = new Bitmap(loadedImage))
                    {
                        selectionColor = GetDominantColor(bmp, false);
                        selectionColor = CalculateOppositeColor(selectionColor);
                    }

                    tZoom.Value = 1;

                    resizePictureArea();
                    updateZoom();
                }
                catch (Exception)
                {
                    MessageBox.Show("Invalid image");
                }               
            }

            picSmall.Invalidate();
        }

        /// <summary>
        /// Stretches out a selected zoom area of an image
        /// </summary>
        private Image ZoomImage(Image input, Rectangle zoomArea, Rectangle sourceArea)
        {
            Bitmap newBmp = new Bitmap(sourceArea.Width, sourceArea.Height);

            using (Graphics g = Graphics.FromImage(newBmp))
            {
                //high interpolation
                g.InterpolationMode = InterpolationMode.HighQualityBicubic;

                g.DrawImage(input, sourceArea, zoomArea, GraphicsUnit.Pixel);
            }

            return newBmp;
        }

        /// <summary>
        /// Draws the selection rectangle on an image
        /// </summary>
        private Image MarkImage(Image input, Rectangle selectedArea, Color selectColor)
        {
            Bitmap newImg = new Bitmap(input.Width, input.Height);

            using (Graphics g = Graphics.FromImage(newImg))
            {
                //Prevent using images internal thumbnail
                input.RotateFlip(RotateFlipType.Rotate180FlipNone);
                input.RotateFlip(RotateFlipType.Rotate180FlipNone);

                g.DrawImage(input, 0, 0);

                //Draw the selection rect
                using (Pen p = new Pen(selectColor))
                    g.DrawRectangle(p, selectedArea);
            }

            return (Image)newImg;
        }

        /// <summary>
        /// Resizes an image
        /// </summary>
        private Image ResizeImage(Image input, Size newSize, InterpolationMode interpolation)
        {
            Bitmap newImg = new Bitmap(newSize.Width, newSize.Height);

            using (Graphics g = Graphics.FromImage(newImg))
            {
                //Prevent using images internal thumbnail
                input.RotateFlip(RotateFlipType.Rotate180FlipNone);
                input.RotateFlip(RotateFlipType.Rotate180FlipNone);

                //Interpolation
                g.InterpolationMode = interpolation;

                //Draw the image with the new dimensions
                g.DrawImage(input, 0, 0, newSize.Width, newSize.Height);
            }

            return (Image)newImg;
        }

        /// <summary>
        /// Returns the dominant color of an image
        /// </summary>
        private Color GetDominantColor(Bitmap bmp, bool includeAlpha)
        {
            // GDI+ still lies to us - the return format is BGRA, NOT ARGB.
            BitmapData bmData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height),
                                           ImageLockMode.ReadWrite,
                                           PixelFormat.Format32bppArgb);

            int stride = bmData.Stride;
            IntPtr Scan0 = bmData.Scan0;

            int r = 0;
            int g = 0;
            int b = 0;
            int a = 0;
            int total = 0;

            unsafe
            {
                byte* p = (byte*)(void*)Scan0;

                int nOffset = stride - bmp.Width * 4;
                int nWidth = bmp.Width;

                for (int y = 0; y < bmp.Height; y++)
                {
                    for (int x = 0; x < nWidth; x++)
                    {
                        r += p[0];
                        g += p[1];
                        b += p[2];
                        a += p[3];

                        total++;

                        p += 4;
                    }
                    p += nOffset;
                }
            }

            bmp.UnlockBits(bmData);

            r /= total;
            g /= total;
            b /= total;
            a /= total;

            if (includeAlpha)
                return Color.FromArgb(a, r, g, b);
            else
                return Color.FromArgb(r, g, b);
        }

        /// <summary>
        /// Calculates the opposite color of a given color.
        /// Source: http://dotnetpulse.blogspot.com/2007/01/function-to-calculate-opposite-color.html
        /// </summary>
        /// <param name="clr"></param>
        /// <returns></returns>
        private Color CalculateOppositeColor(Color clr)
        {
            return Color.FromArgb(255 - clr.R, 255 - clr.G, 255 - clr.B);
        }

        /// <summary>
        /// Constricts a set of given dimensions while keeping aspect ratio.
        /// </summary>
        private Size ShrinkToDimensions(int originalWidth, int originalHeight, int maxWidth, int maxHeight)
        {
            int newWidth = 0;
            int newHeight = 0;

            if (originalWidth >= originalHeight)
            {
                //Match area width to max width
                if (originalWidth <= maxWidth)
                {
                    newWidth = originalWidth;
                    newHeight = originalHeight;
                }
                else
                {
                    newWidth = maxWidth;
                    newHeight = originalHeight * maxWidth / originalWidth;
                }
            }
            else
            {
                //Match area height to max height
                if (originalHeight <= maxHeight)
                {
                    newWidth = originalWidth;
                    newHeight = originalHeight;
                }
                else
                {
                    newWidth = originalWidth * maxHeight / originalHeight;
                    newHeight = maxHeight;
                }
            }

            return new Size(newWidth, newHeight);
        }

        private void resizePictureArea()
        {
            //Create a thumbnail image (maintaining aspect ratio)

            Size newSize = ShrinkToDimensions(loadedImage.Width, loadedImage.Height, 160, 130);

            //use low interpolation
            thumbnail = ResizeImage(loadedImage, new Size(newSize.Width, newSize.Height), InterpolationMode.Low);

            picSmall.Invalidate();
        }

        private void updateZoom()
        {
            if (loadedImage != null)
            {
                //Map the area selected in the thumbail to the actual image size
                Rectangle zoomArea = new Rectangle();
                zoomArea.X = selectedArea.X * loadedImage.Width / thumbnail.Width;
                zoomArea.Y = selectedArea.Y * loadedImage.Height / thumbnail.Height;
                zoomArea.Width = selectedArea.Width * loadedImage.Width / thumbnail.Width;
                zoomArea.Height = selectedArea.Height * loadedImage.Height / thumbnail.Height;

                //Adjust the selected area to the current zoom value
                zoomArea.Width /= tZoom.Value;
                zoomArea.Height /= tZoom.Value;

                picZoom.Image = ZoomImage(loadedImage, zoomArea, picZoom.ClientRectangle);
                picZoom.Refresh();
            }
        }

        private void picSmall_Paint(object sender, PaintEventArgs e)
        {
            if (loadedImage != null)
            {
                //Adjust the selected area to reflect the zoom value
                Rectangle adjustedArea = new Rectangle();
                adjustedArea.X = selectedArea.X;
                adjustedArea.Y = selectedArea.Y;
                adjustedArea.Width = selectedArea.Width / tZoom.Value;
                adjustedArea.Height = selectedArea.Height / tZoom.Value;

                //Draw the selected area on the thumbnail
                picSmall.Image = MarkImage(thumbnail, adjustedArea, selectionColor);
            }
        }

        private void picSmall_Click(object sender, EventArgs e)
        {
            //Update the selected area when the user clicks on the thumbnail
            Point mouseLoc = picSmall.PointToClient(Cursor.Position);

            selectedArea.X = mouseLoc.X - ((selectedArea.Width / tZoom.Value) / 2);
            selectedArea.Y = mouseLoc.Y - ((selectedArea.Height / tZoom.Value) / 2);

            //Bound the box to the picture area bounds
            if (selectedArea.Left < 0)
                selectedArea.X = 0;
            else if (selectedArea.Right > picSmall.Width)
                selectedArea.X = picSmall.Width - selectedArea.Width - 1;

            if (selectedArea.Top < 0)
                selectedArea.Y = 0;
            else if (selectedArea.Bottom > picSmall.Height)
                selectedArea.Y = picSmall.Height - selectedArea.Height - 1;

            picSmall.Invalidate();
            updateZoom();
        }

        private void tValue_Scroll(object sender, EventArgs e)
        {
            updateZoom();
        }

        private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            System.Diagnostics.Process.Start("http://www.vcskicks.com/");
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值