使用Bitmiracle Libtiff.net创建一个Bigtiff(> 4GB)文件

时间:2015-02-23 15:03:59

标签: c# .net tiff imaging libtiff.net

首先,我要感谢Bitmiracle这个伟大的lib。即使在创建非常大的文件时,内存占用也非常低。 几天前,我遇到了一个问题,我想创建一个大于4GB的tiff文件。我成功地创建了平铺的tiff文件,但是看起来创建超过4GB的瓷砖的颜色在某种程度上是倒置的。

Resulted File viewed with vilv viewer 这里代码相关代码:

用法:

WriteTiledTiff("bigtiff.tiff",BitmapSourceFromBrush(new RadialGradientBrush(Colors.Aqua,Colors.Red), 256));

方法:

public static BitmapSource BitmapSourceFromBrush(Brush drawingBrush, int size = 32, int dpi = 96)
    {
        // RenderTargetBitmap = builds a bitmap rendering of a visual
        var pixelFormat = PixelFormats.Pbgra32;
        RenderTargetBitmap rtb = new RenderTargetBitmap(size, size, dpi, dpi, pixelFormat);

        // Drawing visual allows us to compose graphic drawing parts into a visual to render
        var drawingVisual = new DrawingVisual();
        using (DrawingContext context = drawingVisual.RenderOpen())
        {
            // Declaring drawing a rectangle using the input brush to fill up the visual
            context.DrawRectangle(drawingBrush, null, new Rect(0, 0, size, size));
        }

        // Actually rendering the bitmap
        rtb.Render(drawingVisual);
        return rtb;
    }

public static void WriteTiledTiff(string fileName, BitmapSource tile)
    {
        const int PIXEL_WIDTH = 48000;
        const int PIXEL_HEIGHT = 48000;

         int iTile_Width = tile.PixelWidth;
         int iTile_Height = tile.PixelHeight;

        using (Tiff tiff = Tiff.Open(fileName, "w"))
        {
            tiff.SetField(TiffTag.IMAGEWIDTH, PIXEL_WIDTH);
            tiff.SetField(TiffTag.IMAGELENGTH, PIXEL_HEIGHT);
            tiff.SetField(TiffTag.COMPRESSION, Compression.NONE);
            tiff.SetField(TiffTag.PHOTOMETRIC, Photometric.RGB);

            tiff.SetField(TiffTag.ROWSPERSTRIP, PIXEL_HEIGHT);

            tiff.SetField(TiffTag.XRESOLUTION, 96);
            tiff.SetField(TiffTag.YRESOLUTION, 96);

            tiff.SetField(TiffTag.BITSPERSAMPLE, 8);
            tiff.SetField(TiffTag.SAMPLESPERPIXEL, 3);

            tiff.SetField(TiffTag.PLANARCONFIG, PlanarConfig.CONTIG);

            tiff.SetField(TiffTag.TILEWIDTH, iTile_Width);
            tiff.SetField(TiffTag.TILELENGTH, iTile_Height);

            int tileC = 0;
            for (int row = 0; row < PIXEL_HEIGHT; row += iTile_Height)
            {
                for (int col = 0; col < PIXEL_WIDTH; col += iTile_Width)
                {
                    if (tile.Format != PixelFormats.Rgb24) tile = new FormatConvertedBitmap(tile, PixelFormats.Rgb24, null, 0);
                    int stride = tile.PixelWidth * ((tile.Format.BitsPerPixel + 7) / 8);

                    byte[] pixels = new byte[tile.PixelHeight * stride];
                    tile.CopyPixels(pixels, stride, 0);

                    tiff.WriteEncodedTile(tileC++, pixels, pixels.Length);
                }
            }

            tiff.WriteDirectory();
        }
    }

结果文件大小为6,47GB。我用一个名为&#34; vliv&#34;的小工具查看了它。 vilv download

3 个答案:

答案 0 :(得分:3)

包括2.4.500.0在内的所有LibTiff.Net版本均基于原始libtiff的3.x分支。

在原始libtiff的4.x分支中引入了对BigTIFF的支持。因此,此时没有设计用于处理磁盘上超过4GB的BigTiff文件/文件的LibTiff.Net版本。

修改

LibTiff.Net 2.4.508增加了对BigTiff的支持。

答案 1 :(得分:0)

我下载了Milster repo https://github.com/Milster/libtiff.net并自己构建了BitMiracle.LibTiff.NET.dll。这对我有用!

修改 V. 2.4.528也为我工作!

答案 2 :(得分:0)

我没有足够的声誉进行评论,因此即使它没有回答原始问题,我也将其发布为答案。

@Andreas在评论中问

  

即使大小小于4gb,也有可能强制“ bigtiff”吗?

确实存在。诀窍是向Tiff.Open方法的mode参数传递一个额外的'8':

using (Tiff output = Tiff.Open(filePath, "w8"))

模式参数描述为here about after the first third of the page