2012-04-12 152 views
0

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

问候。

+0

的可能的复制http://stackoverflow.com/questions/483014/generate-image-file-with-low-bit-depths – pstrjds 2012-04-12 14:07:38

+0

我有检查邮政,但它也不起作用 – 2012-04-13 06:35:41

回答

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; 
     } 
+1

为什么在将所有页面写入您的PNG之前,您将Tiff(因为它是黑色和白色假定为第4组Tiff)转换为JPEG(这是一种有损压缩)。另外我不知道你的ResizeImage是干什么的,但是从粗略浏览代码看来,你似乎认为Tiff中的所有页面都是相同的大小。我不知道你在使用这个域名的域名,但是Tiff可以有不同的大小页面(去办公室记录并获取一些tiffs,很多时候他们有合法大小的页面,8.5 x 11,以及巨大的地产板块相同的文件) – pstrjds 2012-04-13 13:04:49

+0

是tiffs在黑色和白色具有相同的页面大小的所有帧,所有我需要一个PNG格式只是因为我希望他们显示在Silverlight应用程序(不支持TIFF)首先我试图转换jiff中的tiff,以及你说它是一个可怕的选项,因为jpeg被设计为使用更多的颜色,并且它的压缩适合彩色图像。然后我留下了PNG选项。因为我知道tiff不需要有24位色彩深度,所以我试图将它们的色彩深度降低到8位,并使用调色板量化将色彩降低到只有黑色和白色。 – 2012-04-13 15:24:56

+0

我也想知道,如果我可以使白色透明的PNG,因为大多数文件使用白色背景。以及它会影响png文件大小? – 2012-04-13 15:27:03