1、需求分析

用winform窗体程序,开发一个能够自动、批量对图片进行缩放和裁剪的程序。

原本想直接从网上找类型的工具直接用,但是无奈现在网上能找到的工具,要么不能用,要么就是很

恶心的下载完后还有一堆插件的,要么就是我用不来的。

这个程序是我根据个人需求,想要把所有拍好的人像照,直接批处理成1寸的照片,就能省去很多裁剪图片的时间。

这里要对生成的1寸图片做个说明:1寸图片我网上查到的大小是:照片规格(英寸) (厘米) (像素)

  1寸 2.5*3.5cm 413*295

由于在拍摄时可能存在横拍和竖拍,所以生成后图片虽然也是1寸的,但是方向不一样,这个不影响,还可以根据需求在代码中修改。

先看效果:

可以看出缩放图片后,图片的质量也会随之变低,而裁剪则不会有这个问题。

2、图片裁剪代码

      /// <summary>
/// 裁剪按钮
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Button1_Click(object sender, EventArgs e)
{
OpenFileDialog dialog = new OpenFileDialog(); //打开文件夹,选择图片
dialog.Filter = "(*.jpg,*.png,*.jpeg,*.bmp,*.gif)|*.jgp;*.png;*.jpeg;*.bmp;*.gif;*.JPG;*.PNG;|All files(*.*)|*.*";
dialog.Multiselect = true;
if (dialog.ShowDialog() == DialogResult.OK)
{
string path = dialog.FileName;
Bitmap img = new Bitmap(path);
Image img2 = ImageTailor(img, , ); //设置大小为1寸照片
string imgSaveUrl = @"D:/我的图片/处理完成/" + dialog.SafeFileName; //保存图片到文件夹
img2.Save(imgSaveUrl);
img2.Dispose(); //释放资源
}
} public Image ImageTailor(Bitmap bmp,int nowWidth,int nowHeight)
{
Bitmap newbm = new Bitmap(nowWidth, nowHeight);
Graphics g = Graphics.FromImage(newbm);
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.SmoothingMode = SmoothingMode.HighQuality;
g.CompositingQuality = CompositingQuality.HighQuality;
//前Rectangle代表画布大小,后Rectangle代表裁剪后右边留下的区域
g.DrawImage(bmp, new Rectangle(, , nowWidth, nowHeight), new Rectangle(, , bmp.Width / , bmp.Height), GraphicsUnit.Pixel);
g.Dispose();
return newbm;
}

裁剪按钮方法还没完善好,目前只完成了单张图片的裁剪。要想修改成批量的,只需在openfiledialog控件设置成允许多选,然后根据选中的图片数量进行循环处理,就可以了。

后面的缩放按钮是比较完善的,可以允许多选图片,并进行批处理。

3、图片缩放代码:

缩放图片的代码看起来会比较复杂些,但是逻辑并不难。一些代码也是在网上看其他人写的,拿过来用(那个“中间件确实是自己写着玩的,懒得改回去,哈哈”)

  1      /// <summary>
/// 显示图片
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Button_SelectImg_Click(object sender, EventArgs e)
{
OpenFileDialog dialog = new OpenFileDialog();
dialog.Filter = "(*.jpg,*.png,*.jpeg,*.bmp,*.gif)|*.jgp;*.png;*.jpeg;*.bmp;*.gif;*.JPG;*.PNG;|All files(*.*)|*.*";
dialog.Multiselect = true; //允许文件多选
string folder = "";
if (Directory.Exists(@"D:/我的图片/处理完成/"))
{
folder = @"D:/我的图片/处理完成/";
}
else
{
Directory.CreateDirectory(@"D:/我的图片/处理完成/");
folder = @"D:/我的图片/处理完成/";
}
if (dialog.ShowDialog() == DialogResult.OK)
{
int fileCount = dialog.FileNames.Length; //获取选中图片数量
int countNum = fileCount;
for (int i = ; i < fileCount; i++)
{
string path = dialog.FileNames[i]; //图片绝对路径,包含图片名称
Image img = GetReducedImage(path);
string imgSaveUrl = folder + dialog.SafeFileNames[i]; //保存图片到文件夹
img.Save(imgSaveUrl);
img.Dispose(); //释放资源
countNum--;
if (countNum == )
{
MessageBox.Show("处理图片完成,总计处理:" + fileCount + "张");
}
}
}
} /// <summary>
/// 中间件,写着玩
/// </summary>
/// <param name="fileName"></param>
/// <returns></returns>
public Image GetReducedImage(string fileName)
{
Image ResourceImage = Image.FromFile(fileName);
Bitmap img = new Bitmap(ResourceImage);
return ZoomImage(img, , );
} #region 等比例缩放图片
/// <summary>
/// 等比例缩放图片
/// </summary>
/// <param name="bitmap"></param>
/// <param name="destHeight"></param>
/// <param name="destWidth"></param>
/// <returns></returns>
private Bitmap ZoomImage(Bitmap bitmap, int destHeight, int destWidth)
{
try
{
Image sourImage = bitmap;
ImageCodecInfo ici = GetEncoder(ImageFormat.Jpeg);
int width = , height = ;
//按比例缩放
int sourWidth = sourImage.Width;
int sourHeight = sourImage.Height;
if (sourHeight > destHeight || sourWidth > destWidth)
{
if ((sourWidth * destHeight) > (sourHeight * destWidth))
{
width = destWidth;
height = (destWidth * sourHeight) / sourWidth;
}
else
{
height = destHeight;
width = (sourWidth * destHeight) / sourHeight;
}
}
else
{
width = sourWidth;
height = sourHeight;
}
Bitmap destBitmap = new Bitmap(destWidth, destHeight);
Graphics g = Graphics.FromImage(destBitmap);
g.Clear(Color.Transparent);
//设置画布的描绘质量
g.CompositingQuality = CompositingQuality.HighQuality;
g.SmoothingMode = SmoothingMode.HighQuality;
g.InterpolationMode = InterpolationMode.HighQualityBilinear;
g.DrawImage(sourImage, new Rectangle((destWidth - width) / , (destHeight - height) / , width, height), , , sourImage.Width, sourImage.Height, GraphicsUnit.Pixel);
g.Dispose();
//设置压缩质量
EncoderParameters encoderParams = new EncoderParameters();
long[] quality = new long[];
quality[] = ;
EncoderParameter encoderParam = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality);
encoderParams.Param[] = encoderParam;
sourImage.Dispose();
return destBitmap;
}
catch
{
return bitmap;
}
}
#endregion public static ImageCodecInfo GetEncoder(ImageFormat format)
{
ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders();
foreach (ImageCodecInfo codec in codecs)
{
if (codec.FormatID == format.Guid)
{
return codec;
}
}
return null;
}

4、总结:

以上,就完成了简单的图片批量缩放(裁剪)成1寸图片的功能。

C#开发自动照片(图片)裁剪(缩放)工具的更多相关文章

  1. 如何安装nginx_lua_module模块,升级nginx,nginx-lua-fastdfs-GraphicsMagick动态生成缩略图,实现图片自动裁剪缩放

    如何安装nginx_lua_module模块,升级nginx,nginx-lua-fastdfs-GraphicsMagick动态生成缩略图,实现图片自动裁剪缩放 参考网站:nginx-lua-fas ...

  2. web开发实战--图片裁剪和上传

    前言: 最近的开发中, 有一个上传头像的任务. 由于头像本身的特殊性, 其一般流程为选择图片, 编辑裁剪区域, 再继而上传图片操作. 看似简单的东西, 实则是挺麻烦的一件事. 借助这次开发机会, 来具 ...

  3. 鸿蒙Java开发模式11:鸿蒙图片裁剪功能的实现

    鸿蒙入门指南,小白速来!从萌新到高手,怎样快速掌握鸿蒙开发?[课程入口] 目录: 1. 鸿蒙版图片裁剪功能效果展示 2.Java代码实现 3.裁剪工具类实现 4.<鸿蒙Java开发模式>系 ...

  4. PHP图片裁剪_图片缩放_PHP生成缩略图

    在制作网页过程中,为了排版整齐美观,对网页中的图片处理成固定大小尺寸的图片,或是要截去图片边角中含有水印的图片,对于图片量多,每天更新大量图,靠人工PS处理是不现实的,那么有没有自动处理图片的程序了! ...

  5. iOS 仿看了吗应用、指南针测网速等常用工具、自定义弹出视图框架、图片裁剪、内容扩展等源码

    iOS精选源码 扩展内容的cell - folding-cell 一个近乎完整的可识别中国身份证信息的Demo 可自动快速... JPImageresizerView 仿微信的图片裁剪 带年月和至今以 ...

  6. C#图片处理示例(裁剪,缩放,清晰度,水印)

    C#图片处理示例(裁剪,缩放,清晰度,水印) 吴剑 2011-02-20 原创文章,转载必需注明出处:http://www.cnblogs.com/wu-jian/ 前言 需求源自项目中的一些应用,比 ...

  7. C#图片处理高级应用(裁剪,缩放,清晰度,水印)

    转自:http://wu-jian.cnblogs.com/ 前言 需求源自项目中的一些应用,比如相册功能,通常用户上传相片后我们都会针对该相片再生成一张缩略图,用于其它页面上的列表显示.随便看一下, ...

  8. Android开发技巧——定制仿微信图片裁剪控件

    拍照--裁剪,或者是选择图片--裁剪,是我们设置头像或上传图片时经常需要的一组操作.上篇讲了Camera的使用,这篇讲一下我对图片裁剪的实现. 背景 下面的需求都来自产品. 裁剪图片要像微信那样,拖动 ...

  9. 使用PHP的GD2裁剪 + 缩放图片

    /** * 裁剪 + 缩放图片 * @param array $params 包含x,y,width,height,path * @return string */ public function t ...

随机推荐

  1. python基础—条件语句

    一.Python基础 1.第一句python print('hello,world') Q: 后缀名可以任意? A:  导入模块时,如果不是.py后缀,会出错. 2.两种执行的方式: -python解 ...

  2. PLSQL 12 安装、连接Oracle

    点击下载PLSQL,本次安装的PLSQL版本为12.0.7,建议安装64位. 下载PLSQL时,版本旁边会有个“Language pack”的链接,点击后左侧选择“Chinese”即可下载汉化包. 注 ...

  3. 高强度学习训练第九天总结:5道剑指offer的题目

    实在不想看JVM了.刷几道剑指Offer的题,今天就水一水吧,脑子迷糊. 1.二维数组中的查找 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增 ...

  4. Spring 注解配置Bean

    一.使用注解配置Bean 1.注解 在类定义.方法定义.成员变量定义前使用.其简化<bean>标签,功能同<bean>标签.格式为: @注解标记名. 2.组件扫描 Spring ...

  5. Typescript基础(3)——类

    前言 今天继续typescript的学习,开始ts类的学习. 类 类的实现 在ES6中新增了类的概念.我们先看ES6中类的实现. class Person { constructor(name,age ...

  6. 生成前N个自然数随机置换的3个程序

    问题描述: 假设需要生成前N个自然数的一个随机置换.例如,{4,3,1,5,2}和{3,1,4,2,5}就是合法的置换,但{5,4,1,2,1}却不是,因为数1出现两次而数3却没有.这个程序常常用于模 ...

  7. [Go] golang实现mysql连接池

    golang中连接mysql数据库,需要使用一个第三方类库github.com/go-sql-driver/mysql,在这个类库中就实现了mysql的连接池,并且只需要设置两个参数就可以实现 一般连 ...

  8. ACM-ICPC 2018 南京赛区网络预赛 I. Skr(回文树)

    题意 https://nanti.jisuanke.com/t/A1955 求所有本质不同的回文串转成数后的和. 思路 如果了解回文树的构造原理,那么这题就很简单了,回文树每个结点代表一个回文串,每添 ...

  9. python简单面试题

    在这个即将进入金9银10的跳槽季节的时候,肯定需要一波面试题了,安静总结了一些经常遇到的python面试题,让我们一起撸起来. python面试题 1.求出1-100之间的和 # coidng:utf ...

  10. C学习笔记(7)--- typedef,输入输出

    1.typedef: C 语言提供了 typedef 关键字,您可以使用它来为类型(type)取一个新的名字. 比如: typedef unsigned char BYTE; 然后你就可以把BYTE当 ...