How can i convert an array of bitmaps into a brand new image of TIFF format, adding all the bitmaps as frames in this new tiff image?
using .NET 2.0.
How can i convert an array of bitmaps into a brand new image of TIFF format, adding all the bitmaps as frames in this new tiff image?
using .NET 2.0.
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.
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;
}
}
Not being a fan of Microsoft's track record when it comes to handling and creating files of standardized formats, I would suggest using ImageMagick, available as a .Net library in the form of MagickNet (beware, http://midimick.com/magicknet/ currently has a spyware popup, I have alerted the site owner).
Here is how to do this in vb.net:
Imports System.Drawing.Imaging
Sub CreateTiff(sOutTiffFile As String, sInFile1 As String, sInFile2 As String)
Dim bitmap As Bitmap = Image.FromFile(sInFile1)
Dim byteStream As MemoryStream = New MemoryStream()
bitmap.Save(byteStream, System.Drawing.Imaging.ImageFormat.Tiff)
Dim tiff As Image = Image.FromStream(byteStream)
Dim oParams As EncoderParameters = New EncoderParameters(2)
oParams.Param(0) = New EncoderParameter(Imaging.Encoder.Compression, EncoderValue.CompressionCCITT4)
oParams.Param(1) = New EncoderParameter(Imaging.Encoder.SaveFlag, EncoderValue.MultiFrame)
tiff.Save(sOutTiffFile, GetEncoderInfo("image/tiff"), oParams)
'Next Page
Dim bitmap2 As Bitmap = Image.FromFile(sInFile2)
oParams.Param(1) = New EncoderParameter(Imaging.Encoder.SaveFlag, EncoderValue.FrameDimensionPage)
tiff.SaveAdd(bitmap2, oParams)
'Flush
Dim oFlushParams As EncoderParameters = New EncoderParameters(1)
oFlushParams.Param(0) = New EncoderParameter(Imaging.Encoder.SaveFlag, EncoderValue.Flush)
tiff.SaveAdd(oFlushParams)
End Sub
Private Function GetEncoderInfo(mimeType As String) As System.Drawing.Imaging.ImageCodecInfo
Dim encoders = System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders()
For i As Integer = 0 To encoders.Length - 1
If encoders(i).MimeType = mimeType Then
Return encoders(i)
End If
Next
Return Nothing
End Function