1数据的存取方式
1.1数据库存取:适合大量且关系复杂并有序的数据存取
1.2文件存取:适合大量且数据关系简单的数据存取,如软件的日志文件等
2文件存取的好处
读取操作方便
文件可以存取在任何介质中
3文件存取的方式:流对象
4代码
1 string path_Debug = Directory.GetCurrentDirectory();
1 //【1】创建文件流
2 FileStream fs = new FileStream(path_Debug+"\\myfile.txt", FileMode.Create);
3 //【2】创建写入器
4 StreamWriter sw = new StreamWriter(fs);
5 //【3】以流的方式写入数据
6 sw.Write(this.tb_Content.Text.Trim());
7 //【4】关闭写入器
8 sw.Close();
9 //【5】关闭文件流
10 fs.Close();
1 //【1】创建文件流
2 FileStream fs = new FileStream(path_Debug+"\\myfile.txt", FileMode.Open);
3 //【2】创建读取器
4 StreamReader sr = new StreamReader(fs);
5 //【3】以流的方式读取数据
6 this.tb_Content.Text = sr.ReadToEnd();
7 //【4】关闭读取器
8 sr.Close();
9 //【5】关闭文件流
10 fs.Close();
1 //【1】创建文件流(文件模式为:追加)
2 FileStream fs = new FileStream(path_Debug+"\\myfile.txt", FileMode.Append);
3 //【2】创建写入器
4 StreamWriter sw = new StreamWriter(fs);
5 //【3】以流的方式“逐行”写入数据
6 sw.WriteLine(DateTime.Now.ToString() + " 文件操作正常!");
7 //【4】关闭写入器
8 sw.Close();
9 //【5】关闭文件流
10 fs.Close();
1 File.Delete(this.txtFrom.Text.Trim());
1 if (File.Exists(this.txtTo.Text.Trim())) //首先判断文件是否存在(如果文件存在,直接复制会出现错误)
2 {
3 File.Delete(this.txtTo.Text.Trim());//删除文件
4 }
5 File.Copy(this.txtFrom.Text.Trim(), this.txtTo.Text.Trim()); //复制文件
1 //首先判断目标路径文件是否存在(如果文件存在,直接复制会出现错误)
2 if (File.Exists(this.txtTo.Text.Trim()))
3 {
4 File.Delete(this.txtTo.Text.Trim());//删除文件
5 }
6 if (File.Exists(this.txtFrom.Text.Trim()))//如果当前文件存在则移动
7 {
8 //移动文件
9 File.Move(this.txtFrom.Text.Trim(), this.txtTo.Text.Trim());
10 }
11 else
12 {
13 MessageBox.Show("文件不存在!");
14 }
1 string[] files = Directory.GetFiles(path_Debug);
2 this.tb_Content.Clear();
3 foreach (string item in files)
4 {
5 this.tb_Content.Text += item + "\r\n";
6 }
1 string[] dirs = Directory.GetDirectories(path_Debug);
2 this.tb_Content.Clear();
3 foreach (string item in dirs)
4 {
5 this.tb_Content.Text += item + "\r\n";
6 }
1 Directory.CreateDirectory(path_Debug+"\\Myfiles\\newfiles");
1 Directory.Delete("C:\\Myfiles");//要求目录必须为空
2 //使用DirectoryInfo对象,可以删除不为空的目录
3 DirectoryInfo dir = new DirectoryInfo(path_Debug + "\\Myfiles");
4 dir.Delete(true);
1 /// <summary>
2 /// 复制目录下的所有子目录及文件(递归)
3 /// </summary>
4 /// <param name="Source">源目录</param>
5 /// <param name="Goal">新目录</param>
6 public static void copyDirectory(string Source, string Goal)
7 {
8 String[] Files;
9 if (Goal[Goal.Length - 1] != Path.DirectorySeparatorChar)
10 {
11 Goal += Path.DirectorySeparatorChar;
12 }
13 if (!Directory.Exists(Goal))
14 {
15 Directory.CreateDirectory(Goal);
16 }
17 Files = Directory.GetFileSystemEntries(Source);
18 foreach (string Element in Files)
19 {
20 if (Directory.Exists(Element))
21 copyDirectory(Element, Goal + Path.GetFileName(Element));
22 else System.IO.File.Copy(Element, Goal + Path.GetFileName(Element), true);
23 }
24 }
1 DirectoryInfo dir_Images = new DirectoryInfo(sPath);
2 DirectoryInfo[] DirImages = dir_Images.GetDirectories();
3 Dictionary<DirectoryInfo, DateTime> DirCreateDate = new Dictionary<DirectoryInfo, DateTime>();
4 for (int i = 0; i < DirImages.Length; i++)
5 {
6 DirectoryInfo fi = new DirectoryInfo(DirImages[i].FullName);
7 DirCreateDate[DirImages[i]] = fi.CreationTime;
8 }
9 DirCreateDate = DirCreateDate.OrderBy(f => f.Value).ToDictionary(f => f.Key, f => f.Value);
10 int m = 0;
11 foreach (KeyValuePair<DirectoryInfo, DateTime> item in DirCreateDate)
12 {
13 if (m == 0)
14 {//对最先保存的图像给予删除。在这里尝试了隔月和隔年的特殊情况,暂无意外
15 item.Key.Delete(true);
16 }
17 m++;
18 if (m > 1)
19 {
20 string[] name = item.Key.Name.Split('-');
21 if (name.Length != 4)
22 {//对文件夹不满足默认格式的文件给予删除
23 item.Key.Delete(true);
24 }
25 }
26 }
if (!Directory.Exists(LogPath))//检测文件夹是否存在
{
}
DirectoryInfo directoryInfo = Directory.CreateDirectory(LogPath);//一次性创建全部的子路径
Directory.Move(LogPath, LogMovePath);//移动 原文件夹就不在了
Directory.Delete(LogMovePath);//删除
//DirectoryInfo不存在不报错 注意exists属性
Directory.CreateDirectory(LogPath);//创建文件的前提是文件所在文件夹必须事先存在,否则会报错
//创建文本文件的几种方式
using (FileStream fileStream = File.Create(fileName))
{
string name = "12345567778890";
byte[] bytes = Encoding.Default.GetBytes(name);
fileStream.Write(bytes, 0, bytes.Length);
fileStream.Flush();
}
using (FileStream fileStream = File.Create(fileName))
{
StreamWriter sw = new StreamWriter(fileStream);
sw.WriteLine("1234567890");
sw.Flush();
}
using (StreamWriter sw = File.AppendText(fileName))
{
string msg = "今天是Course6IOSerialize,今天上课的人有55个人";
sw.WriteLine(msg);
sw.Flush();
}
using (StreamWriter sw = File.AppendText(fileName))
{
string name = "0987654321";
byte[] bytes = Encoding.Default.GetBytes(name);
sw.BaseStream.Write(bytes, 0, bytes.Length);
sw.Flush();
}
//一次性将文本文件读入到内存的几种方式,适合小文件,如果文件太大不见这样操作
foreach (string result in File.ReadAllLines(fileName))
{
Console.WriteLine(result);
}
string sResult = File.ReadAllText(fileName);
Byte[] byteContent = File.ReadAllBytes(fileName);
string sResultByte = Encoding.UTF8.GetString(byteContent);
//分批读取
using (FileStream stream = File.OpenRead(fileName))//分批读取
{
int length = 5;
int result = 0;
do
{
byte[] bytes = new byte[length];
result = stream.Read(bytes, 0, 5);
for (int i = 0; i < result; i++)
{
Console.WriteLine(bytes[i].ToString());
}
}
while (length == result);
}
File.Copy(fileName, fileNameCopy);
File.Move(fileName, fileNameMove);
File.Delete(fileNameMove);//尽量不要delete
DriveInfo[] drives = DriveInfo.GetDrives();
foreach (DriveInfo drive in drives)
{
if (drive.IsReady)
Console.WriteLine("类型:{0} 卷标:{1} 名称:{2} 总空间:{3} 剩余空间:{4}", drive.DriveType, drive.VolumeLabel, drive.Name, drive.TotalSize, drive.TotalFreeSpace);
else
Console.WriteLine("类型:{0} is not ready", drive.DriveType);
}
Console.WriteLine(Path.GetDirectoryName(LogPath)); //返回目录名,需要注意路径末尾是否有反斜杠对结果是有影响的
Console.WriteLine(Path.GetDirectoryName(@"d:\\abc")); //将返回 d:\
Console.WriteLine(Path.GetDirectoryName(@"d:\\abc\"));// 将返回 d:\abc
Console.WriteLine(Path.GetRandomFileName());//将返回随机的文件名
Console.WriteLine(Path.GetFileNameWithoutExtension("d:\\abc.txt"));// 将返回abc
Console.WriteLine(Path.GetInvalidPathChars());// 将返回禁止在路径中使用的字符
Console.WriteLine(Path.GetInvalidFileNameChars());//将返回禁止在文件名中使用的字符
Console.WriteLine(Path.Combine(LogPath, "log.txt"));//合并两个路径
private static void GetChildDirectory(List<DirectoryInfo> directoryList, DirectoryInfo directoryParent)
{
DirectoryInfo[] directoryListChild = directoryParent.GetDirectories();//一级子文件夹
if (directoryListChild != null && directoryListChild.Length > 0)//递归的跳出条件
{
directoryList.AddRange(directoryListChild);
foreach (var child in directoryListChild)
{
GetChildDirectory(directoryList, child);
}
}
}
//分批读取
using (FileStream stream = File.OpenRead(fileName))//分批读取
{
int length = 5;
int result = 0;
do
{
byte[] bytes = new byte[length];
result = stream.Read(bytes, 0, 5);
for (int i = 0; i < result; i++)
{
Console.WriteLine(bytes[i].ToString());
}
}
while (length == result);
}
5文本保存对象的不足
使用文本保存对象存在两个问题:
当对象属性变化时,增加和减少信息的写入或读取次数会很多。
信息安全性较差。
6对象序列化保存
对象序列化(Serialize)成流(stream),流可以反序列化(Deserialize)成对象。
对象序列化前的准备:
引入命名空间 using System.Runtime.Serialization.Formatters.Binary;
所要保存的类前面需要加上对象可序列化标记: [Serializable]
使用二进制格式化器
反序列化方法参数只有一个;并且返回值时object类型,需要强制转换成具体类型
7序列化与反序列化小结
序列化:内存中的对象保存到本地的文件; 反序列化:本地的文件重新转化为内存中的对象
1 [Serializable]//很重要
2 class Student
3 {
4 public string Name { get; set; }
5 public string Gender { get; set; }
6 public int Age { get; set; }
7 public DateTime Birthday { get; set; }
8 }
1 //封装对象信息
2 Student objStu = new Student()
3 {
4 Name = this.txtName.Text.Trim(),
5 Age = Convert.ToInt16(this.txtAge.Text.Trim()),
6 Gender = this.txtGender.Text.Trim(),
7 Birthday = Convert.ToDateTime(this.txtBirthday.Text.Trim())
8 };
9 //【1】创建文件流
10 FileStream fs = new FileStream("C:\\objStu.obj", FileMode.Create);
11 //【2】创建二进制格式化器
12 BinaryFormatter formatter = new BinaryFormatter();
13 //【3】调用序列化方法
14 formatter.Serialize(fs, objStu);
15 //【4】关闭文件流
16 fs.Close();
1 //【1】创建文件流
2 FileStream fs = new FileStream("C:\\objStu.obj", FileMode.Open);
3 //【2】创建二进制格式化器
4 BinaryFormatter formatter = new BinaryFormatter();
5 //【3】调用序列化方法
6 Student objStu = (Student)formatter.Deserialize(fs);
7 //【4】关闭文件流
8 fs.Close();
9 //显示对象属性
10 this.txtName.Text = objStu.Name;
11 this.txtAge.Text = objStu.Age.ToString();
12 this.txtGender.Text = objStu.Gender;
13 this.txtBirthday.Text = objStu.Birthday.ToShortDateString();
//BinaryFormatter序列化自定义类的对象时,序列化之后的流中带有空字符,以致于无法反序列化,反序列化时总是报错“在分析完成之前就遇到流结尾”(已经调用了stream.Seek(0, SeekOrigin.Begin);)。
//改用XmlFormatter序列化之后,可见流中没有空字符,从而解决上述问题,但是要求类必须有无参数构造函数,而且各属性必须既能读又能写,即必须同时定义getter和setter,若只定义getter,则反序列化后的得到的各个属性的值都为null。
应用场合:应用系统配置信息,信息量大时可用该方法方便读取和写入
需用数据库时可作为数据存取载体
模块之间数据传递
好处:对象保存和读取方便,扩张性强
数据安全高效
8什么是XML?
XML是可扩展标记语言。
可用来创建自定义的标记语言,由万维网协会(W3C)创建,用来克服HTML的局限。
XML主要用来数据的储蓄,HTML主要用来数据显示。
版本号和字符集不能修改。节点成对出现。节点区分大小写。节点可自由扩展。
9 XML文档的格式要求
确定且唯一的根元素
开始标签和结束标签匹配
元素标签的正确嵌套
属性值要用引号括起来
同一个元素的属性不能重复
10 XML语法要求
元素:<标签>文本内容</标签>
处理指令:<?xmlversion="1.0"?>
注释:<!--这是一个XML注释-->
属性:<salary curuency="USS">25000</salary>
11 XML文件读取步骤
1创建文档对象 2加载XML文档
3获取根节点 4遍历节点并封装数据
12 XML文件读取总结
常用对象:XmlDocument对象表示XML整个文档
XmlNode对象表示XML文件的单个节点
1 XmlDocument objDoc = new XmlDocument(); //【1】创建XML文档操作对象
2 objDoc.Load("StuScore.xml"); //【2】加载XML文件到文档对象中
3 XmlNode rootNode = objDoc.DocumentElement; //【3】获取XML文档根目录
4 List<Student> list = new List<Student>();//创建对象集合
5 foreach (XmlNode stuNode in rootNode.ChildNodes) //【4】遍历根节点(根节点包含所有节点)
6 {
7 if (stuNode.Name == "Student")
8 {
9 Student objStu = new Student();
10 foreach (XmlNode subNode in stuNode) //【5】遍历子节点
11 {
12 switch (subNode.Name)//根据子节点的名称封装到对象的属性
13 {
14 case "StuName":
15 objStu.StuName = subNode.InnerText;//获取《节点名称》对应的《节点值》
16 break;
17 case "StuAge":
18 objStu.StuAge = Convert.ToInt16(subNode.InnerText);
19 break;
20 case "Gender":
21 objStu.Gender = subNode.InnerText;
22 break;
23 case "ClassName":
24 objStu.ClassName = subNode.InnerText;
25 break;
26 }
27 }
28 list.Add(objStu);
29 }
30 }
31 this.dgvStuList.DataSource = list;
常用属性与说明
对象 | 属性和方法 | 说明 |
XmlDocument | DocumentElement属性 | 获取根节点 |
ChildNodes属性 | 获取所有子节点 | |
Load()方法 | 读取整个XML的结构 | |
XmlNode | InnerText属性 | 当前节点的值 |
Name属性 | 当前节点的名字 | |
ChildNodes属性 | 当前节点的所有子节点 |
13.Json
using System.Web.Script.Serialization;//System.Web.Extensions
using Newtonsoft.Json;//nuget Newtonsoft
namespace Helper
{
//【Json序列化】将一组对象降低维度为一个string字符串
//【Json反序列化】将一个string字符串增加维度转化为一组对象
public class JsonHelper
{
//System.Web.Script.Serialization序列化
public static string ObjectToString<T>(T obj)
{
JavaScriptSerializer jss = new JavaScriptSerializer();
return jss.Serialize(obj);
}
//System.Web.Script.Serialization反序列化
public static T StringToObject<T>(string content)
{
JavaScriptSerializer jss = new JavaScriptSerializer();
return jss.Deserialize<T>(content);
}
//Newtonsoft.Json序列化
public static string ToJson<T>(T obj)
{
return JsonConvert.SerializeObject(obj);
}
//Newtonsoft.Json反序列化
public static T ToObject<T>(string content)
{
return JsonConvert.DeserializeObject<T>(content);
}
}
}
{
string jResult = JsonHelper.ObjectToString<List<Programmer>>(list);
List<Programmer> list1 = JsonHelper.StringToObject<List<Programmer>>(jResult);
}
{
string jResult = JsonHelper.ToJson<List<Programmer>>(list);
List<Programmer> list1 = JsonHelper.ToObject<List<Programmer>>(jResult);
}
14.XML
using System.Xml.Serialization;
using System.IO;
namespace Helper
{
/// <summary>
/// 使用序列化器完成的
/// </summary>
public class XmlHelper
{
// XmlSerializer序列化实体为字符串
public static string ToXml<T>(T t) where T : new() //必须有无参构造函数
{
XmlSerializer xmlSerializer = new XmlSerializer(t.GetType());
Stream stream = new MemoryStream();
xmlSerializer.Serialize(stream, t);
stream.Position = 0;
StreamReader reader = new StreamReader(stream);
string text = reader.ReadToEnd();
return text;
}
// 字符串反序列化成XML
public static T ToObject<T>(string content) where T : new()
{
using (MemoryStream stream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(content)))
{
XmlSerializer xmlFormat = new XmlSerializer(typeof(T));
return (T)xmlFormat.Deserialize(stream);
}
}
/// xml文件反序列化成实体
public static T FileToObject<T>(string fileName) where T : new()
{
using (Stream fStream = new FileStream(fileName, FileMode.Open, FileAccess.ReadWrite))
{
XmlSerializer xmlFormat = new XmlSerializer(typeof(T));
return (T)xmlFormat.Deserialize(fStream);
}
}
}
}
List<Programmer> list = DataFactory.BuildProgrammerList();
{
//一堆对象序列化为xml字符串
string xmlResult = XmlHelper.ToXml<List<Programmer>>(list);
//xml字符串反序列化为一堆对象
List<Programmer> list1 = XmlHelper.ToObject<List<Programmer>>(xmlResult);
//【一个xml文件直接反序列化为一堆对象】
List<Programmer> list2 = XmlHelper.FileToObject<List<Programmer>>(fileName);
}
15.SerializeHelper
public class SerializeHelper
{
/// <summary>
/// 二进制序列化器
/// </summary>
public static void BinarySerialize()
{
//使用二进制序列化对象
string fileName = Path.Combine(Constant.SerializeDataPath, @"BinarySerialize.txt");//文件名称与路径
using (Stream fStream = new FileStream(fileName, FileMode.Create, FileAccess.ReadWrite))
{//需要一个stream,这里是直接写入文件了
List<Programmer> pList = DataFactory.BuildProgrammerList();
BinaryFormatter binFormat = new BinaryFormatter();//创建二进制序列化器
binFormat.Serialize(fStream, pList);
}
using (Stream fStream = new FileStream(fileName, FileMode.Open, FileAccess.ReadWrite))
{//需要一个stream,这里是来源于文件
BinaryFormatter binFormat = new BinaryFormatter();//创建二进制序列化器
//使用二进制反序列化对象
fStream.Position = 0;//重置流位置
List<Programmer> pList = (List<Programmer>)binFormat.Deserialize(fStream);//反序列化对象
}
}
/// <summary>
/// soap序列化器
/// </summary>
public static void SoapSerialize()
{
//使用Soap序列化对象
string fileName = Path.Combine(Constant.SerializeDataPath, @"SoapSerialize.txt");//文件名称与路径
using (Stream fStream = new FileStream(fileName, FileMode.Create, FileAccess.ReadWrite))
{
List<Programmer> pList = DataFactory.BuildProgrammerList();
SoapFormatter soapFormat = new SoapFormatter();//创建二进制序列化器
//soapFormat.Serialize(fStream, list);//SOAP不能序列化泛型对象
soapFormat.Serialize(fStream, pList.ToArray());
}
using (Stream fStream = new FileStream(fileName, FileMode.Open, FileAccess.ReadWrite))
{
SoapFormatter soapFormat = new SoapFormatter();//创建二进制序列化器
//使用二进制反序列化对象
fStream.Position = 0;//重置流位置
List<Programmer> pList = ((Programmer[])soapFormat.Deserialize(fStream)).ToList();//反序列化对象
}
}
//BinaryFormatter序列化自定义类的对象时,序列化之后的流中带有空字符,以致于无法反序列化,反序列化时总是报错“在分析完成之前就遇到流结尾”(已经调用了stream.Seek(0, SeekOrigin.Begin);)。
//改用XmlFormatter序列化之后,可见流中没有空字符,从而解决上述问题,但是要求类必须有无参数构造函数,而且各属性必须既能读又能写,即必须同时定义getter和setter,若只定义getter,则反序列化后的得到的各个属性的值都为null。
/// <summary>
/// XML序列化器
/// </summary>
public static void XmlSerialize()
{
//使用XML序列化对象
string fileName = Path.Combine(Constant.SerializeDataPath, @"XmlStudent.xml");//文件名称与路径
using (Stream fStream = new FileStream(fileName, FileMode.Create, FileAccess.ReadWrite))
{
List<Programmer> pList = DataFactory.BuildProgrammerList();
XmlSerializer xmlFormat = new XmlSerializer(typeof(List<Programmer>));//创建XML序列化器,需要指定对象的类型
xmlFormat.Serialize(fStream, pList);
}
using (Stream fStream = new FileStream(fileName, FileMode.Open, FileAccess.ReadWrite))
{
XmlSerializer xmlFormat = new XmlSerializer(typeof(List<Programmer>));//创建XML序列化器,需要指定对象的类型
fStream.Position = 0;//重置流位置
List<Programmer> pList = pList = (List<Programmer>)xmlFormat.Deserialize(fStream);
}
}
}
16.ImageHelper
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
namespace Helper
{
/// <summary>
///
/// </summary>
public class ImageHelper
{
private static string ImagePath = @"D:\软媒\课程代码+课件\20180515Advanced11Course7IOSerialize\IOSerialize\IOSerialize\bin\Debug";
private static string VerifyPath = ImagePath;
//绘图的原理很简单:Bitmap就像一张画布,Graphics如同画图的手,把Pen或Brush等绘图对象画在Bitmap这张画布上
/// <summary>
/// 画验证码
/// </summary>
public static void Drawing()
{
Bitmap bitmapobj = new Bitmap(100, 100);
//在Bitmap上创建一个新的Graphics对象
Graphics g = Graphics.FromImage(bitmapobj);
//创建绘画对象,如Pen,Brush等
Pen redPen = new Pen(Color.Red, 8);
g.Clear(Color.White);
//绘制图形
g.DrawLine(redPen, 50, 20, 500, 20);
g.DrawEllipse(Pens.Black, new Rectangle(0, 0, 200, 100));//画椭圆
g.DrawArc(Pens.Black, new Rectangle(0, 0, 100, 100), 60, 180);//画弧线
g.DrawLine(Pens.Black, 10, 10, 100, 100);//画直线
g.DrawRectangle(Pens.Black, new Rectangle(0, 0, 100, 200));//画矩形
g.DrawString("我爱北京天安门", new Font("微软雅黑", 12), new SolidBrush(Color.Red), new PointF(10, 10));//画字符串
//g.DrawImage(
if (!Directory.Exists(ImagePath))
Directory.CreateDirectory(ImagePath);
bitmapobj.Save(ImagePath + "pic1.jpg", ImageFormat.Jpeg);
//释放所有对象
bitmapobj.Dispose();
g.Dispose();
}
public static void VerificationCode()
{
Bitmap bitmapobj = new Bitmap(300, 300);
//在Bitmap上创建一个新的Graphics对象
Graphics g = Graphics.FromImage(bitmapobj);
g.DrawRectangle(Pens.Black, new Rectangle(0, 0, 150, 50));//画矩形
g.FillRectangle(Brushes.White, new Rectangle(1, 1, 149, 49));
g.DrawArc(Pens.Blue, new Rectangle(10, 10, 140, 10), 150, 90);//干扰线
string[] arrStr = new string[] { "我", "们", "孝", "行", "白", "到", "国", "中", "来", "真" };
Random r = new Random();
int i;
for (int j = 0; j < 4; j++)
{
i = r.Next(10);
g.DrawString(arrStr[i], new Font("微软雅黑", 15), Brushes.Red, new PointF(j * 30, 10));
}
bitmapobj.Save(Path.Combine(VerifyPath, "Verif.jpg"), ImageFormat.Jpeg);
bitmapobj.Dispose();
g.Dispose();
}
/// <summary>
/// 按比例缩放,图片不会变形,会优先满足原图和最大长宽比例最高的一项
/// </summary>
/// <param name="oldPath"></param>
/// <param name="newPath"></param>
/// <param name="maxWidth"></param>
/// <param name="maxHeight"></param>
public static void CompressPercent(string oldPath, string newPath, int maxWidth, int maxHeight)
{
Image _sourceImg = Image.FromFile(oldPath);
double _newW = (double)maxWidth;
double _newH = (double)maxHeight;
double percentWidth = (double)_sourceImg.Width > maxWidth ? (double)maxWidth : (double)_sourceImg.Width;
if ((double)_sourceImg.Height * (double)percentWidth / (double)_sourceImg.Width > (double)maxHeight)
{
_newH = (double)maxHeight;
_newW = (double)maxHeight / (double)_sourceImg.Height * (double)_sourceImg.Width;
}
else
{
_newW = percentWidth;
_newH = (percentWidth / (double)_sourceImg.Width) * (double)_sourceImg.Height;
}
System.Drawing.Image bitmap = new System.Drawing.Bitmap((int)_newW, (int)_newH);
Graphics g = Graphics.FromImage(bitmap);
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
g.Clear(Color.Transparent);
g.DrawImage(_sourceImg, new Rectangle(0, 0, (int)_newW, (int)_newH), new Rectangle(0, 0, _sourceImg.Width, _sourceImg.Height), GraphicsUnit.Pixel);
_sourceImg.Dispose();
g.Dispose();
bitmap.Save(newPath, System.Drawing.Imaging.ImageFormat.Jpeg);
bitmap.Dispose();
}
/// <summary>
/// 按照指定大小对图片进行缩放,可能会图片变形
/// </summary>
/// <param name="oldPath"></param>
/// <param name="newPath"></param>
/// <param name="newWidth"></param>
/// <param name="newHeight"></param>
public static void ImageChangeBySize(string oldPath, string newPath, int newWidth, int newHeight)
{
Image sourceImg = Image.FromFile(oldPath);
System.Drawing.Image bitmap = new System.Drawing.Bitmap(newWidth, newHeight);
Graphics g = Graphics.FromImage(bitmap);
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
g.Clear(Color.Transparent);
g.DrawImage(sourceImg, new Rectangle(0, 0, newWidth, newHeight), new Rectangle(0, 0, sourceImg.Width, sourceImg.Height), GraphicsUnit.Pixel);
sourceImg.Dispose();
g.Dispose();
bitmap.Save(newPath, System.Drawing.Imaging.ImageFormat.Jpeg);
bitmap.Dispose();
}
//添加水印
//二维码 QRCode
}
}