原文:上传图片时,使用GDI+中重绘方式将CMYK图片转为RGB图片

我们知道,如果网站上传图片时,如果用户上传的是CMYK图片,那么在网站上将是无法显示的,通常的现象是出现一个红叉。
下面使用将Image重新绘制为Format24bppRgb的方式来解决此问题:

public static void SavePostedImage(HttpPostedFile postedFile, string destFileName, int maxHeight, int maxWidth)
{
     System.Drawing.Imaging.ImageFormat imgFormat;
     if (destFileName.ToLower().EndWith("jpg"))
     {
          imgFormat = ImageFormat.Jpeg;
     }
     else //这里可以加更多选项,比如png,gif,tif....
     {
          imgFormat = ImageFormat.Gif;
     }

     Bitmap bmp = new Bitmap(postedFile.InputStream);

     if (IsCMYK(bmp))
     {
          bmp = ConvertCMYK(bmp);
     }

     if ((bmp.HorizontalResolution > 72) || (bmp.VerticalResolution > 72))
     {
          bmp.SetResolution(72, 72);
     }

     Bitmap saveBmp;
     if ((bmp.Height > maxHeight) || (bmp.Width > maxWidth))
     {
          Double heightRatio = Convert.ToDouble(maxHeight) / Convert.ToDouble(bmp.Height);
          Double widthRatio = Convert.ToDouble(maxWidth) / Convert.ToDouble(bmp.Width);
          Double scaleRatio;

          if (heightRatio > widthRatio)
          {
               scaleRatio = widthRatio;
          }
          else
          {
               scaleRatio = heightRatio;
          }

          int height = Convert.ToInt32(bmp.Height * scaleRatio);
          int width = Convert.ToInt32(bmp.Width * scaleRatio);

          saveBmp = new Bitmap(bmp, width, height);
     }
     else
     {
          saveBmp = new Bitmap(bmp);
     }

     bmp.Dispose();
     saveBmp.Save(destFileName, imgFormat);
     saveBmp.Dispose();
     postedFile.InputStream.Close();
}

public static string GetImageFlags(System.Drawing.Image img)
{
     ImageFlags FlagVals = (ImageFlags)Enum.Parse(typeof(ImageFlags), img.Flags.ToString());
     return FlagVals.ToString();
}

public static bool IsCMYK(System.Drawing.Image img)
{
     bool isCmyk;

     if ((GetImageFlags(img).IndexOf("Ycck") > -1) || (GetImageFlags(img).IndexOf("Cmyk") > -1))
     { isCmyk = true; }
     else
     { isCmyk = false; }

     return isCmyk;
}

public static Bitmap ConvertCMYK(Bitmap bmp)
{
     Bitmap tmpBmp = new Bitmap(bmp.Width, bmp.Height, PixelFormat.Format24bppRgb);

     Graphics g = Graphics.FromImage(tmpBmp);
     g.CompositingQuality = CompositingQuality.HighQuality;
     g.SmoothingMode = SmoothingMode.HighQuality;
     g.InterpolationMode = InterpolationMode.HighQualityBicubic;

     Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
     // 将CMYK图片重绘一遍,此时GDI+自动将CMYK格式转换为RGB了
     g.DrawImage(bmp, rect);

     Bitmap returnBmp = new Bitmap(tmpBmp);

     g.Dispose();
     tmpBmp.Dispose();
     bmp.Dispose();

     return returnBmp;


更多讨论:
(1)如何将RGB图片转换为CMYK图片?
(2)如何将RGB图片转换为索引图片?
(3)如何将RGB图片转换为灰度/黑白线条图片?
(4)上述转换如果是在WPF中,又如何进行呢?

留给读者去思考吧.

上传图片时,使用GDI+中重绘方式将CMYK图片转为RGB图片的更多相关文章

  1. 【转】VC的MFC中重绘函数的使用总结(整理)

    原文网址:http://www.cnblogs.com/x8023z/archive/2008/12/09/mfc33.html 在刷新窗口时经常要调用重绘函数MFC提供了三个函数用于窗口重绘Inva ...

  2. 在WPF窗体中重绘

    原文:在WPF窗体中重绘   写这篇主要是为了验证任何元素自身都具备绘图功能. 在默认Window中重写OnRender方法 protected override void OnRender(Draw ...

  3. WinForm中重绘TabControl选项卡标题

    最近开发WinForm频繁使用了TabControl控件,这个控件的选项卡没有BackgroundImage这个属性,那么如何为其各个选项卡添加背景图片呢?(这里说的是每个TabPage的头部,也就是 ...

  4. C# .NET开发图形图像程序时提示"GDI+ 中发生一般性错误"

    今天突然收到一封信,说我那个极度复杂的Marshal的问题被解决了(http://www.cnblogs.com/hotcan/archive/2005/01/12/91007.html).顿时感觉好 ...

  5. 关于生成缩略图及水印图片时出现GDI+中发生一般性错误解决方法

    System.Drawing.Image OldImage = null; oldImage = System.Drawing.Image.FromFile(ImageUrl); 使用该方法读取图片时 ...

  6. PHP上传图片时,如何判断上传的文件是否为可用的图片文件

    利用getimagesize函数: function isImage($filename){$types = '.gif|.jpeg|.png|.bmp';//定义检查的图片类型if(file_exi ...

  7. Java CMYK图片转RGB图片(TwelveMonkeys方式)

    TwelveMonkeys的使用比较简单,只要把相关的jar包加入到类路径,他的类我们基本不会用到,只要使用jdk ImageIO或其上层的接口就行了.jdk的ImageIO有自动发现功能,会自动查找 ...

  8. 【MFC】MFC中窗口重绘

    MFC中窗口重绘 摘自:http://blog.csdn.net/shuilan0066/article/details/5859057 在刷新窗口时经常要调用重绘函数 MFC提供了三个函数用于窗口重 ...

  9. 深入Windows窗体原理及控件重绘技巧

    之前有学MFC的同学告诉我觉得Windows的控件重绘难以理解,就算重绘成功了还是有些地方不明白,我觉得可能很多人都有这样的问题,在这里我从Windows窗体的最基本原理来讲解,如果你有类似的疑惑希望 ...

随机推荐

  1. js进阶 12-7 如何知道你是从哪个元素移动到当前元素与事件调用时如何添加额外数据

    js进阶 12-7 如何知道你是从哪个元素移动到当前元素与事件调用时如何添加额外数据 一.总结 一句话总结:event的relatedTarget属性和data属性. 1.如何知道你是从哪个元素移动到 ...

  2. 几款用jQuery写的h5小游戏

    人人都说前端用来做游戏是一件很困难的事情,遇到这些js的逻辑性问题,是不是有点懵?其实,做完一款游戏之后就会发现,没啥难的地方,差不多都是换汤不换药,作为爱玩游戏的我,也总结收集了几款比较流行的小软件 ...

  3. 【24.17%】【codeforces 721D】Maxim and Array

    time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  4. Java 学习(21):Java 实例

    Java 实例 本章节我们将为大家介绍 Java 常用的实例,通过实例学习我们可以更快的掌握 Java 的应用. Java 环境设置实例 //HelloWorld.java 文件 public cla ...

  5. Linux下kill进程脚本

    Linux下kill进程脚本 在Linux有时会遇到需要kill同一个程序的进程,然而这个程序有多个进程,一一列举很是繁琐,使用按名字检索,统一kill Perl脚本 使用方法 kill_all.pl ...

  6. windows下perl使用

    windows下perl使用 windows下perl开发工具 Perl 的官方网址提供下载的windows perl开发环境 ActiveState Perl Strawberry Perl DWI ...

  7. [AngularFire2] Building an Authentication Observable Data Service

    After successfully login, we want something help to check whether user has already login or not. And ...

  8. iOS开发RunLoop学习:四:RunLoop的应用和RunLoop的面试题

    一:RunLoop的应用 #import "ViewController.h" @interface ViewController () /** 注释 */ @property ( ...

  9. 通过select下拉框里的value控制div显示与隐藏

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  10. 【hdu 4315】Climbing the Hill

    Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s) ...