1
votes

I am trying to understand and implement a piece of code for Tiff compression.

I have already used 2 separate techniques - Using 3rd party dll's LibTiff.NEt (1st method is bulky) and the Image save method, http://msdn.microsoft.com/en-us/library/ytz20d80%28v=vs.110%29.aspx (2nd method works only on windows 7 machine but not on windows 2003 or 2008 server).

Now I am looking to explore this 3rd method.

using System.Windows.Forms;
using System.Windows.Media.Imaging;
using System.Drawing.Imaging;

        int width = 800;
        int height = 1000;
        int stride = width/8;
        byte[] pixels = new byte[height*stride];

        // Try creating a new image with a custom palette.
        List<System.Windows.Media.Color> colors = new List<System.Windows.Media.Color>();
        colors.Add(System.Windows.Media.Colors.Red);
        colors.Add(System.Windows.Media.Colors.Blue);
        colors.Add(System.Windows.Media.Colors.Green);
        BitmapPalette myPalette = new BitmapPalette(colors);

        // Creates a new empty image with the pre-defined palette

        BitmapSource image = BitmapSource.Create(
            width,
            height,
            96,
            96,
            System.Windows.Media.PixelFormats.BlackWhite,
            myPalette, 
            pixels, 
            stride);


FileStream stream = new FileStream(Original_File, FileMode.Create);
TiffBitmapEncoder encoder = new TiffBitmapEncoder();
encoder.Compression = TiffCompressOption.Ccitt4;
encoder.Frames.Add(BitmapFrame.Create(image));
encoder.Save(stream);

But I don't have a full understanding of what is happening here.

There is obviously some kind of a memory stream that the compression technique is being applied to. But I am a bit confused how to apply this to my specific case. I have an original tiff file, I want to use this method to set its compression to CCITT and save it back. Can anyone help?

I copied the above code and the code runs. But my end output file is a solid black background image. Although on the positive side it is of the correct compression type.

http://msdn.microsoft.com/en-us/library/ms616002%28v=vs.110%29.aspx

http://msdn.microsoft.com/en-us/library/system.windows.media.imaging.tiffcompressoption%28v=vs.100%29.aspx

http://social.msdn.microsoft.com/Forums/vstudio/en-US/1585c562-f7a9-4cfd-9674-6855ffaa8653/parameter-is-not-valid-for-compressionccitt4-on-windows-server-2003-and-2008?forum=netfxbcl

1
Why did you add the asp.net tag? Are you doing this is an asp.net project? - mbeckish
yes. I have a web page, that allows user input, which is then converted into a tiff file. This tiff file's original compression type is LZW. I need it in CCITT compression format. - Philo
PixelFormats is in System.Windows.Media, not System.Windows.Media.Imaging. - mbeckish
thanks, now my code runs, but the output file I get doesn't have any image or properties...when I open the file I get the message windows photo editor cannot open the file, because it is being used in another application. - Philo

1 Answers

0
votes

LibTiff.net is a little bulky because it's based off LibTiff, which has its own set of problems.

My company (Atalasoft) has the ability to do that fairly easily, and the free version of the SDK will do the task you want with a few restrictions. The code for re-encoding a file would look like this:

public bool ReencodeFile(string path)
{
    AtalaImage image = new AtalaImage(path);
    if (image.PixelFormat == PixelFormat.Pixel1bppIndexed)
    {
        TiffEncoder encoder = new TiffEncoder();
        encoder.Compression = TiffCompression.Group4FaxEncoding;
        image.Save(path, encoder, null); // destroys the original - use carefully
        return true;
    }
    return false;
}

Things you should be aware of:

  • this code will only work properly on 1bpp images
  • this code will NOT work properly on multi-page TIFFs
  • this code does NOT preserve metadata within the original file

and I would want the code to at least check for that. If you are inclined to have a solution that better preserves what's in the content of the file, you would want to do this:

public bool ReencodeFile(string origPath, string outputPath)
{
    if (origPath == outputPath) throw new ArgumentException("outputPath needs to be different from input path.");
    TiffDocument doc = new TiffDocuemnt(origPath);

    bool needsReencoding = false;
    for (int i=0; i < doc.Pages; i++) {
        if (doc.Pages[i].PixelFormat == PixelFormat.Pixel1bppIndexed) {
            doc.Pages[i] = new TiffPage(new AtalaImage(origPath, i, null), TiffCompression.Group4FaxEncoding);
            needsReencoding = true;
        }
    }
    if (needsReendcoding)
        doc.Save(outputPath);
    return needsReencoding;
}

This solution will respect all pages within the document as well as document metadata.