为什么当我想用 C# 合并两个大的 tiff 图像时出错?
Why is it wrong when I want merging two large tiff images with C#?
我想合并两个 Large Tiff。我尝试了很多 ways.But 每次都出错。
例如:
我使用了 ImageMagic 和 System.Drowing.Graphics 以及 ImageProcessor 等。
OneDrive 文件:https://1drv.ms/u/s!AlD9jC3hP9FTcEB2J2rKgp8Lw_E?e=JFVewK
已共享四个文件。
原始文件名:_1.tif 和 _11.tif
使用 Magick.NET-Q16-x64 V7.14.3 创建:dotnet.tif
使用 ImageMagick Q16 v 7.0.8 创建:magickcmd.tif
系统信息:
OP:赢得 10 x64
Ram:64Gig
Cpu:I7
显卡:8G
FreeSpace:400Gig
Tif 格式:
像素格式:Format1bppIndexed
尺寸:2Gig
模式:位图
压缩:lzw
像素顺序:交错
字节顺序:lsb
宽度:95752px
高度:295464px
水平分辨率:800dpi
垂直分辨率:2400dpi
位深度:1
分辨率单位:2
感谢您的帮助...
/// Use ImageMagick
using (MagickImageCollection images = new MagickImageCollection())
{
MagickNET.SetTempDirectory(@"d:\");
images.Add(new MagickImage(txtAddress2.Text, new MagickReadSettings { Endian = Endian.LSB }));
images.Add(new MagickImage(txtAddress1.Text, new MagickReadSettings { Endian = Endian.LSB }));
using (IMagickImage image = images.AppendHorizontally())
{
image.Endian = Endian.LSB;
image.Settings.SetDefine("tiff:endian", "lsb");
image.Write(@"d:\output" + new Random().Next() + ".tif");
}
}
//////使用System.Drowing
public static Bitmap MergeTwoImages(Image firstImage, Image secondImage)
{
int outputImageWidth = firstImage.Width > secondImage.Width ? firstImage.Width : secondImage.Width;
int outputImageHeight = firstImage.Height + secondImage.Height + 1;
Bitmap outputImage = new Bitmap(outputImageWidth, outputImageHeight, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
using (Graphics graphics = Graphics.FromImage(outputImage))
{
graphics.DrawImage(firstImage, new Rectangle(new Point(), firstImage.Size),
new Rectangle(new Point(), firstImage.Size), GraphicsUnit.Pixel);
graphics.DrawImage(secondImage, new Rectangle(new Point(0, firstImage.Height + 1), secondImage.Size),
new Rectangle(new Point(), secondImage.Size), GraphicsUnit.Pixel);
}
return outputImage;
}
对于这个问题我建议...
我查看了您的输出图像,它们看起来都不错。如果您看不到它们,可能是因为它们对于您正在使用的任何程序来说都太大了。它们在 nip2, the libvips GUI 中为我显示,尽管它们需要几分钟才能打开。
您的图片很大:15,000 像素宽,180,000 像素。它们以每像素 1 位的形式存储在 TIFF 文件中,但 ImageMagick6 会将它们解压缩为五个通道,每个通道 16 位以进行处理,因此每个通道为 25GB。 ImageMagick7 将使用每个通道 32 位,因此每个图像 50GB。这已接近您计算机的极限 -- 它可能相当慢。
libvips 可以执行这样的操作,而无需将整个图像加载到内存中:它在一系列小区域中将图像从输入流传输到输出。它将 运行 为您计算机上的每个内核提供一个流,所以速度也很快。
它具有良好的 C# 绑定:net-vips。我实际上并没有在这台笔记本电脑上安装它,所以我在 Python 中尝试了。
import sys
import pyvips
left = pyvips.Image.new_from_file(sys.argv[2], access='sequential')
right = pyvips.Image.new_from_file(sys.argv[1], access='sequential')
join = left.join(right, 'horizontal', expand=True)
join.tiffsave(sys.argv[3], predictor='none', compression='lzw', squash=True)
绑定非常相似——您应该能够轻松地将其转换为 C#。
我在这台双核 2015 笔记本电脑上看到:
$ /usr/bin/time -f %M:%e python3 join.py _1.tif _11.tif vips.tif
65832:26.55
因此它 运行 需要 65MB 内存。运行 需要 65MB 内存。
您尝试过 deflate 压缩吗?它比 LZW 慢,但提供更好的结果。将保存行更改为:
join.tiffsave(sys.argv[3], compression='deflate', squash=True)
运行时间上升到57s,但输出文件小了25%。
libvips 也有一个 CLI,你也可以直接输入:
vips join _1.tif _11.tif vips.tif[compression=deflate,squash] horizontal --expand
我想合并两个 Large Tiff。我尝试了很多 ways.But 每次都出错。 例如: 我使用了 ImageMagic 和 System.Drowing.Graphics 以及 ImageProcessor 等。
OneDrive 文件:https://1drv.ms/u/s!AlD9jC3hP9FTcEB2J2rKgp8Lw_E?e=JFVewK
已共享四个文件。
原始文件名:_1.tif 和 _11.tif
使用 Magick.NET-Q16-x64 V7.14.3 创建:dotnet.tif
使用 ImageMagick Q16 v 7.0.8 创建:magickcmd.tif
系统信息: OP:赢得 10 x64 Ram:64Gig Cpu:I7 显卡:8G FreeSpace:400Gig
Tif 格式:
像素格式:Format1bppIndexed
尺寸:2Gig
模式:位图
压缩:lzw
像素顺序:交错
字节顺序:lsb
宽度:95752px
高度:295464px
水平分辨率:800dpi
垂直分辨率:2400dpi
位深度:1
分辨率单位:2
感谢您的帮助...
/// Use ImageMagick
using (MagickImageCollection images = new MagickImageCollection())
{
MagickNET.SetTempDirectory(@"d:\");
images.Add(new MagickImage(txtAddress2.Text, new MagickReadSettings { Endian = Endian.LSB }));
images.Add(new MagickImage(txtAddress1.Text, new MagickReadSettings { Endian = Endian.LSB }));
using (IMagickImage image = images.AppendHorizontally())
{
image.Endian = Endian.LSB;
image.Settings.SetDefine("tiff:endian", "lsb");
image.Write(@"d:\output" + new Random().Next() + ".tif");
}
}
//////使用System.Drowing
public static Bitmap MergeTwoImages(Image firstImage, Image secondImage)
{
int outputImageWidth = firstImage.Width > secondImage.Width ? firstImage.Width : secondImage.Width;
int outputImageHeight = firstImage.Height + secondImage.Height + 1;
Bitmap outputImage = new Bitmap(outputImageWidth, outputImageHeight, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
using (Graphics graphics = Graphics.FromImage(outputImage))
{
graphics.DrawImage(firstImage, new Rectangle(new Point(), firstImage.Size),
new Rectangle(new Point(), firstImage.Size), GraphicsUnit.Pixel);
graphics.DrawImage(secondImage, new Rectangle(new Point(0, firstImage.Height + 1), secondImage.Size),
new Rectangle(new Point(), secondImage.Size), GraphicsUnit.Pixel);
}
return outputImage;
}
对于这个问题我建议...
我查看了您的输出图像,它们看起来都不错。如果您看不到它们,可能是因为它们对于您正在使用的任何程序来说都太大了。它们在 nip2, the libvips GUI 中为我显示,尽管它们需要几分钟才能打开。
您的图片很大:15,000 像素宽,180,000 像素。它们以每像素 1 位的形式存储在 TIFF 文件中,但 ImageMagick6 会将它们解压缩为五个通道,每个通道 16 位以进行处理,因此每个通道为 25GB。 ImageMagick7 将使用每个通道 32 位,因此每个图像 50GB。这已接近您计算机的极限 -- 它可能相当慢。
libvips 可以执行这样的操作,而无需将整个图像加载到内存中:它在一系列小区域中将图像从输入流传输到输出。它将 运行 为您计算机上的每个内核提供一个流,所以速度也很快。
它具有良好的 C# 绑定:net-vips。我实际上并没有在这台笔记本电脑上安装它,所以我在 Python 中尝试了。
import sys
import pyvips
left = pyvips.Image.new_from_file(sys.argv[2], access='sequential')
right = pyvips.Image.new_from_file(sys.argv[1], access='sequential')
join = left.join(right, 'horizontal', expand=True)
join.tiffsave(sys.argv[3], predictor='none', compression='lzw', squash=True)
绑定非常相似——您应该能够轻松地将其转换为 C#。
我在这台双核 2015 笔记本电脑上看到:
$ /usr/bin/time -f %M:%e python3 join.py _1.tif _11.tif vips.tif
65832:26.55
因此它 运行 需要 65MB 内存。运行 需要 65MB 内存。
您尝试过 deflate 压缩吗?它比 LZW 慢,但提供更好的结果。将保存行更改为:
join.tiffsave(sys.argv[3], compression='deflate', squash=True)
运行时间上升到57s,但输出文件小了25%。
libvips 也有一个 CLI,你也可以直接输入:
vips join _1.tif _11.tif vips.tif[compression=deflate,squash] horizontal --expand