![](/img/trans.png)
[英]32-bit Grayscale Tiff with floating point pixel values to array using LibTIFF.NET C#
[英]Load 32-bit greyscale TIFF image in C#
我正在开发一个小型C#工具,该工具必须能够加载TIFF图像,将图像裁剪为特定大小并将其另存为PNG文件。
我有大约28000x256像素的大型灰度TIFF图像,具有32位的位深度。 当我尝试使用工具处理图像时,它只会输出空白的白色图像。
另外,当我尝试使用Windows Photo Viewer打开原始TIFF图像(不是用我的工具处理过的图像)时,它还会显示空白的白色图像。 其他一些应用程序,例如ImageJ,可以正确显示图像。 这里有什么问题?
我的加载图像的代码如下所示:
Image image = Bitmap.FromFile(path.LocalPath);
int width = image.Width;
int height = image.Height;
Bitmap bmp = new Bitmap(width, height);
Graphics g = Graphics.FromImage(bmp);
问题在于C#(或更确切地说是底层API)无法处理Colordepth大于8bit的灰度图像。
我建议使用LibTiff.NET处理TIFF图像。 遇到此类问题时,我将TIFF图像原始数据加载到了数组中
using (var inputImage = Tiff.Open(image, "r"))
{
width = inputImage.GetField(TiffTag.IMAGEWIDTH)[0].ToInt();
height = inputImage.GetField(TiffTag.IMAGELENGTH)[0].ToInt();
inputImageData = new byte[width * height * bytePerPixel];
var offset = 0;
for (int i = 0; i < inputImage.NumberOfStrips(); i++)
{
offset += inputImage.ReadRawStrip(i, inputImageData, offset, (int)inputImage.RawStripSize(i));
}
}
然后必须将字节转换为uint
数组(在我的情况下,imagedata只有16位,所以我使用了ushort
)。记住要注意数据的字节序!
// has to be done by hand to ensure endiannes is kept correctly.
var outputImageData = new ushort[inputImageData.Length / 2];
for (var i = 0; i < outputImageData.Length; i++)
{
outputImageData[i] = (ushort)((inputImageData[i * 2 + 1]) + (ushort)(inputImageData[i * 2] << 8));
}
然后,您可以使用常规阵列操作来操作映像。 我建议您使用普通的数组操作,而不要使用Lambda-Expression,因为它们要快得多。 (在“我的方案100s vs 2s Runtime”中)
最后,您可以再次使用LibTiff保存图像
using (var output = Tiff.Open(imageout, "w"))
{
output.SetField(TiffTag.IMAGEWIDTH, width);
output.SetField(TiffTag.IMAGELENGTH, height);
output.SetField(TiffTag.SAMPLESPERPIXEL, 1);
output.SetField(TiffTag.BITSPERSAMPLE, 16);
output.SetField(TiffTag.ROWSPERSTRIP, height);
output.SetField(TiffTag.PHOTOMETRIC, Photometric.MINISBLACK);
output.SetField(TiffTag.FILLORDER, FillOrder.MSB2LSB);
// Transform to Byte-Array
var buffer = new byte[outputImageData.Length * sizeof(ushort)];
Buffer.BlockCopy(outputImageData, 0, buffer, 0, buffer.Length);
// Write it to Image
output.WriteRawStrip(0, buffer, buffer.Length);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.