I've sent you a link to the file through contact. In the meantime, I've changed my approach and have something that seems to work for my needs:
Thanks!
/// <summary>
/// Converts an unspecified image to a format supported by Kofax Capture.
/// </summary>
/// <param name="source">The original image bytes.</param>
/// <returns>The converted TIFF bytes.</returns>
public static byte[] MakeValidKofaxTiff(byte[] source, bool ccittBitonal = false)
{
using (var frames = new MagickImageCollection(source))
{
var colorType = frames[0].ColorType;
if (colorType == ColorType.Bilevel)
{
if (!ccittBitonal)
{
SetTiffProfile(frames, ColorSpace.GRAY, ColorType.Bilevel, 1, CompressionMethod.LZW);
}
else
{
SetTiffProfile(frames, ColorSpace.GRAY, ColorType.Bilevel, 1, CompressionMethod.Group4);
}
}
else if (colorType == ColorType.Grayscale)
{
SetTiffProfile(frames, ColorSpace.GRAY, ColorType.Grayscale, 8, CompressionMethod.LZW);
}
else
{
SetTiffProfile(frames, ColorSpace.sRGB, ColorType.TrueColor, 24, CompressionMethod.LZW);
}
frames.RePage();
return frames.ToByteArray();
}
}
/// <summary>
/// Sets the TIFF profile for an image.
/// </summary>
/// <param name="frames">A collection of pages for the image.</param>
/// <param name="colorSpace">The color space of the target (eg. RGB, CMYK).</param>
/// <param name="colorType">The color type of the target (eg. Bitonal, Grayscal, Color)</param>
/// <param name="depth">The number of bits used per pixel in the target.</param>
/// <param name="compression">The desired TIFF compression method.</param>
private static void SetTiffProfile(MagickImageCollection frames, ColorSpace colorSpace, ColorType colorType, int depth, CompressionMethod compression)
{
foreach (var frame in frames)
{
frame.Format = MagickFormat.Tif;
frame.CompressionMethod = compression;
frame.ColorSpace = colorSpace;
frame.ColorType = colorType;
frame.Depth = depth;
}
}
There's one snag though. One of my test images is a 20MB 32-bit TIFF, and I consistently get a data flush exception on frames.ToByteArray():ImageMagick.MagickCoderErrorException was unhandled
HResult=-2146233088
Message=reci.ImageProcessing.Test.vshost.exe: Error flushing data before directory write. `TIFFWriteDirectorySec' @ error/tiff.c/TIFFErrors/560
Source=Magick.NET-x86
StackTrace:
at ImageMagick.MagickImageCollection.HandleException(MagickException exception)
at ImageMagick.MagickImageCollection.ToByteArray()
at reci.ImageProcessing.Magick.ImageTools.MakeValidKofaxTiff(Byte[] source, Boolean ccittBitonal) in C:\TFS\Other\Image Processing\WPF Imaging\codebase\reci.ImageProcessing.Magick\ImageTools.cs:line 61
at reci.ImageProcessing.Test.TestUtility.<buttonKofaxTiff_Click>b__e(Stream strm) in C:\TFS\Other\Image Processing\WPF Imaging\codebase\reci.ImageProcessing.Test\TestUtility.cs:line 99
at reci.ImageProcessing.Test.TestUtility.RunCommandOnFile(Func`2 action, String targetExt) in C:\TFS\Other\Image Processing\WPF Imaging\codebase\reci.ImageProcessing.Test\TestUtility.cs:line 118
at reci.ImageProcessing.Test.TestUtility.buttonKofaxTiff_Click(Object sender, EventArgs e) in C:\TFS\Other\Image Processing\WPF Imaging\codebase\reci.ImageProcessing.Test\TestUtility.cs:line 97
at System.Windows.Forms.Control.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ButtonBase.WndProc(Message& m)
at System.Windows.Forms.Button.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.Run(Form mainForm)
at reci.ImageProcessing.Test.Program.Main() in C:\TFS\Other\Image Processing\WPF Imaging\codebase\reci.ImageProcessing.Test\Program.cs:line 18
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException: ImageMagick.MagickCoderErrorException
HResult=-2146233088
Message=reci.ImageProcessing.Test.vshost.exe: IO error writing tag data. `TIFFWriteDirectoryTagData' @ error/tiff.c/TIFFErrors/560
InnerException:
Presumably this is due to the size of the file (51 pages at 300x300 DPI, 2550x3300 pixels), but I can easily see such files needing to be run through the conversion. Do you have any tips on how I can do things differently to work around this exception?Thanks!