在使用Graphics.FromImage方法的时候,如果传入的System.Drawing.Image图像是索引像素格式,那么将会引发异常并提示以下消息:“无法从带有索引像素格式的图像创建 Graphics 对象。”。

先说下本人遇到的具体情况:由于网站需要添加一个上传图片自动打水印的功能,所以需要使用System.Drawing.Graphics类对图像重新绘制,将水印图片绘制到图片上。但在实际测试中,发现上传图片后,有的图片可以打水印成功,有的则会抛出异常,出现错误信息:A Graphics object cannot be created from an image that has an indexed pixel format。
后来断点调试,发现主要出错的地方是在Graphics.FromImage方法那,查阅了MSDN才发现这是由于索引像素格式的图片造成的(一般大多数的GIF格式图片都是这种类型):

官方文档:https://msdn.microsoft.com/zh-cn/library/system.drawing.graphics.fromimage.aspx

这里说下解决的思路,既然问题出在索引像素格式的图像上,那么只要对其进行处理即可。

根据官方文档所描述,一共有这8种像素格式会出现带有索引像素格式的图像无法创建 Graphics 对象的错误:Format1bppIndexed、Format4bppIndexed、Format8bppIndexed、Undefined、DontCare、Format16bppArgb1555、Format16bppGrayScale

我们使用下面的方法来判断图像的像素格式是否会引发异常:

/// <summary>
/// 判断图片是否索引像素格式,是否是引发异常的像素格式
/// </summary>
/// <param name="imagePixelFormat">图片的像素格式</param>
/// <returns></returns>
private bool IsIndexedPixelFormat(System.Drawing.Imaging.PixelFormat imagePixelFormat)
{PixelFormat[] pixelFormatArray = {PixelFormat.Format1bppIndexed,PixelFormat.Format4bppIndexed,PixelFormat.Format8bppIndexed,PixelFormat.Undefined,PixelFormat.DontCare,PixelFormat.Format16bppArgb1555,PixelFormat.Format16bppGrayScale};foreach (PixelFormat pf in pixelFormatArray){if (imagePixelFormat == pf){return true;}}return false;
}

我们只要传入当前Image对象的PixelFormat属性,就可以判断当前图像是否会抛出异常。那么接下来就可以根据自己的业务需求进行操作。

这里有多种方法,比如官方文档上所说的使用Image.Save(String, ImageFormat) 方法将索引的图像保存为另一种格式,然后为此新图像检索 Graphics 对象。

也可以使用Graphics.DrawImage方法将图像重新绘制到一个Bitmap对象中,并指定像素格式,从而去除索引,简单的范例:

using (System.Drawing.Image img = System.Drawing.Image.FromFile("要打水印的图片的路径"))
{if (IsIndexedPixelFormat(img.PixelFormat)){Bitmap bmp = new Bitmap(img.Width, img.Height, PixelFormat.Format32bppArgb);using (Graphics g = Graphics.FromImage(bmp)){g.DrawImage(img, 0, 0);}}
}

当然也可以直接禁止对索引像素格式的图片进行操作,如果想要偷懒,还可以直接使用try catch将异常捕获处理。无论使用什么方法,就是一定要注意带有索引像素格式的图片不能使用FromImage方法Graphics对象。


无法从带有索引像素格式的图像创建graphics对象问题解决

今天在一个项目中突然遇到一个问题,上传图片不能上传。于是断点跟踪。程序每次运行到Graphics g = Graphics.FromImage(img);就爆出如下错误:

“无法从带有索引像素格式的图像创建graphics对象”这个错误,对应的英文错误提示是“A Graphics object cannot be created from an image that has an indexed pixel format
于是通过查询 MSDN, 我们可以看到如下的提示信息:

通过上面的错误解释,我们可以看到,原因是因为图片是索引像素格式的。为了避免此问题的发生,我们在做水印之前,可以先判断原图片是否是索引像素格式的,如果是,则可以采用将此图片先clone到一张BMP上的方法来解决:

/// <summary>
/// 会产生graphics异常的PixelFormat
/// </summary>
private static PixelFormat[] indexedPixelFormats = { PixelFormat.Undefined, PixelFormat.DontCare,
PixelFormat.Format16bppArgb1555, PixelFormat.Format1bppIndexed, PixelFormat.Format4bppIndexed,
PixelFormat.Format8bppIndexed};/// <summary>
/// 判断图片的PixelFormat 是否在 引发异常的 PixelFormat 之中
/// </summary>
/// <param name="imgPixelFormat">原图片的PixelFormat</param>
/// <returns></returns>
private static bool IsPixelFormatIndexed(PixelFormat imgPixelFormat)
{foreach (PixelFormat pf in indexedPixelFormats){if (pf.Equals(imgPixelFormat)) return true;}return false;
}//.........使用
using (Image img = Image.FromFile("原图片路径"))
{//如果原图片是索引像素格式之列的,则需要转换if (IsPixelFormatIndexed(img.PixelFormat)){Bitmap bmp = new Bitmap(img.Width, img.Height, PixelFormat.Format32bppArgb);using (Graphics g = Graphics.FromImage(bmp)){g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;g.DrawImage(img, 0, 0);}//下面的水印操作,就直接对 bmp 进行了//......}else //否则直接操作{//直接对img进行水印操作}
}

无法从带有索引像素格式的图像创建 Graphics 对象相关推荐

  1. 无法从带有索引像素格式的图像创建graphics对象 问题的解决方案。

    .net下灰度模式图像在创建Graphics时出现:无法从带有索引像素格式的图像创建graphics对象 问题的解决方案. 在.net下,如果你加载了一副8位的灰度图像,然后想向其中绘制一些线条.或者 ...

  2. 绘图操作时报错“无法从带有索引像素格式的图像创建 Graphics 对象”

    如下代码会出现"无法从带有索引像素格式的图像创建 Graphics 对象"异常 Bitmap bitmap = new Bitmap(fileName); Graphics gra ...

  3. 对索引像素格式的图片进行Setpixel(具有索引像素格式的图像不支持SetPixel)解决方案

    对索引像素格式的图片进行Setpixel(具有索引像素格式的图像不支持SetPixel)解决方案 参考文章: (1)对索引像素格式的图片进行Setpixel(具有索引像素格式的图像不支持SetPixe ...

  4. c#_具有索引像素格式的图像不支持 SetPixel

    首先呢我们要明白各种图片格式,不同的图片格式成像也是不同的,对于索引类型的图片,其文件头部有一个颜色表,这个表按照一定的规律存储了所有的可能在这张图片中出现的颜色.它的每一个点的像素值(ARGB)并不 ...

  5. Python数字图像处理---1.1图像的像素格式与图像读写

    目录 前言 图像像素格式 图像读写 前言 本专栏面向所有希望或有兴趣从事数字图像处理工作.学习或研究的朋友,编程语言采用了当下最火的Python语言. Python是一种跨平台的计算机设计语言,也是一 ...

  6. C语言数字图像处理---1.1图像的像素格式与图像读写

    前言 本专栏面向所有希望或有兴趣从事数字图像处理工作.学习或研究的朋友,不懂MATLAB和OPENCV没关系,仅需要基础的C语言知识,便可以通过本专栏内容轻松入门数字图像处理方向.目前市面上的数字图像 ...

  7. 【Android 内存优化】自定义组件长图组件 ( 获取图像宽高 | 计算解码区域 | 设置图像解码属性 复用 像素格式 | 图像绘制 )

    文章目录 一.获取图像真实宽高 二.计算解码区域 三.设置解码参数 内存复用 像素格式 四.图像绘制 五.执行效果 六.源码及资源下载 官方文档 API : BitmapRegionDecoder 在 ...

  8. [译]在cocos2d里面如何使用Texture Packer和像素格式来优化 spritesheet

    免责申明(必读!):本博客提供的所有教程的翻译原稿均来自于互联网,仅供学习交流之用,切勿进行商业传播.同时,转载时不要移除本申明.如产生任何纠纷,均与本博客所有人.发表该翻译稿之人无任何关系.谢谢合作 ...

  9. 在 cocos2d 里面如何使用 Texture Packer 和像素格式来优化 spritesheet

    原文链接:http://www.cnblogs.com/andyque/archive/2011/03/18/1988097.html 免责申明(必读!):本博客提供的所有教程的翻译原稿均来自于互联网 ...

最新文章

  1. Cordova打包教程知识体系整理(Vue项目打包成ipa)
  2. ITK:重新运行管道不断变化的最大可能的地区
  3. 系统架构设计师证书含金量_计算机专科生不能错过的两个证书,含金量比较高,出社会有益...
  4. python import如何使用_Python如何import其它.py文件及其函数
  5. 前端通过spark-md5.js计算本地文件md5
  6. 一位工作了10年的C++程序员总结出这些忠告
  7. 深入解读Service Mesh的数据面Envoy
  8. 技术发展杂谈——RTC、WebRTC、VP9(2018年的文章)
  9. 计算机基础中关于二进制,计算机基础二进制十进制.ppt
  10. 【Python】QQ大家来找茬辅助
  11. 2022卡塔尔世界杯赛程直播北京时间_足球世界杯对阵表图完整全部
  12. Vs2008在高DPI下显示模糊的解决办法
  13. 算法LeetCode解题(C++)-15. 四数之和(难度:中等)
  14. Mac清理系统用什么软件?
  15. led手电筒烧灯珠_浅谈务优LED手电筒灯珠型号与区别技巧
  16. Numpy中flatten与ravel的区别
  17. python获取系统环境变量|os.environ|os.putenv|cmd添加环境变量
  18. Logstash 2.2.0 的最佳实践
  19. 51单片机与HC-05蓝牙模块连接使用
  20. 微信小程序智慧新零售

热门文章

  1. “同心同行,健康防疫”——海滨街社工服务站大筛纪实
  2. 180123 PCA主成分分析的原理解释及python代码实现
  3. Android中adb push和adb install的使用区别
  4. NSSCTF prize_p5
  5. FIS学习——利用Matlab创建模糊推理系统Ⅰ
  6. 访问ftp服务器文件夹权限设置,访问ftp服务器文件夹权限设置
  7. linux brctl 网桥配置
  8. html让图片下浮的代码,HTML基础-标签
  9. 二十一世纪大学英语读写教程(第三册)学习笔记(原文)——6 - Every 23 Minutes(每隔二十三分钟)
  10. 生信格式 | GAF GO注释文件详解