C#把图像处理为正方形图像

摘要
在C#的winform平台上利用基于GDI底层图形引擎(WPF是DirectX图形引擎,效率更高,该代码再WPF上不适用)的操作进行图像的大小处理,转化为自定义像素的正方形图像。

一 基本界面及代码

1.图形界面

正方形图像转换

2.界面代码

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

namespace ToSquareImage2
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        Image ima_;
        int pixelSize;
        private void btnOpen_Click(object sender, EventArgs e)
        {
            OpenFileDialog fd = new OpenFileDialog();
            fd.Filter = "请选择图片|*.GIF;*.BMP;*.JPG;*.PNG";
            if (fd.ShowDialog() == DialogResult.OK)
            {
                string path = fd.FileName;
                Image ima = Image.FromFile(path);
                ima_ = ima;
                pictureBox1.Image = ima;
            }

        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            bool canBeParsed = int.TryParse(textBox1.Text, out pixelSize);
            if (canBeParsed)
            {
                pixelSize = int.Parse(textBox1.Text);
                SaveFileDialog sf = new SaveFileDialog();
                sf.Filter = ".jpg|*.JPG";
                if (sf.ShowDialog() == DialogResult.OK)
                {
                    string path = sf.FileName;
                    Transform.Class3.MakeSquareImage(ima_, path, pixelSize);
                    if (path != "")
                    {
                        MessageBox.Show("保存成功");
                    }
                    else
                    {
                        MessageBox.Show("保存失败");
                    }
                }
            }
            else
            {
                MessageBox.Show("边长设置有误!");
            }
        }
    }
}

3.函数代码

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;

namespace Transform
{
    /// <summary>
    /// 制作小正方形
    /// </summary>
    class Class3
    {
        /// <summary>
        /// 保存图片
        /// </summary>
        /// <param name="image">Image 对象</param>
        /// <param name="savePath">保存路径</param>
        /// <param name="ici">指定格式的编解码参数</param>
        private static void SaveImage(Image image, string savePath, ImageCodecInfo ici)
        {
            //设置 原图片 对象的 EncoderParameters 对象
            EncoderParameters parameters = new EncoderParameters(1);
            parameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, ((long)100));
            image.Save(savePath, ici, parameters);
            parameters.Dispose();
        }

        /// <summary>
        /// 获取图像编码解码器的所有相关信息
        /// </summary>
        /// <param name="mimeType">包含编码解码器的多用途网际邮件扩充协议 (MIME) 类型的字符串</param>
        /// <returns>返回图像编码解码器的所有相关信息</returns>
        private static ImageCodecInfo GetCodecInfo(string mimeType)
        {
            ImageCodecInfo[] CodecInfo = ImageCodecInfo.GetImageEncoders();
            foreach (ImageCodecInfo ici in CodecInfo)
            {
                if (ici.MimeType == mimeType)
                    return ici;
            }
            return null;
        }

        /// <summary>
        /// 计算新尺寸
        /// </summary>
        /// <param name="width">原始宽度</param>
        /// <param name="height">原始高度</param>
        /// <param name="maxWidth">最大新宽度</param>
        /// <param name="maxHeight">最大新高度</param>
        /// <returns></returns>
        private static Size ResizeImage(int width, int height, int maxWidth, int maxHeight)
        {
            if (maxWidth <= 0)
                maxWidth = width;
            if (maxHeight <= 0)
                maxHeight = height;
            decimal MAX_WIDTH = (decimal)maxWidth;
            decimal MAX_HEIGHT = (decimal)maxHeight;
            decimal ASPECT_RATIO = MAX_WIDTH / MAX_HEIGHT;

            int newWidth, newHeight;
            decimal originalWidth = (decimal)width;
            decimal originalHeight = (decimal)height;

            if (originalWidth > MAX_WIDTH || originalHeight > MAX_HEIGHT)
            {
                decimal factor;
                // determine the largest factor 
                if (originalWidth / originalHeight > ASPECT_RATIO)
                {
                    factor = originalWidth / MAX_WIDTH;
                    newWidth = Convert.ToInt32(originalWidth / factor);
                    newHeight = Convert.ToInt32(originalHeight / factor);
                }
                else
                {
                    factor = originalHeight / MAX_HEIGHT;
                    newWidth = Convert.ToInt32(originalWidth / factor);
                    newHeight = Convert.ToInt32(originalHeight / factor);
                }
            }
            else
            {
                newWidth = width;
                newHeight = height;
            }
            return new Size(newWidth, newHeight);
        }

        /// <summary>
        /// 得到图片格式
        /// </summary>
        /// <param name="name">文件名称</param>
        /// <returns></returns>
        public static ImageFormat GetFormat(string name)
        {
            string ext = name.Substring(name.LastIndexOf(".") + 1);
            switch (ext.ToLower())
            {
                case "jpg":
                case "jpeg":
                    return ImageFormat.Jpeg;
                case "bmp":
                    return ImageFormat.Bmp;
                case "png":
                    return ImageFormat.Png;
                case "gif":
                    return ImageFormat.Gif;
                default:
                    return ImageFormat.Jpeg;
            }
        }


        /// <summary>
        /// 制作小正方形
        /// </summary>
        /// <param name="image">图片对象</param>
        /// <param name="newFileName">新地址</param>
        /// <param name="newSize">长度或宽度</param>
        public static void MakeSquareImage(Image image, string newFileName, int newSize)
        {
            //获取最短边
            int i = 0;
            int width = image.Width;
            int height = image.Height;
            if (width > height)
                i = height;
            else
                i = width;

            //构造位图
            Bitmap b = new Bitmap(newSize, newSize);

            try
            {
                Graphics g = Graphics.FromImage(b);
                //设置高质量插值法
                g.InterpolationMode = InterpolationMode.HighQualityBicubic;
                //设置高质量,低速度呈现平滑程度
                g.SmoothingMode = SmoothingMode.AntiAlias;
                g.PixelOffsetMode = PixelOffsetMode.HighQuality;
                //清除整个绘图面并以透明背景色填充
                g.Clear(Color.Transparent);
                if (width < height)
                    g.DrawImage(image, new Rectangle(0, 0, newSize, newSize), new Rectangle(0, (height - width) / 2, width, width), GraphicsUnit.Pixel);
                else
                    g.DrawImage(image, new Rectangle(0, 0, newSize, newSize), new Rectangle((width - height) / 2, 0, height, height), GraphicsUnit.Pixel);

                SaveImage(b, newFileName, GetCodecInfo("image/" + GetFormat(newFileName).ToString().ToLower()));
            }
            finally
            {
                image.Dispose();
                b.Dispose();
            }
        }

        /// <summary>
        /// 制作小正方形
        /// </summary>
        /// <param name="fileName">图片文件名</param>
        /// <param name="newFileName">新地址</param>
        /// <param name="newSize">长度或宽度</param>
        public static void MakeSquareImage(string fileName, string newFileName, int newSize)
        {
            MakeSquareImage(Image.FromFile(fileName), newFileName, newSize);
        }
    }
}

二 思路及代码解释

1.文件操作部分

文件读取

            OpenFileDialog fd = new OpenFileDialog();
            fd.Filter = "请选择图片|*.GIF;*.BMP;*.JPG;*.PNG";
            if (fd.ShowDialog() == DialogResult.OK)
            {
                string path = fd.FileName;
                Image ima = Image.FromFile(path);
                ima_ = ima;
                pictureBox1.Image = ima;
            }

这里是使用了OpenFileDialog这个打开文件对话框类
这个类的常用属性

常用属性属性说明
Filter确定对话框中显示的文件类型
InitialDirectory对话框显示的初始目录
FileName选定文件的完整路径
SafeFileName仅包含文件的文件名(包含后缀)

文件保存

            bool canBeParsed = int.TryParse(textBox1.Text, out pixelSize);
            if (canBeParsed)
            {
                pixelSize = int.Parse(textBox1.Text);
                SaveFileDialog sf = new SaveFileDialog();
                sf.Filter = ".jpg|*.JPG";
                if (sf.ShowDialog() == DialogResult.OK)
                {
                    string path = sf.FileName;
                    Transform.Class3.MakeSquareImage(ima_, path, pixelSize);
                    if (path != "")
                    {
                        MessageBox.Show("保存成功");
                    }
                    else
                    {
                        MessageBox.Show("保存失败");
                    }
                }
            }
            else
            {
                MessageBox.Show("边长设置有误!");
            }

上面仅为界面元素的文件保存对话框代码,目的仅仅是为了获得保存文件的路径,然后传入处理方法内,再进行真正的文件保存,真正的保存文件代码如下:

        /// <summary>
        /// 保存图片
        /// </summary>
        /// <param name="image">Image 对象</param>
        /// <param name="savePath">保存路径</param>
        /// <param name="ici">指定格式的编解码参数</param>
        private static void SaveImage(Image image, string savePath, ImageCodecInfo ici)
        {
            //设置 原图片 对象的 EncoderParameters 对象
            EncoderParameters parameters = new EncoderParameters(1);
            parameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, ((long)100));
            image.Save(savePath, ici, parameters);
            parameters.Dispose();
        }

图片Image类中有一个save的方法可以用来保存图片

2.函数代码部分

函数名说明
MakeSquareImage通过对最短边的获取,然后创建自定义大小的位图,最后再利用Graphics类里面的DrawImage方法进行绘制(该方法不适用与WPF),绘制完成直接保存
GetFormat在保存图片的时候需要获取格式,用SubString方法以及LastIndexOf方法可以快速获取,最后结合switch进行匹配,返回相应的格式
ResizeImage暂时用不到
GetCodecInfo获取图像编码器解码的相关信息,保存图像需要用到
SaveImage保存图像

GitHub代码
https://github.com/Mushano/C-ImageTransformToSquare

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值