我正在尝试在 .NET 库中使用 ImageMagick COM 对象 (ImageMagickObject)。该库旨在从 IronRuby 中调用,但这并不是那么重要。我想采用这种方法,因为它适合我现有的调用,当前调用 ImageMagick 二进制文件作为外部进程。 COM 对象将采用与二进制文件相同的参数,但会保存进程创建,并且总体速度大约快 5 倍。
我唯一的障碍是 COM 对象的“Compare”方法将其结果返回到 STDERR。这也是二进制文件的一个问题,但是很容易将其返回到我所期望的 STDOUT 中。通过 COM 对象,我可以从函数返回值中获取结果。
如何将“比较”的结果重定向到字符串缓冲区甚至文件而不是 STDERR?
我尝试了以下操作,这确实阻止了输出到达 STDERR,但它没有按预期写入文件:
using ImageMagickObject;
...
public class ImageMagickCOM
{
[DllImport("Kernel32.dll", SetLastError = true)]
public static extern int SetStdHandle(int device, IntPtr handle);
private const int STDOUT_HANDLE = -11;
private const int STDERR_HANDLE = -12;
private ImageMagickObject.MagickImage magickImage = null;
private FileStream filestream = null;
private StreamWriter streamwriter = null;
public ImageMagickCOM()
{
IntPtr handle;
int status;
filestream = new FileStream("output.txt", FileMode.Create);
streamwriter = new StreamWriter(filestream);
streamwriter.AutoFlush = true;
//handle = filestream.Handle; // deprecated
handle = filestream.SafeFileHandle.DangerousGetHandle(); // replaces filestream.handle
status = SetStdHandle(STDOUT_HANDLE, handle);
status = SetStdHandle(STDERR_HANDLE, handle);
Console.SetOut(streamwriter);
Console.SetError(streamwriter);
magickImage = new ImageMagickObject.MagickImage();
}
public string Compare()
{
object[] args = new object[] { "-metric", "AE", "-fuzz", "10%", "imageA.jpg", "imageB.jpg", "diff.png" };
return (string)this.magickImage.Compare(ref args);
}
public void Close()
{
if (this.magickImage != null)
{
Marshal.ReleaseComObject(magickImage);
this.magickImage = null;
}
if (this.streamwriter != null)
{
this.streamwriter.Flush();
this.streamwriter.Close();
this.streamwriter = null;
this.filestream = null;
}
}
}
只有“比较”操作似乎使用 STDERR 来发送结果(它使用返回值作为成功指示符)。所有其他方法(Identify、Convert、Mogrify 等)均按您的预期工作。
作为参考,它的名称如下(来自 IronRuby):
require 'ImagingLib.dll'
im = ImagingLib::ImageMagickCOM.new
im.compare # returns nil
im.close
并创建了output.txt,但它是空的。没有任何内容打印到 STDOUT 或 STDERR。
编辑:为了清楚地了解流写入器刷新/关闭以及如何从 IronRuby 使用示例。