Convert bitmaps to one multipage TIFF image in .NET 2.0
Came across this post after a bit of searching on Google. I tried the code that was in the post by a'b'c'd'e'f'g'h', but that didn't work for me. Perhaps, I was not doing something correctly.
In any case, I found another post that saved images to multi page tiffs. Here is the link to the post: Adding frames to a Multi-Frame TIFF.
Also, here is the code that worked for me. It should be identical to that post.
Encoder encoder = Encoder.SaveFlag;
ImageCodecInfo encoderInfo = ImageCodecInfo.GetImageEncoders().First(i => i.MimeType == "image/tiff");
EncoderParameters encoderParameters = new EncoderParameters(1);
encoderParameters.Param[0] = new EncoderParameter(encoder, (long)EncoderValue.MultiFrame);
// Save the first frame of the multi page tiff
Bitmap firstImage = (Bitmap) _scannedPages[0].RawContent;
firstImage.Save(fileName, encoderInfo, encoderParameters);
encoderParameters.Param[0] = new EncoderParameter(encoder, (long)EncoderValue.FrameDimensionPage);
// Add the remaining images to the tiff
for (int i = 1; i < _scannedPages.Count; i++)
{
Bitmap img = (Bitmap) _scannedPages[i].RawContent;
firstImage.SaveAdd(img, encoderParameters);
}
// Close out the file
encoderParameters.Param[0] = new EncoderParameter(encoder, (long)EncoderValue.Flush);
firstImage.SaveAdd(encoderParameters);
Necromancing
The accepted answer is a bit vague.
Here's full working code:
public class MultiPageTiff
{
private static System.Drawing.Imaging.ImageCodecInfo GetEncoderInfo(string mimeType)
{
System.Drawing.Imaging.ImageCodecInfo[] encoders =
System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders();
if (encoders != null)
{
for (int i = 0; i < encoders.Length; i++)
{
if (encoders[i].MimeType == mimeType)
{
return encoders[i];
} // End if (encoders[i].MimeType == mimeType)
} // Next i
} // End if (encoders != null)
return null;
} // End Function GetEncoderInfo
public static System.Drawing.Image Generate(string[] filez)
{
System.Drawing.Image multiPageFile = null;
byte[] ba = null;
System.Drawing.Imaging.ImageCodecInfo tiffCodec = GetEncoderInfo("image/tiff");
using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
{
for (int i = 0; i < filez.Length; ++i)
{
using (System.Drawing.Image inputImage = System.Drawing.Image.FromFile(filez[i]))
{
using (System.IO.MemoryStream byteStream = new System.IO.MemoryStream())
{
inputImage.Save(byteStream, System.Drawing.Imaging.ImageFormat.Tiff);
if (i == 0)
{
multiPageFile = System.Drawing.Image.FromStream(byteStream);
multiPageFile = SaveImages(tiffCodec, ms, multiPageFile, null);
}
else
{
using (System.Drawing.Image tiffImage = System.Drawing.Image.FromStream(byteStream))
{
multiPageFile = SaveImages(tiffCodec, ms, tiffImage, multiPageFile);
} // End Using tiffImage
}
} // End Using byteStream
} // End Using inputImage
} // Next i
ba = ms.ToArray();
} // End Using ms
System.IO.File.WriteAllBytes(@"d:\mytiff.tiff", ba);
//if (multiPageFile != null)
//{
// multiPageFile.Dispose();
// multiPageFile = null;
//}
return multiPageFile;
}
private static System.Drawing.Image SaveImages(
System.Drawing.Imaging.ImageCodecInfo tiffCodec
, System.IO.MemoryStream outputStream
, System.Drawing.Image tiffImage, System.Drawing.Image firstImage)
{
using (System.Drawing.Imaging.EncoderParameters encParameters =
new System.Drawing.Imaging.EncoderParameters(3))
{
if (firstImage == null)
{
encParameters.Param[0] = new System.Drawing.Imaging.EncoderParameter(
System.Drawing.Imaging.Encoder.SaveFlag
, (long)System.Drawing.Imaging.EncoderValue.MultiFrame // 18L
);
}
else
{
encParameters.Param[0] = new System.Drawing.Imaging.EncoderParameter(
System.Drawing.Imaging.Encoder.SaveFlag
, (long)System.Drawing.Imaging.EncoderValue.FrameDimensionPage // 23L
);
}
encParameters.Param[1] = new System.Drawing.Imaging.EncoderParameter(
System.Drawing.Imaging.Encoder.ColorDepth, 24L
);
encParameters.Param[2] = new System.Drawing.Imaging.EncoderParameter(
System.Drawing.Imaging.Encoder.Compression
, (long)System.Drawing.Imaging.EncoderValue.CompressionLZW
);
if (firstImage == null)
{
firstImage = tiffImage;
((System.Drawing.Bitmap)tiffImage).SetResolution(96, 96);
firstImage.Save(outputStream, tiffCodec, encParameters);
}
else
{
((System.Drawing.Bitmap)tiffImage).SetResolution(96, 96);
firstImage.SaveAdd(tiffImage, encParameters);
}
if (encParameters.Param[0] != null)
encParameters.Param[0].Dispose();
if (encParameters.Param[1] != null)
encParameters.Param[1].Dispose();
if (encParameters.Param[2] != null)
encParameters.Param[2].Dispose();
} // End Using encParameters
return firstImage;
}
}
Start with the first bitmap by putting it into an Image object
Bitmap bitmap = (Bitmap)Image.FromFile(file);
Save the bitmap to memory as tiff
MemoryStream byteStream = new MemoryStream();
bitmap.Save(byteStream, ImageFormat.Tiff);
Put Tiff into another Image object
Image tiff = Image.FromStream(byteStream)
Prepare encoders:
var encoderInfo = ImageCodecInfo.GetImageEncoders().First(i => i.MimeType == "image/tiff");
EncoderParameters encoderParams = new EncoderParameters(2);
encoderParams.Param[0] = new EncoderParameter(Encoder.Compression, (long)EncoderValue.CompressionNone);
encoderParams.Param[1] = new EncoderParameter(Encoder.SaveFlag, (long)EncoderValue.MultiFrame);
Save to file:
tiff.Save(sOutFilePath, encoderInfo, encoderParams);
For subsequent pages, prepare encoders:
EncoderParameters EncoderParams = new EncoderParameters(2);
EncoderParameter SaveEncodeParam = new EncoderParameter(
Encoder.SaveFlag,
(long)EncoderValue.FrameDimensionPage);
EncoderParameter CompressionEncodeParam = new EncoderParameter(
Encoder.Compression, (long)EncoderValue.CompressionNone);
EncoderParams.Param[0] = CompressionEncodeParam;
EncoderParams.Param[1] = SaveEncodeParam;
tiff.SaveAdd(/* next image as tiff - do the same as above with memory */, EncoderParams);
Finally flush the file:
EncoderParameter SaveEncodeParam = new EncoderParameter(
Encoder.SaveFlag, (long)EncoderValue.Flush);
EncoderParams = new EncoderParameters(1);
EncoderParams.Param[0] = SaveEncodeParam;
tiff.SaveAdd(EncoderParams);
That should get you started.