Wednesday, May 23, 2012

Tifflib Convert multipage Tiffs to a single stitched jpeg image

I was facing issues reading 8 bit tiff files using .net GDI+ as it do not support all Tiff formats so i opt to use tifflib(an open source library to manipulate tiff files) to read the tiff images and create a 16bit tiff image from it and then create a single stitched jpeg image. converting tiffs to jpeg is not ideal because jpeg will be very large in size but i have done this because in silverlight we have no support to display tiff natively. 

Hope this will help the others

 public bool convertTiffToJpg(string sourceFile, string targetFile)
        {

            bool response = false;

            try
            {

                // Get individual Images from the original image
                //Image sourceImage = Bitmap.FromFile(sourceFile,true);
                Image sourceImage = getBitmap8Bit(sourceFile);

                var total = sourceImage.GetFrameCount(FrameDimension.Page);
                var pageNumbers = Enumerable.Range(0, total).ToArray();
                Image[] sourceImages = new Image[pageNumbers.Length];
                for (int i = 0; i < pageNumbers.Length; i++)
                {
                    sourceImage.SelectActiveFrame(FrameDimension.Page, pageNumbers[i]);
                    float width = sourceImage.Width;
                    float height = sourceImage.Height;
                    ResizeImage(1024, sourceImage.Height, ref width, ref height);

                    using (var returnImage = new Bitmap(sourceImage, (int)width, (int)height))
                    {
                        using (MemoryStream ms = new MemoryStream())
                        {
                            returnImage.Save(ms, ImageFormat.Jpeg);
                            sourceImages[i] = Image.FromStream(ms);
                        }
                    }
                }
                var p = new System.Collections.ArrayList();
                p.Add(Color.Black);
                p.Add(Color.Gray);
                p.Add(Color.LightGray);
                p.Add(Color.DarkGray);
                p.Add(Color.White);
                PaletteQuantizer quantizer = new PaletteQuantizer(p);
                //OctreeQuantizer quantizer = new OctreeQuantizer(2,2);
                //var quantizer = new WuQuantizer();
                // Merge individual Images into one Image
                var totalHeight = sourceImages.FirstOrDefault().Height * total;
                var totalWidth = sourceImages.FirstOrDefault().Width;
                using (var finalImage = new Bitmap(totalWidth, totalHeight))
                {

                    using (var g = Graphics.FromImage(finalImage))
                    {
                        g.InterpolationMode = InterpolationMode.Low;
                        g.PixelOffsetMode = PixelOffsetMode.HighSpeed;

                        // All other pages
                        for (int i = 0; i < pageNumbers.Length; i++)
                        {
                            g.DrawImage(sourceImages[i], new Point(0, sourceImages[i].Height * i));
                        }
                    }

                    //finalImage.MakeTransparent(Color.White);
                    using (var toout = quantizer.Quantize(finalImage))
                    {
                        ImageCodecInfo Codec = ImageCodecInfo.GetImageEncoders().Where(codec => codec.FormatID.Equals(ImageFormat.Png.Guid)).FirstOrDefault();
                        toout.Save(targetFile, Codec, GetCodedParams(null));
                    }

                }

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

            return response;
        }

 private static Image getBitmap8Bit(string inputName)
        {

            Encoder enc = Encoder.SaveFlag;
            EncoderParameters ep = new EncoderParameters(1);
            ep.Param[0] = new EncoderParameter(enc, (long)EncoderValue.MultiFrame);
            ImageCodecInfo info = GetEncoderInfo();
            foreach (ImageCodecInfo ice in ImageCodecInfo.GetImageEncoders())
                if (ice.MimeType == "image/tiff")
                    info = ice;

            MemoryStream ms = new MemoryStream();
            Bitmap result = null;
            using (Tiff tif = Tiff.Open(inputName, "r"))
            {
                short dirs = tif.NumberOfDirectories();

                for (int page = 0; page < dirs; page++)
                {
                    if (tif.SetDirectory((short)page))
                    {
                        FieldValue[] value = tif.GetField(TiffTag.IMAGEWIDTH);
                        int width = value[0].ToInt();

                        value = tif.GetField(TiffTag.IMAGELENGTH);
                        int height = value[0].ToInt();

                        int imageSize = height * width;
                        int[] raster = new int[imageSize];

                        if (tif.ReadRGBAImage(width, height, raster))
                        {
                            var bitmap = new Bitmap(width, height);
                            for (int i = 0; i < bitmap.Width; ++i)
                                for (int j = 0; j < bitmap.Height; ++j)
                                    bitmap.SetPixel(i, j, getSample(i, j, raster, width, height));
                            if (result == null)
                            {
                                result = bitmap;
                                result.Save(ms, info, ep);
                                ep.Param[0] = new EncoderParameter(enc, (long)EncoderValue.FrameDimensionPage);
                            }
                            else
                            {
                                result.SaveAdd((bitmap as Image), ep);
                            }
                        }
                    }
                }
            }
            ep.Param[0] = new EncoderParameter(enc, (long)EncoderValue.Flush);
            result.SaveAdd(ep);
            return Image.FromStream(ms);


        }

1 comment:

Unknown said...

nice post on Shoaib Sheikh's Blog........
Multipage Tiff Convert