2010-01-10 50 views
4

我有一个函数需要一个位图,将它的一部分复制并保存为8bpp tiff。结果图像的文件名是唯一的,文件不存在,程序有权写入目标文件夹。System.Drawing.Image.Save抛出ExternalException:在GDI中发生了一般性错误

void CropImage(Bitmap map) { 
     Bitmap croped = new Bitmap(200, 50); 

     using (Graphics g = Graphics.FromImage(croped)) { 
      g.DrawImage(map, new Rectangle(0, 0, 200, 50), ...); 
     } 

     var encoderParams = new EncoderParameters(2); 
     encoderParams.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.ColorDepth, 8L); 
     encoderParams.Param[1] = new EncoderParameter(System.Drawing.Imaging.Encoder.Compression, (long)EncoderValue.CompressionNone); 

     croped.Save(filename, tiffEncoder, encoderParams); 
     croped.Dispose(); 
    } 

奇怪的是,这funcion效果很好,在某些计算机(Win 7的),并抛出System.Runtime.InteropServices.ExternalException:在其他计算机上(主要是Win XP的)GDI异常发生一般性错误。

所有计算机都安装了.NET 3.5 SP1运行时。

如果我使用croped.Save(filename, ImageFormat.Tiff);而不是croped.Save(filename, tiffEncoder, encoderParams);比它适用于所有计算机,但我需要以8bpp格式保存Tiff。

你有什么想法,问题可能出在哪里?

谢谢,卢卡斯

+0

也许图片还没有保存,并开始处置? – serhio 2010-01-10 15:12:59

+0

它是否有任何Windows XP机器可以使用? – SLaks 2010-01-10 15:27:16

+0

GDI +在Vista中升级到版本1.1。我从来没有发现任何描述这些变化的文档。听起来像你找到一个。 – 2010-01-10 16:41:09

回答

1

GDI是一个Windows操作系统的功能。处理16位TIFF文件时遇到了类似的问题,并使用了不同的库。请参阅using LibTIFF from c#

MSDN帮助建议该功能可用,但在Windows尝试将位图复制到新位图或将其保存到文件或流时,Windows会引发“通用错误”异常。事实上,相同的功能在Windows7上运行良好(这似乎具有良好的TIFF支持)。请参阅New WIC functioanity in Windows 7

我使用的另一个解决方案是在8位制作不安全的副本。这样我就可以保存PNG文件(使用调色板)。我还没有尝试过这个TIFF。

 // part of a function taking a proprietary TIFF tile structure as input and saving it into the desired bitmap format 
     // tile.buf is a byterarray, containing 16-bit samples from TIFF. 

     bmp = new Bitmap(_tile_width, _tile_height, PixelFormat.Format8bppIndexed); 
     System.Drawing.Rectangle rect = new System.Drawing.Rectangle(0, 0, bmp.Width, bmp.Height); 
     BitmapData bmpData =bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite,bmp.PixelFormat); 
     int bytes = bmpData.Stride * bmp.Height; 

     dstBitsPalette = (byte *)bmpData.Scan0; 

     offset=0; 


     for (offset = 0; offset < _tile_size; offset += 2) 
     { 
      dstBitsPalette[offset >> 1] = tile.buf[offset + 1]; 
     } 

     // setup grayscale palette 
     ColorPalette palette = bmp.Palette; 
     for (int i = 0; i < 256; i++) 
     { 
      Color c = Color.FromArgb(i, i, i); 
      palette.Entries[i] = c; 
     } 
     bmp.Palette = palette; 
     bmp.UnlockBits(bmpData); 

     return bmp; 

    } 
相关问题