C# 分割和合并Tiff文件后,图像的字节大小会增加

C# 分割和合并Tiff文件后,图像的字节大小会增加,c#,tiff,system.drawing,libtiff.net,system.drawing.imaging,C#,Tiff,System.drawing,Libtiff.net,System.drawing.imaging,我正在尝试拆分和合并多页tiff图像。我拆分的原因是在每个图像级别绘制注释。代码运行良好,但是合并的tiff与源tiff相比相当大。例如,我测试了17个彩色页面的tiff图像(大小为5MB),经过分割和合并后,它生成85MB的tiff图像。我正在使用BitMiracle.LibTiff。实际上,为了解决这个大小问题,我暂时也对注释代码进行了注释,我不确定我做错了什么。。下面是要拆分的代码 private List<Bitmap> SplitTiff(byte[] imageData)

我正在尝试拆分和合并多页tiff图像。我拆分的原因是在每个图像级别绘制注释。代码运行良好,但是合并的tiff与源tiff相比相当大。例如,我测试了17个彩色页面的tiff图像(大小为5MB),经过分割和合并后,它生成85MB的tiff图像。我正在使用BitMiracle.LibTiff。实际上,为了解决这个大小问题,我暂时也对注释代码进行了注释,我不确定我做错了什么。。下面是要拆分的代码

private List<Bitmap> SplitTiff(byte[] imageData)
{
    var bitmapList = new List<Bitmap>();
    var tiffStream = new TiffStreamForBytes(imageData);

    //open tif file
    var tif = Tiff.ClientOpen("", "r", null, tiffStream);

    //get number of pages
    var num = tif.NumberOfDirectories();
    if (num == 1) 
        return new List<Bitmap> 
        { 
            new Bitmap(GetImage(imageData)) 
        };

    for (short i = 0; i < num; i++)
    {
         //set current page
         tif.SetDirectory(i);
         FieldValue[] photoMetric = tif.GetField(TiffTag.PHOTOMETRIC);
         Photometric photo = Photometric.MINISBLACK;
         if (photoMetric != null && photoMetric.Length > 0)
             photo = (Photometric)photoMetric[0].ToInt();

         if (photo != Photometric.MINISBLACK && photo != Photometric.MINISWHITE)
             bitmapList.Add(GetBitmapFromTiff(tif));
         // else
             // bitmapList.Add(GetBitmapFromTiffBlack(tif, photo));// commented temporrarly to fix size issue
     }
     return bitmapList;
}

private static Bitmap GetBitmapFromTiff(Tiff tif)
{
    var value = tif.GetField(TiffTag.IMAGEWIDTH);
    var width = value[0].ToInt();

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

    //Read the image into the memory buffer
    var raster = new int[height * width];
    if (!tif.ReadRGBAImage(width, height, raster))
    {
        return null;
    }

    var bmp = new Bitmap(width, height, PixelFormat.Format32bppRgb);

    var rect = new Rectangle(0, 0, bmp.Width, bmp.Height);

    var bmpdata = bmp.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format32bppRgb);
    var bits = new byte[bmpdata.Stride * bmpdata.Height];

    for (var y = 0; y < bmp.Height; y++)
    {
        int rasterOffset = y * bmp.Width;
        int bitsOffset = (bmp.Height - y - 1) * bmpdata.Stride;

        for (int x = 0; x < bmp.Width; x++)
        {
            int rgba = raster[rasterOffset++];
            bits[bitsOffset++] = (byte)((rgba >> 16) & 0xff);
            bits[bitsOffset++] = (byte)((rgba >> 8) & 0xff);
            bits[bitsOffset++] = (byte)(rgba & 0xff);
            bits[bitsOffset++] = (byte)((rgba >> 24) & 0xff);
         }
    }

    System.Runtime.InteropServices.Marshal.Copy(bits, 0, bmpdata.Scan0, bits.Length);
    bmp.UnlockBits(bmpdata);

    return bmp;
}
private List SplitTiff(字节[]图像数据)
{
var bitmapList=新列表();
var tiffStream=新的TiffStreamForBytes(图像数据);
//打开tif文件
var tif=Tiff.ClientOpen(“,”r“,null,tiffStream);
//获取页数
var num=tif.NumberOfDirectories();
如果(num==1)
返回新列表
{ 
新位图(GetImage(imageData))
};
用于(短i=0;i0)
photo=(光度)光度[0]。ToInt();
如果(照片!=光度控制.miniBlack和照片!=光度控制.miniWhite)
添加(GetBitmapFromTiff(tif));
//否则
//bitmapList.Add(GetBitmapFromTiffBlack(tif,照片));//临时注释以修复大小问题
}
返回位图列表;
}
私有静态位图GetBitmapFromTiff(Tiff tif)
{
var值=tif.GetField(TiffTag.IMAGEWIDTH);
变量宽度=值[0]。ToInt();
值=tif.GetField(TiffTag.IMAGELENGTH);
变量高度=值[0]。ToInt();
//将图像读入内存缓冲区
var raster=新整数[高度*宽度];
如果(!tif.ReadRGBAImage(宽度、高度、光栅))
{
返回null;
}
var bmp=新位图(宽度、高度、像素格式.Format32bppRgb);
var rect=新矩形(0,0,bmp.Width,bmp.Height);
var bmpdata=bmp.LockBits(rect,ImageLockMode.ReadWrite,PixelFormat.Format32bppRgb);
变量位=新字节[bmpdata.Stride*bmpdata.Height];
对于(变量y=0;y>16)和0xff);
位[bitsofset++]=(字节)((rgba>>8)和0xff);
位[bitsofset++]=(字节)(rgba和0xff);
位[bitsofset++]=(字节)((rgba>>24)和0xff);
}
}
System.Runtime.InteropServices.Marshal.Copy(bits,0,bmpdata.Scan0,bits.Length);
bmp.UnlockBits(bmpdata);
返回bmp;
}
将单个位图合并到tiff的代码在这里

public static PrizmImage PrizmImageFromBitmaps(List<Bitmap> imageItems, string ext)
{
     if (imageItems.Count == 1 && !(ext.ToLower().Equals(".tif") || ext.ToLower().Equals(".tiff")))
         return new PrizmImage(new MemoryStream(ImageUtility.BitmapToByteArray(imageItems[0])), ext);

     var codecInfo = GetCodecInfo();
     var memoryStream = new MemoryStream();

     var encoderParams = new EncoderParameters(1);
     encoderParams.Param[0] = new EncoderParameter(Encoder.SaveFlag, (long)EncoderValue.MultiFrame);

     var initialImage = imageItems[0];
     var masterBitmap = imageItems[0];// new Bitmap(initialImage);
     masterBitmap.Save(memoryStream, codecInfo, encoderParams);
     encoderParams.Param[0] = new EncoderParameter(Encoder.SaveFlag,  (long)EncoderValue.FrameDimensionPage);

     for (var i = 1; i < imageItems.Count; i++)
     {
          var img = imageItems[i];
          masterBitmap.SaveAdd(img, encoderParams);
          img.Dispose();
     }

     encoderParams.Param[0] = new EncoderParameter(Encoder.SaveFlag, (long)EncoderValue.Flush);
     masterBitmap.SaveAdd(encoderParams);

     memoryStream.Seek(0, SeekOrigin.Begin);
     encoderParams.Dispose();
     masterBitmap.Dispose();
     return new PrizmImage(memoryStream, ext);
}
publicstaticprizmimage prizmimagefromfrombitmap(列出imageItems,字符串ext)
{
如果(imageItems.Count==1&&!(ext.ToLower().Equals(“.tif”)| | ext.ToLower().Equals(“.tiff”))
返回新的PrizImage(新的MemoryStream(ImageUtility.BitmapToByteArray(imageItems[0])),ext;
var codecInfo=GetCodecInfo();
var memoryStream=新的memoryStream();
var encoderParams=新的EncoderParameters(1);
encoderParams.Param[0]=新的EncoderParameter(Encoder.SaveFlag,(long)EncoderValue.MultiFrame);
var initialImage=imageItems[0];
var masterBitmap=imageItems[0];//新位图(initialImage);
masterBitmap.Save(memoryStream、codecInfo、encoderParams);
encoderParams.Param[0]=新的EncoderParameter(Encoder.SaveFlag,(long)EncoderValue.FrameDimensionPage);
对于(var i=1;i
最可能的原因是,您正在将所有图像转换为32位/像素位图

假设您有一个黑白传真编码图像。它可能被编码为100 Kb的TIFF文件。当您将同一图像保存为32bpp位图时,它可能需要10兆以上的字节。压缩这些兆字节会有所帮助,但您永远无法实现与源图像相同的压缩比,因为您将图像数据量从每像素1位增加到每像素32位

因此,如果可能,不应将图像转换为32bpp位图。尽量保留它们的属性和压缩。请查看TiffCP实用程序的源代码,以了解如何执行此操作的提示


如果您必须将图像转换为32bpp位图(如果向其添加彩色注释,则可能必须进行转换),则没有多少方法可以减小结果大小。如果选择更好的压缩方案并适当调整方案,则输出大小可能会减少10-20%。但恐怕就这些了。

请在图片前后发布样本链接,我会告诉您为什么大小如此不同。这可能与次优编码方法/选项有关。如何将图像发送给您?你能给我发一封测试邮件吗harinatha@gmail.com这样我就可以发送图像了?谢谢。我不必保存为32bpp位图。。。如何更改上述代码以使用最少的每像素位?