C# 在.NET中打开巨大的TIF并将部分复制到新图像
我正在寻找一个库,可以打开和复制一个大TIFF文件的部分。我看了一下哪个可以很快打开文件,但它没有任何裁剪或复制图像部分的功能。我的图像向上为100000 x 100000像素,并且创建该大小的C# 在.NET中打开巨大的TIF并将部分复制到新图像,c#,.net,image-processing,tiff,libtiff.net,C#,.net,Image Processing,Tiff,Libtiff.net,我正在寻找一个库,可以打开和复制一个大TIFF文件的部分。我看了一下哪个可以很快打开文件,但它没有任何裁剪或复制图像部分的功能。我的图像向上为100000 x 100000像素,并且创建该大小的系统.Drawing.Bitmap会导致应用程序崩溃,因此不能先转换为位图 有人能推荐一个.NET库吗 您的图像必须采用格式,因为普通TIFF不能大于4 GB BigTIFF可以通过libtiff的修改版本(中提供)读取,该库允许以您想要的方式处理此类图像,而无需在内存中加载所有像素数据 我没有看到.NE
系统.Drawing.Bitmap
会导致应用程序崩溃,因此不能先转换为位图
有人能推荐一个.NET库吗 您的图像必须采用格式,因为普通TIFF不能大于4 GB
BigTIFF可以通过libtiff的修改版本(中提供)读取,该库允许以您想要的方式处理此类图像,而无需在内存中加载所有像素数据
我没有看到.NET的绑定,但这样做应该不会太长。如果您的文件在磁盘上小于4GB,我建议您再看看LibTiff.NET。即使有这么大的图像,你也有一些选择 首先,检查您的图像是平铺还是剥离
Tiff.IsTiled
方法将为您提供答案
如果您的图像是平铺的,那么您可能不应该使用ReadScanline
方法读取它。在这种情况下,最好使用ReadEncodedTile
方法
如果图像被剥离,则可以使用ReadScanline
和ReadEncodedStrip
方法来读取图像
如果您想使用需要System.Drawing.Bitmap
的内容,请尝试使用ReadRGBATile
或ReadRGBAStrip
。这些方法可用于从图像的某些部分创建位图。这方面没有示例,但应该为您提供有关如何将图像的平铺或条带转换为位图的几乎所有必需信息
编辑:
LibTiff.Net 2.4.508增加了对BigTiff的支持,因此也支持大于4GB的文件。在TIFF解码器中内置了此功能。解码实现了接口IRegionReadable,它允许您从流中图像的给定页面读取矩形部分
在TIFF中,此部分将遵循方向标记,在剥离或平铺TIFF中,使用最小的平铺和条带集填充矩形
(免责声明,我为Atalasoft工作,编写了该接口并在TIFF解码器中实现)正如Bobrovsky提到的,您应该检查您的文件图像是否平铺。在下面,我介绍了读取流tiff并裁剪图像左上部分的代码片段
using (Tiff input = Tiff.Open(@"imageFile.tif", "r"))
{
// get properties to use in writing output image file
int width = input.GetField(TiffTag.IMAGEWIDTH)[0].ToInt();
int height = input.GetField(TiffTag.IMAGELENGTH)[0].ToInt();
int samplesPerPixel = input.GetField(TiffTag.SAMPLESPERPIXEL)[0].ToInt();
int bitsPerSample = input.GetField(TiffTag.BITSPERSAMPLE)[0].ToInt();
int photo = input.GetField(TiffTag.PHOTOMETRIC)[0].ToInt();
int scanlineSize = input.ScanlineSize();
byte[][] buffer = new byte[height][];
for (int i = 0; i < height; ++i)
{
buffer[i] = new byte[scanlineSize];
input.ReadScanline(buffer[i], i);
}
using (Tiff output = Tiff.Open("splitedImage.tif", "w"))
{
output.SetField(TiffTag.SAMPLESPERPIXEL, samplesPerPixel);
output.SetField(TiffTag.IMAGEWIDTH, width/2);
output.SetField(TiffTag.IMAGELENGTH, height/2);
output.SetField(TiffTag.BITSPERSAMPLE, bitsPerSample);
output.SetField(TiffTag.ROWSPERSTRIP, output.DefaultStripSize(0));
output.SetField(TiffTag.PHOTOMETRIC, photo);
output.SetField(TiffTag.PLANARCONFIG, PlanarConfig.CONTIG);
int c = 0;
byte[][] holder = new byte[height][];
for (int i = height/2; i < height; i++)
//for (int j = 0; j < height/2 ; j++)
{
holder[i] = buffer[i].Skip(buffer[i].Length/2).ToArray();
output.WriteScanline(holder[i], c);
c++;
}
}
}
System.Diagnostics.Process.Start("splitedImage.tif");
使用(Tiff输入=Tiff.Open(@“imageFile.tif”,“r”))
{
//获取用于写入输出图像文件的属性
int width=input.GetField(TiffTag.IMAGEWIDTH)[0].ToInt();
int height=input.GetField(TiffTag.IMAGELENGTH)[0].ToInt();
int samplesPerPixel=input.GetField(TiffTag.samplesPerPixel)[0].ToInt();
int bitsPerSample=input.GetField(TiffTag.bitsPerSample)[0].ToInt();
int photo=input.GetField(TiffTag.photomic)[0].ToInt();
int scanlineSize=input.scanlineSize();
字节[][]缓冲区=新字节[高度][];
对于(int i=0;i
对于图像的其他部分,您可以在For循环中更改“i”的范围。哦,上帝,这是40 GB。我想你只有一个32位的操作系统使它更具挑战性?我在64位硬件上运行,但从磁盘读取将是处理它的理想方式。我正在深入研究LibTiff.Net,它有读取扫描线的功能,我需要的可能是图像颜色、灰度或双层?对于双层,我有一个本机代码解决方案,可以解决内存问题。给我发电子邮件(bitbank@pobox.com)。如果您可以将其预转换为PNG,这可能会有所帮助:请回答我的问题。如果100kx100k的图像是彩色的或是双层的,这会有很大的不同。我有一张经过JPG压缩的平铺图像。我想访问图像并将其写回。我是用ReadEncodedFile读取,还是用WriteFile或WriteEncodedFile写入?我先用ReadEncodedFile,然后是WriteEncodedFile。使用dotImage是否可以使用比例因子(比如1/2或1/4)打开TIFF文件。那么要快速生成大型TIFF文件的缩略图呢?我可以以多快的速度更新大型TIFF文件的元数据?在一般情况下,由于平铺和图像方向的复杂性,这是不可能的。然而,在实现IScaledDecoder接口以允许按比例读取图像时,我们确实考虑了其中的大部分因素,因此,尽管最坏的情况没有改变,但最好的情况还是得到了尊重。至于更新元数据,什么对你来说很快?这是一个IO绑定的进程。它似乎和我想象的一样好