我有一个允许用户定义图像区域并将该区域保存到文件的应用程序。我遇到了一个我无法解决的障碍。我创建的用于绘制选定区域的位图被“MemoryBmp”的 ImageFormat 卡住,看起来这是为任何非文件加载位图设置的 ImageFormat。问题是我的位图是在内存中创建的,我想将其保存为 CCITT4 双色 TIFF,但我收到“GDI+ 中发生一般错误”异常。我非常有信心这是因为 Image.RawFormat 属性是可怕的 MemoryBmp。
Image.Save() 有一个带有 ImageFormat 参数的重载,当我使用传递 ImageFormat.Tiff 时,它保存得很好,但我没有机会指定我的编码器参数。
我能想到的唯一可能的解决方法是使用 Image.Save(Image, ImageFormat) 保存到磁盘然后重新加载它(RawFormat 现在将正确设置为 ImageFormat.Tif),然后通过编码器设置再次保存。这只是愚蠢的,但必须有更好的方法。
这是一段代码(这只是测试的东西),如果我之前的描述不够清楚,应该可以让您了解我在做什么:
SizeF dpiScale = GetScreenToImageDPIRatio(loadedImage);
using (Bitmap image = new Bitmap(loadedImage,
(int)(_cropBox.Width * dpiScale.Width),
(int)(_cropBox.Height * dpiScale.Height)))
{
image.SetResolution(loadedImage.HorizontalResolution,
loadedImage.VerticalResolution);
using (Graphics g = Graphics.FromImage(image))
{
g.DrawImage(loadedImage, 0, 0, new Rectangle(
(int)(_cropBox.Location.X * dpiScale.Width),
(int)(_cropBox.Location.Y * dpiScale.Height),
(int)(_cropBox.Width * dpiScale.Width),
(int)(_cropBox.Height * dpiScale.Height)),
GraphicsUnit.Pixel);
}
// It's stuck as a MemoryBmp so none of these checks will work
if (true || image.RawFormat.Equals(ImageFormat.Tiff))
{
ImageCodecInfo tiffCodecInfo = ImageUtils.GetEncoderInfo("image/tiff");
EncoderParameters myEncoderParameters = new EncoderParameters(2);
myEncoderParameters.Param[0] = new
EncoderParameter(System.Drawing.Imaging.Encoder.Compression,
(long)EncoderValue.CompressionCCITT4);
myEncoderParameters.Param[1] = new
EncoderParameter(System.Drawing.Imaging.Encoder.ColorDepth, 1L);
image.Save(Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".tif"),
tiffCodecInfo, myEncoderParameters);
// The file is a "MemoryBmp" and it's screwing things up
//image.Save(Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".tif"),
// ImageFormat.Tiff);
}
else
{
// other format saving support, blah blah blah
}
}
哦,我应该提到“loadedIimage”确实是一个 tiff 图像,我将 loadImage 的引用传递给 Bitmap.ctor() 以查看它是否会提示它正在处理的内容,但它没有任何区别。