首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在C#中加载32位灰度TIFF图像

在C#中加载32位灰度TIFF图像
EN

Stack Overflow用户
提问于 2015-03-20 18:10:13
回答 1查看 1.8K关注 0票数 0

我正在开发一个小的C#工具,必须能够加载TIFF图像,裁剪图像到一定的大小,并将其保存为PNG文件。

我有大约28000x256像素的32位深度的大型灰度TIFF图像。当我尝试用我的工具处理图像时,它只输出一张空白的白色图像。

此外,当我尝试使用Windows照片查看器打开原始TIFF图像(不是用我的工具处理的图像)时,它也显示为空白的白色图像。其他一些应用程序,如ImageJ,可以正确显示图像。这里的问题是什么?

我加载图像的代码如下所示:

代码语言:javascript
运行
复制
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);
EN

回答 1

Stack Overflow用户

发布于 2015-03-20 18:30:26

问题是C# (或者更确切地说是底层应用程序接口)不能处理颜色深度大于8位的灰度图像。

我建议使用LibTiff.NET来处理TIFF图像。当我遇到这样的问题时,我将TIFF图像原始数据加载到一个数组中

代码语言:javascript
运行
复制
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)记住要注意数据的字节顺序!

代码语言:javascript
运行
复制
// 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表达式,因为它们要快得多。(在我的场景中,100s vs 2s运行时)

最后,您可以再次使用LibTiff保存图像

代码语言:javascript
运行
复制
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);
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29164001

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档