使用 Bitmiracle Libtiff.net 创建 Bigtiff (>4GB) 文件
Create a Bigtiff (>4GB) File with Bitmiracle Libtiff.net
首先,我要感谢 Bitmiracle 提供的这个很棒的库。即使在创建非常大的文件时,内存占用也非常低。
几天前,我 运行 遇到了一个问题,我想创建一个大于 4GB 的 tiff 文件。我成功创建了平铺的 tiff 文件,但是创建的超过 4GB 的平铺的颜色似乎以某种方式反转了。
这里代码相关代码:
用法:
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。我用一个叫"vliv"vilv download
的小工具查看的
包括 2.4.500.0 在内的所有 LibTiff.Net 版本均基于原始 libtiff 的 3.x 分支。
在原始 libtiff 的 4.x 分支中引入了对 BigTIFF 的支持。因此,目前没有 LibTiff.Net 版本旨在处理 BigTiff 文件/磁盘上超过 4GB 的文件。
编辑:
LibTiff.Net 2.4.508 添加了对 BigTiff 的支持。
首先,我要感谢 Bitmiracle 提供的这个很棒的库。即使在创建非常大的文件时,内存占用也非常低。 几天前,我 运行 遇到了一个问题,我想创建一个大于 4GB 的 tiff 文件。我成功创建了平铺的 tiff 文件,但是创建的超过 4GB 的平铺的颜色似乎以某种方式反转了。
用法:
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。我用一个叫"vliv"vilv download
的小工具查看的包括 2.4.500.0 在内的所有 LibTiff.Net 版本均基于原始 libtiff 的 3.x 分支。
在原始 libtiff 的 4.x 分支中引入了对 BigTIFF 的支持。因此,目前没有 LibTiff.Net 版本旨在处理 BigTiff 文件/磁盘上超过 4GB 的文件。
编辑:
LibTiff.Net 2.4.508 添加了对 BigTiff 的支持。