zoukankan      html  css  js  c++  java
  • C#中图片与BASE64码互相转换

    复制代码
     //保存目录
                string dir = "/upload/user/head";
                //站点文件目录
                string fileDir = HttpContext.Current.Server.MapPath("~" + dir);
                //文件名称
                string fileName = "headdemo" + DateTime.Now.ToString("yyyyMMddHHmmssff");
                //保存文件所在站点位置
                string filePath = Path.Combine(fileDir, fileName);
    
                if (!System.IO.Directory.Exists(fileDir))
                    System.IO.Directory.CreateDirectory(fileDir);
    
                //读图片转为Base64String
                System.Drawing.Bitmap bmp1 = new System.Drawing.Bitmap(Path.Combine(fileDir, "default.jpg"));
                using (MemoryStream ms1 = new MemoryStream())
                {
                    bmp1.Save(ms1, System.Drawing.Imaging.ImageFormat.Jpeg);
                    byte[] arr1 = new byte[ms1.Length];
                    ms1.Position = 0;
                    ms1.Read(arr1, 0, (int)ms1.Length);
                    ms1.Close();
                    UserPhoto = Convert.ToBase64String(arr1);
                }
    
                //将Base64String转为图片并保存
                byte[] arr2 = Convert.FromBase64String(UserPhoto);
                using (MemoryStream ms2 = new MemoryStream(arr2))
                {
                    System.Drawing.Bitmap bmp2 = new System.Drawing.Bitmap(ms2);
                    bmp2.Save(filePath + ".jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
                    //bmp2.Save(filePath + ".bmp", System.Drawing.Imaging.ImageFormat.Bmp);
                    //bmp2.Save(filePath + ".gif", System.Drawing.Imaging.ImageFormat.Gif);
                    //bmp2.Save(filePath + ".png", System.Drawing.Imaging.ImageFormat.Png);
                }
    复制代码
    复制代码
    //将Base64String转为图片并保存
                            byte[] arr2 = Convert.FromBase64String(UserPhoto);
                            using (MemoryStream ms2 = new MemoryStream(arr2))
                            {
                                System.Drawing.Bitmap bmp2 = new System.Drawing.Bitmap(ms2);
                                ////只有把当前的图像复制一份,然后把旧的Dispose掉,那个文件就不被锁住了,
                                ////这样就可以放心覆盖原始文件,否则GDI+一般性错误(A generic error occurred in GDI+)
                                //System.Drawing.Bitmap bmpNew = new System.Drawing.Bitmap(bmp2);
                                //bmp2.Dispose();
                                //bmp2 = null;
                                bmp2.Save(filePath, System.Drawing.Imaging.ImageFormat.Jpeg);
                                //bmp2.Save(filePath + ".jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
                                //bmp2.Save(filePath + ".bmp", System.Drawing.Imaging.ImageFormat.Bmp);
                                //bmp2.Save(filePath + ".gif", System.Drawing.Imaging.ImageFormat.Gif);
                                //bmp2.Save(filePath + ".png", System.Drawing.Imaging.ImageFormat.Png);
                                bmp2.Dispose();
                            }
    复制代码

    GDI+一般性错误(A generic error occurred in GDI+)

     

    1.GDI+的前世今生

    GDI+全称图形设备接口,Graphics Device Interface (GDI) ,他的爸爸叫做GDI, 用C写的。Windows XP出来以后用C++重新写了一下,变成了GDI+。从.NET Framework 1.0开始,GDI+就被正式封装在了.NET Framework里面,并被广泛地应用到了所有和图形图像相关的程序中。不幸的是,这个GDI+引入了微软有史以来最大的2个patch,造成了Microsoft IT, Support, Developer, Tester的无数麻烦。[1][2]

    GDI+没有用显卡加速,所以Windows Vista推荐用Windows Display Driver Model (WDDM)了,支持渲染,3D加速。不过普通的应用程序,用GDI/GDI+其实是完全足够了,所以GDI+是在微软平台上开发图形图像程序的最好选择了。至少现在没有听说微软准备重新写GDI

    GDI+ 可以用来做图形处理,也可以做图像处理。这里只分析几个使用.NET Framework容易出错的地方。 

    2. GDI+一般性错误(A generic error occurred in GDI+)

    这是使用GDI+的时候最滑稽的一个Exception,里面啥信息都没有。对于刚刚开始使用.NET Framework开发者来说,很难发现这个问题到底是为什么。

    我们先来看看下面一段代码 

    string fileName = "sample.jpg";
    Bitmap bmp = new Bitmap(fileName);
    bmp.Save(fileName, ImageFormat.Jpeg);

    这段代码的目的是要打开一个Bitmap,然后保存。可惜这段代码一定会给你一个GDI+一般性错误:

    System.Runtime.InteropServices.ExternalException

    其中的Error Code是0x80004005, innerException是空。如果你查Windows的Error Code表,会发现这个错误原因是“Unspecified Error”,还是什么都不知道。这其实是.NET Framework封装不好的问题,我们可以调用

    Marshal.GetLastWin32Error()

    拿到Win32的Error, 32。这个错误代码就有点信息量了,在winerror.h里面,我们可以找到下面的定义:

    复制代码
    复制代码
    //
    // MessageId: ERROR_SHARING_VIOLATION
    //
    // MessageText:
    //
    //  The process cannot access the file because it is being used by another process.
    //
    #define ERROR_SHARING_VIOLATION          32L
    复制代码
    复制代码

      

    原来是文件不能写。其实MSDN里面有一句话,The file remains locked until the Bitmap is disposed。所以文件读取以后是锁着的,没有办法写。那如果我想做点改动然后再保存原来的文件怎么办呢?

    这里有个土办法可以搞定这个问题 

    Bitmap bmpTemp = new Bitmap(image);
    Bitmap bmp = new Bitmap(bmpTemp);
    bmpTemp.Dispose();
    bmp.Save(image, ImageFormat.Jpeg);

    只要把当前的图像复制一份,然后把旧的Dispose掉,那个文件就不被锁住了,这样就可以放心覆盖原始文件了。

    想想如果你要用GDI+写一个Painter,很容易你就会遇到这个问题。

  • 相关阅读:
    vs2012 切换语言
    extjs 多维数组支持
    Extjs: 对象不支持“createContextualFragment”属性或方法
    Servlet学习五——流的分发
    Servlet学习四——传输文本
    Servlet学习三——传输文件
    Servlet学习二——doGet和doPost
    Java处理Excel整理篇
    ORA-01033: ORACLE 正在初始化或关闭 进程 ID: 0 会话 ID: 0 序列号: 0
    Servlet学习一
  • 原文地址:https://www.cnblogs.com/efreer/p/11362601.html
Copyright © 2011-2022 走看看