在 Mac OS X 上使用 System.Drawing.Common 将 BMP 转换为 TIFF
Convert BMP to TIFF using System.Drawing.Common on Mac OS X
我正在尝试使用 System.Drawing.Common
和 Mac os 上的以下 C# 代码 (.NET CORE 3.1) 将 BMP 图像转换为 tiff 图像:
public void SaveBitmapAsTiff(string location, Bitmap image)
{
var imageCodecInfo = GetEncoderInfo("image/tiff");
var encoder = Encoder.Compression;
var encoderParameters = new EncoderParameters(1);
var encoderParameter = new EncoderParameter(
encoder,
(long)EncoderValue.CompressionLZW);
encoderParameters.Param[0] = encoderParameter;
location = location.Replace(".bmp", "");
image.Save(location + ".tiff", imageCodecInfo, encoderParameters);
// image.Save(location + ".tiff", ImageFormat.Tiff); Also tried this method overload
}
private static ImageCodecInfo GetEncoderInfo(string mimeType)
{
int j;
ImageCodecInfo[] encoders;
encoders = ImageCodecInfo.GetImageEncoders();
for(j = 0; j < encoders.Length; ++j)
{
if(encoders[j].MimeType == mimeType)
return encoders[j];
}
return null;
}
location
参数包含我们要写入的文件路径,image
参数包含我们从磁盘加载的位图。
当我尝试 运行 此代码时,出现以下异常:
Unhandled exception. System.NotImplementedException: Not implemented.
at System.Drawing.SafeNativeMethods.Gdip.CheckStatus(Int32 status)
at System.Drawing.Image.Save(String filename, ImageCodecInfo encoder, EncoderParameters encoderParams)
at System.Drawing.Image.Save(String filename, ImageFormat format)
at BmpTiffConverter.Services.FileService.SaveBitmapAsTiff(String location, Bitmap image) in /Users/tomcoldenhoff/Documents/ReSoftware/Repositories/BmpTiffConverter/BmpTiffConverter/Services/FileService.cs:line 54
at BmpTiffConverter.Services.ConverterService.ConvertBmpToTiff(String inputPath, String outputPath) in /Users/tomcoldenhoff/Documents/ReSoftware/Repositories/BmpTiffConverter/BmpTiffConverter/Services/ConverterService.cs:line 20
我的 google 搜索建议我必须安装 libgdiplus,我已经用 brew install mono-libgdiplus
和 brew upgrade mono-libgdiplus
.
安装了
我还通过安装 runtime.osx.10.10-x64.CoreCompat.System.Drawing
包尝试了@Andy 的建议答案,不幸的是这没有用。
还有人有其他建议吗?
不幸的是我没有 Mac 来测试。我使用 DotNet Core 3.1 在 Windows 和 Ubuntu 20 上测试了您的代码,您的代码似乎可以正常工作。我只能猜测这可能与您创建或修改 Bitmap
的方式有关。
下面是我在 Linux 下创建项目的方式。 dotnet add package
是我添加 System.Drawing.Common
NuGet 包的方式。我不确定它在 Mono 上如何工作,或者您是否正在使用 Mono。
> dotnet new console
> dotnet add package System.Drawing.Common
> dotnet restore
我编辑了program.cs
> dotnet build
> dotnet run
而且 运行 非常好。我现在可以在任何图像查看器中打开 tiff 图像。
从代码风格的角度来看,我建议进行相当多的更改。我知道您遵循了 MSDN 的代码示例,但就目前而言,他们的示例在这种情况下并不是很清楚。我刚刚复制并粘贴了我的整个 .cs 文件,并对各种修改添加了注释。编写清晰的代码与编写可工作的代码一样重要。
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
class Program
{
// made the function more generic Bitmap inherits from Image and Image contains
// the save feature so it might as well be made more general
public static void SaveImageAsTiff(string location, Image image)
{
// fetch tiffCodec
var tiffCodec = ImageCodecInfo
.GetImageEncoders()
.Where(info => info.MimeType == "image/tiff")
.First();
// create encoderParameters
// this structure is much clearer IMO
// (Can you see that there is now a color depth parameter?)
var encoderParameters = new EncoderParameters(2)
{
Param = new EncoderParameter[]{
new EncoderParameter(Encoder.Compression, (long)EncoderValue.CompressionLZW),
new EncoderParameter(Encoder.ColorDepth, 24L)
}
};
// save image using codec and encoder parameters
// it is common behavior to just save the file with the given location parameter
// and not to try do some extension conversion
image.Save(location, tiffCodec, encoderParameters);
}
static void Main(string[] args)
{
// original bitmap location
// (Yes forward slashes work on Windows so relative file paths are simple to handle)
string bmpLocation = @"C:/Images/test.bmp";
//string bmpLocation = @"~/Images/test.bmp"; // test on Linux
// tidy way to convert file extensions of a path in C#
string tiffLocation = System.IO.Path.ChangeExtension(bmpLocation, "tiff");
// open image and force it to be a bitmap for examples sakes
Bitmap bmpImage = new Bitmap(Image.FromFile(bmpLocation));
// save image as tiff
SaveImageAsTiff(tiffLocation, bmpImage);
}
}
问题是 mono-libgdiplus
没有实现 EncoderValue.CompressionLZW
编码器参数。我建议不要使用那个库,而是安装这个 nuget 包:
runtime.osx.10.10-x64.CoreCompat.System.Drawing
添加该包后,您的代码运行完美。
我正在尝试使用 System.Drawing.Common
和 Mac os 上的以下 C# 代码 (.NET CORE 3.1) 将 BMP 图像转换为 tiff 图像:
public void SaveBitmapAsTiff(string location, Bitmap image)
{
var imageCodecInfo = GetEncoderInfo("image/tiff");
var encoder = Encoder.Compression;
var encoderParameters = new EncoderParameters(1);
var encoderParameter = new EncoderParameter(
encoder,
(long)EncoderValue.CompressionLZW);
encoderParameters.Param[0] = encoderParameter;
location = location.Replace(".bmp", "");
image.Save(location + ".tiff", imageCodecInfo, encoderParameters);
// image.Save(location + ".tiff", ImageFormat.Tiff); Also tried this method overload
}
private static ImageCodecInfo GetEncoderInfo(string mimeType)
{
int j;
ImageCodecInfo[] encoders;
encoders = ImageCodecInfo.GetImageEncoders();
for(j = 0; j < encoders.Length; ++j)
{
if(encoders[j].MimeType == mimeType)
return encoders[j];
}
return null;
}
location
参数包含我们要写入的文件路径,image
参数包含我们从磁盘加载的位图。
当我尝试 运行 此代码时,出现以下异常:
Unhandled exception. System.NotImplementedException: Not implemented.
at System.Drawing.SafeNativeMethods.Gdip.CheckStatus(Int32 status)
at System.Drawing.Image.Save(String filename, ImageCodecInfo encoder, EncoderParameters encoderParams)
at System.Drawing.Image.Save(String filename, ImageFormat format)
at BmpTiffConverter.Services.FileService.SaveBitmapAsTiff(String location, Bitmap image) in /Users/tomcoldenhoff/Documents/ReSoftware/Repositories/BmpTiffConverter/BmpTiffConverter/Services/FileService.cs:line 54
at BmpTiffConverter.Services.ConverterService.ConvertBmpToTiff(String inputPath, String outputPath) in /Users/tomcoldenhoff/Documents/ReSoftware/Repositories/BmpTiffConverter/BmpTiffConverter/Services/ConverterService.cs:line 20
我的 google 搜索建议我必须安装 libgdiplus,我已经用 brew install mono-libgdiplus
和 brew upgrade mono-libgdiplus
.
我还通过安装 runtime.osx.10.10-x64.CoreCompat.System.Drawing
包尝试了@Andy 的建议答案,不幸的是这没有用。
还有人有其他建议吗?
不幸的是我没有 Mac 来测试。我使用 DotNet Core 3.1 在 Windows 和 Ubuntu 20 上测试了您的代码,您的代码似乎可以正常工作。我只能猜测这可能与您创建或修改 Bitmap
的方式有关。
下面是我在 Linux 下创建项目的方式。 dotnet add package
是我添加 System.Drawing.Common
NuGet 包的方式。我不确定它在 Mono 上如何工作,或者您是否正在使用 Mono。
> dotnet new console
> dotnet add package System.Drawing.Common
> dotnet restore
我编辑了program.cs
> dotnet build
> dotnet run
而且 运行 非常好。我现在可以在任何图像查看器中打开 tiff 图像。
从代码风格的角度来看,我建议进行相当多的更改。我知道您遵循了 MSDN 的代码示例,但就目前而言,他们的示例在这种情况下并不是很清楚。我刚刚复制并粘贴了我的整个 .cs 文件,并对各种修改添加了注释。编写清晰的代码与编写可工作的代码一样重要。
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
class Program
{
// made the function more generic Bitmap inherits from Image and Image contains
// the save feature so it might as well be made more general
public static void SaveImageAsTiff(string location, Image image)
{
// fetch tiffCodec
var tiffCodec = ImageCodecInfo
.GetImageEncoders()
.Where(info => info.MimeType == "image/tiff")
.First();
// create encoderParameters
// this structure is much clearer IMO
// (Can you see that there is now a color depth parameter?)
var encoderParameters = new EncoderParameters(2)
{
Param = new EncoderParameter[]{
new EncoderParameter(Encoder.Compression, (long)EncoderValue.CompressionLZW),
new EncoderParameter(Encoder.ColorDepth, 24L)
}
};
// save image using codec and encoder parameters
// it is common behavior to just save the file with the given location parameter
// and not to try do some extension conversion
image.Save(location, tiffCodec, encoderParameters);
}
static void Main(string[] args)
{
// original bitmap location
// (Yes forward slashes work on Windows so relative file paths are simple to handle)
string bmpLocation = @"C:/Images/test.bmp";
//string bmpLocation = @"~/Images/test.bmp"; // test on Linux
// tidy way to convert file extensions of a path in C#
string tiffLocation = System.IO.Path.ChangeExtension(bmpLocation, "tiff");
// open image and force it to be a bitmap for examples sakes
Bitmap bmpImage = new Bitmap(Image.FromFile(bmpLocation));
// save image as tiff
SaveImageAsTiff(tiffLocation, bmpImage);
}
}
问题是 mono-libgdiplus
没有实现 EncoderValue.CompressionLZW
编码器参数。我建议不要使用那个库,而是安装这个 nuget 包:
runtime.osx.10.10-x64.CoreCompat.System.Drawing
添加该包后,您的代码运行完美。