天天看點

Win7下Bitmap.Clone方法處理CMYK圖檔OutOfMemory異常的解決辦法

Winform下的圖像處理比較郁悶,動不動就蹦出這個 OutOfMemory 異常而不給具體原因。剛才談新客戶,他發給我幾張jpg圖檔,讓我處理一下給效果圖出來,我用自己的圖像處理程式一打開,蹦的一下,蹦出來了個 OutOfMemory 異常。跟蹤進去發現,PixelFormat值為 8207,見下圖:

<a href="http://images.cnblogs.com/cnblogs_com/xiaotie/201103/20110309114709203.png"></a>

我的程式是将所有的圖像都轉化為 Format24bppRgb 或 Format32bppArgb  格式的圖像,然後再進行處理,對于不是 Format24bppRgb 或 Format32bppArgb  這兩種格式的圖像,則使用 Bitmap.Clone()方法進行轉化,而這個方法,在處理 PixelFormat 值為 8207 的圖像時抛出了異常。

John Farrow: The problem is that there are some values missing from the Image.PixelFormat enumeration.  8207 is pixel format PixelFormat32bppCMYK (based on GdiPlusHeaders.h).  For some reason this value is not part of the PixelFormat enumeration. When the problem image is loaded on Windows XP, the .NET framework converts it from CMYK to RGB and thus it matches a value in the enumeration such as PixelFormat32bppRGB but when the image is loaded on Windows 7 it is not converted to RGB, but remains in CMYK format. So the solution is for the application to explicitly test for the 8207 value and treat the image as having PixelFormat32bppCMYK.

也就是說,8207 是一個未定義的 PixelFormat 枚舉值,它應該是 PixelFormat32bppCMYK 格式的圖像。

還是在該頁面,JohnWein給了個解決辦法:

private static Bitmap DownsampleImage(Bitmap srcImg, int destW, int destH, float dstDPI)  {      Bitmap bmPhoto = new Bitmap(destW, destH,PixelFormat.Format32bppRgb);      bmPhoto.SetResolution(dstDPI, dstDPI);      Graphics grPhoto = Graphics.FromImage(bmPhoto);      grPhoto.InterpolationMode = InterpolationMode.HighQualityBicubic;      grPhoto.DrawImage(srcImg,                        new System.Drawing.Rectangle(0, 0, bmPhoto.Width, bmPhoto.Height),                        new System.Drawing.Rectangle(0, 0, srcImg.Width, srcImg.Height),                        GraphicsUnit.Pixel);      grPhoto.Dispose();      return bmPhoto;  }

據測試,該方法可行,問題解決。下面是我修改後的代碼:

private unsafe void CreateFromBitmap(Bitmap map)      int height = map.Height;      int width = map.Width;     const int PixelFormat32bppCMYK = 8207;     PixelFormat format = map.PixelFormat;     if (this.Width != width || this.Height != height)      {          return;      }     Bitmap newMap = map;      Int32 step = SizeOfT();     switch (format)          case PixelFormat.Format24bppRgb:              break;          case PixelFormat.Format32bppArgb:          default:              if ((int)format == PixelFormat32bppCMYK)              {                  format = PixelFormat.Format24bppRgb;                  newMap = new Bitmap(width, height, format);                  using (Graphics g = Graphics.FromImage(newMap))                  {                      g.DrawImage(map, new Point());                  }              }              else                  format = PixelFormat.Format32bppArgb;                  newMap = map.Clone(new Rectangle(0, 0, width, height), PixelFormat.Format32bppArgb);      BitmapData data = newMap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, format);      Byte* line = (Byte*)data.Scan0;     …… 本文轉自xiaotie部落格園部落格,原文連結http://www.cnblogs.com/xiaotie/archive/2011/03/09/1978121.html如需轉載請自行聯系原作者 xiaotie 集異璧實驗室(GEBLAB)

繼續閱讀