Saturday, December 29, 2007

C#: Class for TIFF manipulation

This is probably the best compilation I have ever made. Whoever is reading this, might as well have contributed in creation of this. Special mention for Bob Powell's tips found at www.bobpowell.net...

using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Text;
using System.Collections;
using System.Threading;
using System.Drawing.Imaging;
using System.IO;

namespace TiffUtil
{

public class TiffUtil
{
#region Variable & Class Definitions

private static System.Drawing.Imaging.ImageCodecInfo tifImageCodecInfo;

private static EncoderParameter tifEncoderParameterMultiFrame;
private static EncoderParameter tifEncoderParameterFrameDimensionPage;
private static EncoderParameter tifEncoderParameterFlush;
private static EncoderParameter tifEncoderParameterCompression;
private static EncoderParameter tifEncoderParameterLastFrame;
private static EncoderParameter tifEncoderParameter24BPP;
private static EncoderParameter tifEncoderParameter1BPP;

private static EncoderParameters tifEncoderParametersPage1;
private static EncoderParameters tifEncoderParametersPageX;
private static EncoderParameters tifEncoderParametersPageLast;

private static System.Drawing.Imaging.Encoder tifEncoderSaveFlag;
private static System.Drawing.Imaging.Encoder tifEncoderCompression;
private static System.Drawing.Imaging.Encoder tifEncoderColorDepth;

private static bool encoderAssigned;

public static string tempDir;
public static bool initComplete;

public TiffUtil(string tempPath)
{
try
{
if (!initComplete)
{
if (!tempPath.EndsWith("\\"))
tempDir = tempPath + "\\";
else
tempDir = tempPath;

Directory.CreateDirectory(tempDir);
initComplete = true;
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
throw ex;
}
}

#endregion

#region Retrieve Page Count of a multi-page TIFF file

public int getPageCount(string fileName)
{
int pageCount = -1;

try
{
Image img = Bitmap.FromFile(fileName);
pageCount = img.GetFrameCount(FrameDimension.Page);
img.Dispose();
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}

return pageCount;
}

public int getPageCount(Image img)
{
int pageCount = -1;
try
{
pageCount = img.GetFrameCount(FrameDimension.Page);
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
return pageCount;
}

#endregion

#region Retrieve multiple single page images from a single multi-page TIFF file

public Image[] getTiffImages(Image sourceImage, int[] pageNumbers)
{
MemoryStream ms = null;
Image[] returnImage = new Image[pageNumbers.Length];

try
{
Guid objGuid = sourceImage.FrameDimensionsList[0];
FrameDimension objDimension = new FrameDimension(objGuid);

for (int i = 0; i < pageNumbers.Length; i++)
{
ms = new MemoryStream();
sourceImage.SelectActiveFrame(objDimension, pageNumbers[i]);
sourceImage.Save(ms, ImageFormat.Tiff);
returnImage[i] = Image.FromStream(ms);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
ms.Close();
}

return returnImage;
}

public Image[] getTiffImages(Image sourceImage)
{
MemoryStream ms = null;
int pageCount = getPageCount(sourceImage);

Image[] returnImage = new Image[pageCount];

try
{
Guid objGuid = sourceImage.FrameDimensionsList[0];
FrameDimension objDimension = new FrameDimension(objGuid);

for (int i = 0; i < pageCount; i++)
{
ms = new MemoryStream();
sourceImage.SelectActiveFrame(objDimension, i);
sourceImage.Save(ms, ImageFormat.Tiff);
returnImage[i] = Image.FromStream(ms);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
ms.Close();
}

return returnImage;
}

public Image[] getTiffImages(string sourceFile, int[] pageNumbers)
{
Image[] returnImage = new Image[pageNumbers.Length];

try
{
Image sourceImage = Bitmap.FromFile(sourceFile);
returnImage = getTiffImages(sourceImage, pageNumbers);
sourceImage.Dispose();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
returnImage = null;
}

return returnImage;
}

#endregion

#region Retrieve a specific page from a multi-page TIFF image

public Image getTiffImage(string sourceFile, int pageNumber)
{
Image returnImage = null;

try
{
Image sourceImage = Image.FromFile(sourceFile);
returnImage = getTiffImage(sourceImage, pageNumber);
sourceImage.Dispose();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
returnImage = null;
}

return returnImage;
}

public Image getTiffImage(Image sourceImage, int pageNumber)
{
MemoryStream ms = null;
Image returnImage = null;

try
{
ms = new MemoryStream();
Guid objGuid = sourceImage.FrameDimensionsList[0];
FrameDimension objDimension = new FrameDimension(objGuid);
sourceImage.SelectActiveFrame(objDimension, pageNumber);
sourceImage.Save(ms, ImageFormat.Tiff);
returnImage = Image.FromStream(ms);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
ms.Close();
}

return returnImage;
}

public bool getTiffImage(string sourceFile, string targetFile, int pageNumber)
{
bool response = false;

try
{
Image returnImage = getTiffImage(sourceFile, pageNumber);
returnImage.Save(targetFile);
returnImage.Dispose();
response = true;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}

return response;
}

#endregion

#region Split a multi-page TIFF file into multiple single page TIFF files

public string[] splitTiffPages(string sourceFile, string targetDirectory)
{
string[] returnImages;

try
{
Image sourceImage = Bitmap.FromFile(sourceFile);
Image[] sourceImages = splitTiffPages(sourceImage);

int pageCount = sourceImages.Length;

returnImages = new string[pageCount];
for (int i = 0; i < pageCount; i++)
{
FileInfo fi = new FileInfo(sourceFile);
string babyImg = targetDirectory + "\\" + fi.Name.Substring(0, (fi.Name.Length - fi.Extension.Length)) + "_PAGE" + (i + 1).ToString().PadLeft(3, '0') + fi.Extension;
sourceImages[i].Save(babyImg);
returnImages[i] = babyImg;
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
returnImages = null;
}

return returnImages;
}

public Image[] splitTiffPages(Image sourceImage)
{
Image[] returnImages;

try
{
int pageCount = getPageCount(sourceImage);
returnImages = new Image[pageCount];

for (int i = 0; i < pageCount; i++)
{
Image img = getTiffImage(sourceImage, i);
returnImages[i] = (Image)img.Clone();
img.Dispose();
}

}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
returnImages = null;
}

return returnImages;
}

#endregion

#region Merge multiple single page TIFF to a single multi page TIFF

public bool mergeTiffPages(string[] sourceFiles, string targetFile)
{
bool response = false;

try
{
assignEncoder();

// If only 1 page was passed, copy directly to output
if (sourceFiles.Length == 1)
{
File.Copy(sourceFiles[0], targetFile, true);
return true;
}

int pageCount = sourceFiles.Length;

// First page
Image finalImage = Image.FromFile(sourceFiles[0]);
finalImage.Save(targetFile, tifImageCodecInfo, tifEncoderParametersPage1);

// All other pages
for (int i = 1; i < pageCount; i++)
{
Image img = Image.FromFile(sourceFiles[i]);
finalImage.SaveAdd(img, tifEncoderParametersPageX);
img.Dispose();
}

// Last page
finalImage.SaveAdd(tifEncoderParametersPageLast);
finalImage.Dispose();
response = true;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
response = false;
}

return response;
}

public bool mergeTiffPages(string sourceFile, string targetFile, int[] pageNumbers)
{
bool response = false;

try
{
assignEncoder();

// Get individual Images from the original image
Image sourceImage = Bitmap.FromFile(sourceFile);
MemoryStream ms = new MemoryStream();
Image[] sourceImages = new Image[pageNumbers.Length];
Guid guid = sourceImage.FrameDimensionsList[0];
FrameDimension objDimension = new FrameDimension(guid);
for (int i = 0; i < pageNumbers.Length; i++)
{
sourceImage.SelectActiveFrame(objDimension, pageNumbers[i]);
sourceImage.Save(ms, ImageFormat.Tiff);
sourceImages[i] = Image.FromStream(ms);
}

// Merge individual Images into one Image
// First page
Image finalImage = sourceImages[0];
finalImage.Save(targetFile, tifImageCodecInfo, tifEncoderParametersPage1);
// All other pages
for (int i = 1; i < pageNumbers.Length; i++)
{
finalImage.SaveAdd(sourceImages[i], tifEncoderParametersPageX);
}
// Last page
finalImage.SaveAdd(tifEncoderParametersPageLast);
finalImage.Dispose();

response = true;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}

return response;
}

public bool mergeTiffPagesAlternate(string sourceFile, string targetFile, int[] pageNumbers)
{
bool response = false;

try
{
// Initialize the encoders, occurs once for the lifetime of the class
assignEncoder();

// Get individual Images from the original image
Image sourceImage = Bitmap.FromFile(sourceFile);
MemoryStream[] msArray = new MemoryStream[pageNumbers.Length];
Guid guid = sourceImage.FrameDimensionsList[0];
FrameDimension objDimension = new FrameDimension(guid);
for (int i = 0; i < pageNumbers.Length; i++)
{
msArray[i] = new MemoryStream();
sourceImage.SelectActiveFrame(objDimension, pageNumbers[i]);
sourceImage.Save(msArray[i], ImageFormat.Tiff);
}

// Merge individual page streams into single stream
MemoryStream ms = mergeTiffStreams(msArray);
Image targetImage = Bitmap.FromStream(ms);
targetImage.Save(targetFile);

response = true;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}

return response;
}

public System.IO.MemoryStream mergeTiffStreams(System.IO.MemoryStream[] tifsStream)
{
EncoderParameters ep = null;
System.IO.MemoryStream singleStream = new System.IO.MemoryStream();

try
{
assignEncoder();

Image imgTif = Image.FromStream(tifsStream[0]);

if (tifsStream.Length > 1)
{
// Multi-Frame
ep = new EncoderParameters(2);
ep.Param[0] = new EncoderParameter(tifEncoderSaveFlag, (long)EncoderValue.MultiFrame);
ep.Param[1] = new EncoderParameter(tifEncoderCompression, (long)EncoderValue.CompressionRle);
}
else
{
// Single-Frame
ep = new EncoderParameters(1);
ep.Param[0] = new EncoderParameter(tifEncoderCompression, (long)EncoderValue.CompressionRle);
}

//Save the first page
imgTif.Save(singleStream, tifImageCodecInfo, ep);

if (tifsStream.Length > 1)
{
ep = new EncoderParameters(2);
ep.Param[0] = new EncoderParameter(tifEncoderSaveFlag, (long)EncoderValue.FrameDimensionPage);

//Add the rest of pages
for (int i = 1; i < tifsStream.Length; i++)
{
Image pgTif = Image.FromStream(tifsStream[i]);

ep.Param[1] = new EncoderParameter(tifEncoderCompression, (long)EncoderValue.CompressionRle);

imgTif.SaveAdd(pgTif, ep);
}

ep = new EncoderParameters(1);
ep.Param[0] = new EncoderParameter(tifEncoderSaveFlag, (long)EncoderValue.Flush);
imgTif.SaveAdd(ep);
}
}
catch (Exception ex)
{
throw ex;
}
finally
{
if (ep != null)
{
ep.Dispose();
}
}

return singleStream;
}

#endregion

#region Internal support functions

private void assignEncoder()
{
try
{
if (encoderAssigned == true)
return;

foreach(ImageCodecInfo ici in ImageCodecInfo.GetImageEncoders())
{
if (ici.MimeType == "image/tiff")
{
tifImageCodecInfo = ici;
}
}

tifEncoderSaveFlag = System.Drawing.Imaging.Encoder.SaveFlag;
tifEncoderCompression = System.Drawing.Imaging.Encoder.Compression;
tifEncoderColorDepth = System.Drawing.Imaging.Encoder.ColorDepth;

tifEncoderParameterMultiFrame = new EncoderParameter(tifEncoderSaveFlag, (long)EncoderValue.MultiFrame);
tifEncoderParameterFrameDimensionPage = new EncoderParameter(tifEncoderSaveFlag, (long)EncoderValue.FrameDimensionPage);
tifEncoderParameterFlush = new EncoderParameter(tifEncoderSaveFlag, (long)EncoderValue.Flush);
tifEncoderParameterCompression = new EncoderParameter(tifEncoderCompression, (long)EncoderValue.CompressionRle);
tifEncoderParameterLastFrame = new EncoderParameter(tifEncoderSaveFlag, (long)EncoderValue.LastFrame);
tifEncoderParameter24BPP = new EncoderParameter(tifEncoderColorDepth, (long)24);
tifEncoderParameter1BPP = new EncoderParameter(tifEncoderColorDepth, (long)8);

// ******************************************************************* //
// *** Have only 1 of the following 3 groups assigned for encoders *** //
// ******************************************************************* //

// Regular
tifEncoderParametersPage1 = new EncoderParameters(1);
tifEncoderParametersPage1.Param[0] = tifEncoderParameterMultiFrame;
tifEncoderParametersPageX = new EncoderParameters(1);
tifEncoderParametersPageX.Param[0] = tifEncoderParameterFrameDimensionPage;
tifEncoderParametersPageLast = new EncoderParameters(1);
tifEncoderParametersPageLast.Param[0] = tifEncoderParameterFlush;

//// Regular
//tifEncoderParametersPage1 = new EncoderParameters(2);
//tifEncoderParametersPage1.Param[0] = tifEncoderParameterMultiFrame;
//tifEncoderParametersPage1.Param[1] = tifEncoderParameterCompression;
//tifEncoderParametersPageX = new EncoderParameters(2);
//tifEncoderParametersPageX.Param[0] = tifEncoderParameterFrameDimensionPage;
//tifEncoderParametersPageX.Param[1] = tifEncoderParameterCompression;
//tifEncoderParametersPageLast = new EncoderParameters(2);
//tifEncoderParametersPageLast.Param[0] = tifEncoderParameterFlush;
//tifEncoderParametersPageLast.Param[1] = tifEncoderParameterLastFrame;

//// 24 BPP Color
//tifEncoderParametersPage1 = new EncoderParameters(2);
//tifEncoderParametersPage1.Param[0] = tifEncoderParameterMultiFrame;
//tifEncoderParametersPage1.Param[1] = tifEncoderParameter24BPP;
//tifEncoderParametersPageX = new EncoderParameters(2);
//tifEncoderParametersPageX.Param[0] = tifEncoderParameterFrameDimensionPage;
//tifEncoderParametersPageX.Param[1] = tifEncoderParameter24BPP;
//tifEncoderParametersPageLast = new EncoderParameters(2);
//tifEncoderParametersPageLast.Param[0] = tifEncoderParameterFlush;
//tifEncoderParametersPageLast.Param[1] = tifEncoderParameterLastFrame;

//// 1 BPP BW
//tifEncoderParametersPage1 = new EncoderParameters(2);
//tifEncoderParametersPage1.Param[0] = tifEncoderParameterMultiFrame;
//tifEncoderParametersPage1.Param[1] = tifEncoderParameterCompression;
//tifEncoderParametersPageX = new EncoderParameters(2);
//tifEncoderParametersPageX.Param[0] = tifEncoderParameterFrameDimensionPage;
//tifEncoderParametersPageX.Param[1] = tifEncoderParameterCompression;
//tifEncoderParametersPageLast = new EncoderParameters(2);
//tifEncoderParametersPageLast.Param[0] = tifEncoderParameterFlush;
//tifEncoderParametersPageLast.Param[1] = tifEncoderParameterLastFrame;

encoderAssigned = true;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
throw ex;
}
}

private Bitmap ConvertToGrayscale(Bitmap source)
{
try
{
Bitmap bm = new Bitmap(source.Width, source.Height);
Graphics g = Graphics.FromImage(bm);

ColorMatrix cm = new ColorMatrix(new float[][]{new float[]{0.5f,0.5f,0.5f,0,0}, new float[]{0.5f,0.5f,0.5f,0,0}, new float[]{0.5f,0.5f,0.5f,0,0}, new float[]{0,0,0,1,0,0}, new float[]{0,0,0,0,1,0}, new float[]{0,0,0,0,0,1}});
ImageAttributes ia = new ImageAttributes();
ia.SetColorMatrix(cm);
g.DrawImage(source, new Rectangle(0, 0, source.Width, source.Height), 0, 0, source.Width, source.Height, GraphicsUnit.Pixel, ia);
g.Dispose();

return bm;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
throw ex;
}
}

#endregion
}
}

41 comments:

  1. OK, so I am assuming you figured this out, right?

    ReplyDelete
  2. Hi Kaushik,

    Yes I got it done. Your tiff code has made my task very easy. I am sure it is very helpful to lot of developers. Thank you somuch.

    Thanks & Regards,
    Sowjanya

    ReplyDelete
  3. First off want to say it is very good code. One method I wanted to add was 'mergeTiffFiles' which would Merge multiple multi/single page TIFFs to a single multi page TIFF. Now you have most of the code written for single page processing. Is it best to reuse that code or is there a simpler way to merge multiple tiff files using .NET? Below is the method I tried creating. I also had to make another overload method for mergeTiffPages.

    public bool mergeTiffFiles(string[] sourceFiles, string targetFile)
    {
    bool response = false;

    // If only 1 file was passed, copy directly to output
    if (sourceFiles.Length == 1)
    {
    File.Copy(sourceFiles[0], targetFile, true);
    return true;
    }

    //Get the total page count for all files that will be combined
    int intTotalPageCount = 0;
    for (int temp = 0; temp < sourceFiles.Length; temp++)
    intTotalPageCount += getPageCount(sourceFiles[temp]);

    //Get all the pages of all files into one image array
    Image[] allImages = new Image[intTotalPageCount];
    int pageCounter = 0;
    foreach (string file in sourceFiles)
    {
    Image sourceImage = Bitmap.FromFile(file);
    Image[] imgArray = getTiffImages(sourceImage);
    foreach (Image img in imgArray)
    {
    allImages[pageCounter] = img;
    pageCounter++;
    img.Dispose();
    }
    sourceImage.Dispose();
    }

    //combine all images into one tiff file
    if (mergeTiffPages(allImages, targetFile))
    return true;

    return response;
    }

    ReplyDelete
  4. Tom, you are right. I would have probably done the same thing if I needed to use only 1 function. Since I have so many overloaded method signatures, in order to avoid code repeated all over the place, I routed pretty much everything through the 1 main function. We should always tweak and simplify it to make sure we get the best performance out of it... But I appreciate your comments!

    ReplyDelete
  5. Hi Kaushik,

    Let me know if you have similar C# code to perform similar operations on a multi paged PDF image? For ex: To split a multipagedPDF image to single pages, access one page at a time, find the count of total pages, merge the multiple PDF pages to a single PDF image..etc ? If you have, please do send me the code to sowji250@gmail.com

    Thanks & Regards,
    Sowjanya V

    ReplyDelete
  6. Sowjanya,
    Check out the PDFSharp free libraries (www.pdfsharp.com) for PDF manipulation. They are native C# code too. I have tried the API's for some personal project, and my experience was real good.
    Thanks,
    Kaushik

    ReplyDelete
  7. Hi,
    Kaushik.
    Here I am getting one exception for this function.

    public bool mergeTiffPages(string sourceFile, string targetFile, int[] pageNumbers)

    In this
    finalImage.Save(targetFile, tifImageCodecInfo, tifEncoderParametersPage1) Line giving error. A generic error occurred in GDI +.
    Kindly look into this.


    My task is store data into Database as a Blob.
    So for some bullk of pages I wanna single tiff image and want to store in Blob data.
    If any othe metod for same then please help me.
    Thanks,
    Tejal

    ReplyDelete
  8. Hi Tejal,

    Sorry I could not respond to your question earlier, was busy with TechEd and some other work related stuff. I am sure you have probably figured the issue out already but if not may be I can help...

    Exception handling within GDI+ routines is not very graceful, so in most cases "A generic error occurred in GDI+" message is thrown. If you look through in search engines you will find that many people have got this error for many different reasons but the most common reason I have seen if due to write access permission on the file during the execution.

    For this particular method that you are using, the only reason I can think of is not being able to write to the location where the final image need to be saved. Put a breakpoint right before executing this line of code, and try to see if you can manually write to the file at that location and save.

    I would appreciate if you could share what you found out.

    Thanks,
    KC

    ReplyDelete
  9. Hi,

    I had a similar issue where i was trying to a specific page from the image. The page count starts from so we have to give the correct page number (2 for 3rd page) etc.
    I had 2 pages and when i tried with the 2 value i got an error. i tried with 1 and it worked.

    Just wanted to share it with you all.

    ReplyDelete
  10. Hi,

    I have embedded a multi page tiff file as base64 string into a xml file. But while decoding that base64 string back to TIF image, it is just giving one page instead of all pages in the original multi page tiff. Do you have any idea about this scenario?

    Really appreciate your help on TIFF realted tasks.

    Thanks & Regards,
    Sowjanya V

    ReplyDelete
  11. I am using the method "mergeTiffStreams" to merge memory streams.

    the following line throws an exception "Parameter is not valid."

    //Save the first page
    imgTif.Save(singleStream, tifImageCodecInfo, ep);

    ReplyDelete
  12. nice article, you can also see my vb.net tiff viewer...

    ReplyDelete
  13. Dear Sir,

    I have a launched new web site for .NET programming resources. www.codegain.com. I would like to invite to the codegain.com as author and supporter. I hope you will joins with us soon.

    Thank You
    RRaveen
    Founder www.codegain.com

    ReplyDelete
  14. Can you make the code available as a separate download file, so I don't have to re-format everything?

    ReplyDelete
  15. Hi Its Dharma,
    Can you attach the code for converting the TIFF files to text files.
    Regards,
    Dharma

    ReplyDelete
  16. Great work! I was wondering if you can suggest me some way which can help me convert all the major file formats into tiff images.

    Any help would be highly appreciated.

    ReplyDelete
  17. The 'public bool mergeTiffPages(string[] sourceFiles, string targetFile)'method does not work correctly. It only appends the first page of any multipage TIFF files in all files beyond the first one in the sourceFiles[] array.

    Also, some TIFF property tags are lost during conversion. NewSubfileType is incorrectly set to [Zero] (0), FillOrder is lost, and the PageNumber tag is not set properly.

    Just thought you should know.

    ReplyDelete
  18. Great class, one issue I am having though is that I am receiving an out of memory exception when I try to merge 3 or 4 .tiff files. I'm not sure why this is as I thought the img.Dispose() function would help in preventing this.

    ReplyDelete
  19. Hello my friend im trying to recreate this code however I were not able to do so,would be possible to get this by mail? looks like its exactly what
    I was looking for. rhedersilva@hotmail.com
    thank you

    ReplyDelete
  20. Can someone convert this C# to VB.NET??

    Thanks

    Ed

    ReplyDelete
  21. Dear KC,
    I have been through all the methods of this class and it seems containing a lot of fucntionalities that one would like to have about Tiffs.
    I want a guidance from you. I have requirement that I have a 6 page Tiff file (6 pages in a single file) and i want to convert it into a single Tif File so that the first 3 pages come in first row and the next 3 pages come in the second row of the resultant single page Tif file. Can you tell me if your code can do this and, if yes, which of the methods above can do this? Remember a single 6 pages Tiff file needs to be reproduced into a single Tiff file with all the 6 pages arranged in 2 rows.
    Thanks
    Kashif

    ReplyDelete
  22. Dear KC,

    Thanks, a huge help.

    I'm having trouble opening a color .tiff and wondering if anyone else has come across this. Calling Image.FromStream on the .tiff throws an "invalid parameter" error. Calling Bitmap.FromFile on the .tiff throws a "System.OutOfMemory" error. The .tiff itself is not corrupt, I can open it using MS Picture Manager or MS Document Imaging (although when I open it using Windows Picture and Fax Viewer I get a "preview not available" message). The image comes from a scanned document; when I scan the document in black & white it opens fine, this certainly has to do with it being a color image.

    ReplyDelete
  23. Tom, regarding your image error, your scanner may be saving the tif file as a "jpeg in Tiff" format, which has been an issue I've been pounding my head against for the last week. If this is the case, I've only found one tool so far to solve the issue which is not open source. I hope that's not it.

    ReplyDelete
  24. Hi,

    When splitting TIFF image i got "Generidc Error in GDI+" the file has 110 frames after 95 frames i got above error.

    Please let me know how to solve this.
    I got error at "SelectActiveFrame" method when splitting image.

    Regards
    Siva Prasad

    ReplyDelete
  25. Hi, This was of great help. My problem I am getting is that I can create a new tif file but when I attempt to append additional pages to the TIF file I get the error "Generic Error in GDI+". The error occurs in the "SaveImageExistingSinglePage" method at the line ( origionalFile.Save(location, codecInfo, EncoderParams);).

    I appreciate any help. thanks

    ReplyDelete
  26. Hi. I hate to say this, but could you tell me what I need to do to get this to work with in my app. I built it as a stand alone class and added it as a com reference. Do I still need to register the .dll before I can use it. I would appreciate a little guidance on this.

    Thanks,
    Charles

    ReplyDelete
  27. Hi
    How can I access the CMYK channels of a TIFF image?
    Thanks

    ReplyDelete
  28. I am using the method "mergeTiffStreams" to merge memory streams.

    the following line throws an exception "Parameter is not valid."

    //Save the first page
    imgTif.Save(singleStream, tifImageCodecInfo, ep);

    How can i fix that error?

    ReplyDelete
  29. Hello KC,

    I am new to C# code. What I am trying is to convert a .tif to .gif

    I've used be below code, it converts but I am unable to view the .gif (which is created from the output from the code below) using internet explorer. Probably there is some mistake in me loading the file as Bitmap. Here is the code i've used.

    Bitmap bm = (Bitmap)Bitmap.FromFile(sourceDoc);
    bm.Save(outputDoc, ImageFormat.Gif);

    How can I fix this problem and what wrong i am doing here.

    ReplyDelete
  30. Thanks a lot...
    This code is really awesome!!
    I did copy and paste and every this is working fine...
    Keep doing good work :)

    ReplyDelete
  31. Hello Kaushik. The method MergeTiffStreams() is not working for me. I did a direct copy and paste and it did not work. Do you have an updated version?

    ReplyDelete
  32. A generic error occurred in GDI+. Anyone pls tell how to solve this error.

    ReplyDelete
  33. Its work for me.perfectly.!

    see this code which he copied

    http://clouddetector.googlecode.com/svn-history/r2/trunk/CloudDetector/TiffUtil.cs

    ReplyDelete
  34. Hi Kaushik,

    I was googling around to find a fix for "TIF images not shown in IE".The image works fine with FireFox, anything you could point to or suggest to this issue can be a great help.

    Thanks,

    JJ

    ReplyDelete
  35. If I use Compression encoder, Image.Save throws Parameter Not Valid exception.

    ReplyDelete
  36. In your method:

    splitTiffPages(string sourceFile, string targetDirectory)

    ...you need to add:

    sourceImage.Dispose(); // needed to release file

    ...after the for loop otherwise the original TIFF file remains locked until program exit.

    ReplyDelete
  37. Thank you sooo much for your contribution. You have helped sooo many of us out in the "internet cloud' add better features to our corporations. My team is wondering if part of your posts are copyrighted, or can we use in commercial software as well?

    ReplyDelete
  38. Dear "mr.",
    I am glad my post was able to help you and your corporation out. Like any internet blog, I will be honest in saying that I do not take 100% credit for all my posts, but I do add my own thoughts into most of them after I gather tidbits from the "internet cloud". So you may feel free to use code snippets posted on my blog. But I would strongly request for you and your corporation to recognize my efforts by making a small donation via paypal to support the cause. Thanks!

    ReplyDelete
  39. I'm also unable to get the mergeTiffStreams method to work. All I receive back is a stream that contains the first TIFF. Any advice would be appreciated. Thanks.

    ReplyDelete

Please use your common sense before making a comment, and I truly appreciate your constructive criticisms.