//保存目录
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 = ;
ms1.Read(arr1, , (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,很容易你就会遇到这个问题。

C#中图片与BASE64码互相转换的更多相关文章

  1. JavaScript 图片与Base64数据互相转换脚本

    JavaScript 图片与Base64数据互相转换脚本 注: 转换过程中注意跨域问题.测试页是否支持相关标签创建.dom结构. 方法一:非Html 5使用FileReader 使用XMLHttpRe ...

  2. oracle BLOG图片和CLOG base64码的转换

    --BASE64转图片CREATE OR REPLACE FUNCTION DECODE_BASE64(P_CLOB_IN IN CLOB) RETURN BLOB IS V_BLOB BLOB; V ...

  3. [转]C#中图片.BYTE[]和base64string的转换

    本文转自:http://blog.csdn.net/thebesttome/article/details/6870155 在C#中 图片到byte[]再到base64string的转换: Bitma ...

  4. C#中图片.BYTE[]和base64string的转换

    在C#中 图片到byte[]再到base64string的转换: Bitmap bmp = new Bitmap(filepath);                MemoryStream ms = ...

  5. JavaScript—图片与base64编码互相转换

    图片转换为base64编码 <input type = "file" id = "file" onchange="popFileName(thi ...

  6. c# 图片 与 BASE64 字符串 互相转换。

    using System; using System.Collections.Generic; using System.Drawing; using System.IO; using System. ...

  7. C#中图片转换为Base64编码,Base64编码转换为图片

    #region 图片转为base64编码的字符串 public string ImgToBase64String(string Imagefilename) { try { Bitmap bmp = ...

  8. java中图片地址base64编码的相互转换

    public class Base64Url { /** * 将base64编码字符串转换为图片 * @param imgStr: base64编码字符串 * @param path: 图片路径-具体 ...

  9. 图片和Base64之间的转换

    public static Bitmap GetImageFromBase64String(string strBase) { try { MemoryStream stream = new Memo ...

随机推荐

  1. ubuntu vim8.0源码安装

    安装篇 从https://github.com/vim/vim下载相应zip源码文件,利用unzip vim-master.zip 命令解压到当前用户目录,即~: 解压后进入vim的src目录,首先, ...

  2. poj3069 Saruman's Army

    http://poj.org/problem?id=3069 Saruman the White must lead his army along a straight path from Iseng ...

  3. Jquery表单验证

    .代码中添加引用(必备引用) <script src="Scripts/jquery-1.4.1.min.js" type="text/javascript&quo ...

  4. Sublime Text 3使用指南(1)——安装package control组件

    按Ctrl+`, 调出console 控制台中粘贴一下代码: import urllib.request,os; pf = 'Package Control.sublime-package'; ipp ...

  5. PHP调用webservice遇到 Soap WSDL Error - "failed to load external entity

    本人遇到的原因是服务器上没有安装php-soap centos安装方式: yum install php-soap 安装完成后重启 php-fpm 服务 service php-fpm restart ...

  6. How To Install Java on CentOS and Fedora

    PostedDecember 4, 2014 453.8kviews JAVA CENTOS FEDORA   Introduction This tutorial will show you how ...

  7. UIButton的文本与图片的布局

    UIButton内部文本和图片的布局是我们日常代码中,不可缺少的部分,按钮默认左边图片右边文本,那要实现左边文本,右边图片,我们该怎么解决呢,上面图片,下面文本又该怎么办呢 其实很简单,今天总结下,目 ...

  8. 获取div或者元素相对于屏幕坐上角的绝对位置

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  9. 我的Markdown笔记

    一片简单的Markdown笔记,共8项,基本上满足Markdown文档的编写(表格不建议用Markdown),每项上半部分是源码,下半部分是效果图片. 标题 段落 列表 强调 分割线 代码 连接 图片 ...

  10. Java学习路线图,专为新手定制的Java学习计划建议

    怎么学习Java,这是很多新手经常会问我的问题,现在我简单描述下一个Java初学者到就业要学到的一些东西:    首先要明白Java体系设计到得三个方面:J2SE,J2EE,J2ME(KJAVA).J ...