0

我需要使用 .net 将黑白颜色的 tiff 文件转换为 png。但我无法将颜色深度降低到每像素 8 位。它总是以每像素 24 位输出文件。有什么办法可以在.net中做到这一点?或任何开源托管库这样做?

我正在使用的代码。

public bool convertTiffToJpg(string sourceFile, string targetFile)
        {

            bool response = false;

            try
            {

                // Get individual Images from the original image
                Image sourceImage = Bitmap.FromFile(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(1000, 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);
                        }
                    }
                }

                // 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))
                    {
                        // All other pages
                        for (int i = 0; i < pageNumbers.Length; i++)
                        {
                            g.DrawImage(sourceImages[i], new Point(0, sourceImages[i].Height * i));
                        }
                    }
                        ImageCodecInfo Codec = ImageCodecInfo.GetImageEncoders().Where(codec => codec.FormatID.Equals(ImageFormat.Png.Guid)).FirstOrDefault();

                        finalImage.Save(targetFile, Codec, GetCodedParams(50));
                }

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

            return response;
        }

private EncoderParameters GetCodedParams(int? quality)
        {
            var imageQuality = quality ?? 80;
            EncoderParameter ratio = new EncoderParameter(Encoder.Quality, imageQuality);
            EncoderParameter light = new EncoderParameter(Encoder.ColorDepth, 8L);
            EncoderParameters codecParameters = new EncoderParameters(2);
            codecParameters.Param[0] = ratio;
            codecParameters.Param[1] = light;
            return codecParameters;
        }

但我仍然无法获得 8 位深度的 png。

问候。

4

1 回答 1

0

这就是我想出的。我使用图像量化来减少颜色深度。

http://msdn.microsoft.com/en-us/library/aa479306.aspx 这就是我得到的量化器

 public bool convertTiffToPng(string sourceFile, string targetFile)
        {

            bool response = false;

            try
            {

                // Get individual Images from the original image
                Image sourceImage = Bitmap.FromFile(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);

                // 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;
        }
于 2012-04-13T09:30:41.740 回答