C#面向对象四(文件与目录操作、序列化与反序列化、XML)

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();
写入文件的5个步骤
 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();
读取文件的5个步骤
 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();
追加文件的5个步骤
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);//删除
Directory操作[新建、移动、删除]

//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"));//合并两个路径
各种Path方法
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;
读取遍历XML所有子节点

常用属性与说明

对象属性和方法说明
XmlDocumentDocumentElement属性获取根节点
ChildNodes属性获取所有子节点
Load()方法读取整个XML的结构
XmlNodeInnerText属性当前节点的值
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);
        }
    }
}
JsonHelper
{
    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);
}
Json举例

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);
            }
        }
    }
}
XmlHelper
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);
}
XmlHelper举例

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);
            }
        }
    }
SerializeHelper

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
    }
}
ImageHelper
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值