【CSharp】將ushort數組保存為1通道位深16bit的Tiff圖片
- 1.背景
- 2.接口
1.背景
System.Drawing.Common 是一個用于圖像處理和圖形操作的庫,它是 System.Drawing 命名空間的一部分。由于 .NET Core 和 .NET 5+ 的跨平臺特性,許多以前內置于 .NET Framework 中的庫被移到了獨立的NuGet包中,以便更好地管理和跨平臺使用。
System.Drawing.Common 提供了處理圖像的基礎設施,包括創建、修改和保存圖像的功能。
在使用與圖像相關的類(如 Bitmap 和 Graphics)時,需要引用這個包。
通過 NuGet 包管理器安裝:System.Drawing.Common
如下圖所示:
安裝完成后,將在項目下的packages目錄下生成System.Drawing.Common.8.0.5文件夾,如下圖:
使用如下代碼創建16位深的Tiff圖:
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;namespace Raw2Tiff
{class jn10010537{static void Main(){// 示例 ushort 數組int width = 100;int height = 100;ushort[] ushortArray = new ushort[width * height];Random random = new Random();for (int i = 0; i < ushortArray.Length; i++){ushortArray[i] = (ushort)random.Next(0, 65536);}// 將 ushort 數組轉換為 byte 數組byte[] byteArray = new byte[ushortArray.Length * 2];Buffer.BlockCopy(ushortArray, 0, byteArray, 0, byteArray.Length);// 創建 Bitmap 對象Bitmap bitmap = new Bitmap(width, height, PixelFormat.Format16bppGrayScale);// 獲取 BitmapData 對象// 使用LockBits方法可以更快地設置像素,該方法允許您將托管數據快速封送到非托管位圖字節。BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, bitmap.PixelFormat);// 將 byte 數組拷貝到 BitmapData 對象Marshal.Copy(byteArray, 0, bitmapData.Scan0, byteArray.Length);// 解鎖 BitmapData 對象bitmap.UnlockBits(bitmapData);// 保存為 TIFF 圖片bitmap.Save("output.tiff", ImageFormat.Tiff);Console.WriteLine("圖片已保存為 output.tiff");}}
}
運行如下:
原因:請注意,GDI+似乎不支持16bpp灰度,這意味著。net無法將16bpp灰度位圖保存到文件或流中。
2.接口
在Windows上使用System.Drawing.Common處理16位灰度圖像保存為TIFF時,目前(2024-05-27)會遇到問題!
因為默認情況下System.Drawing庫不直接支持16位灰度圖像的處理。
本博客采用的替代解決方案是使用BitMiracle.LibTiff.NET庫,這是一個強大的庫,專門用于處理TIFF圖像格式。
通過 NuGet 包管理器安裝: BitMiracle.LibTiff.NET 包,
如下圖:
安裝日志:
正在嘗試收集與目標為“.NETFramework,Version=v4.7.2”的項目“Raw2Tiff”有關的包“BitMiracle.LibTiff.NET.2.4.649”的依賴項信息
收集依賴項信息花費時間 665 ms
正在嘗試解析程序包“BitMiracle.LibTiff.NET.2.4.649”的依賴項,DependencyBehavior 為“Lowest”
解析依賴項信息花費時間 0 ms
正在解析操作以安裝程序包“BitMiracle.LibTiff.NET.2.4.649”
已解析操作以安裝程序包“BitMiracle.LibTiff.NET.2.4.649”GET https://api.nuget.org/v3-flatcontainer/bitmiracle.libtiff.net/2.4.649/bitmiracle.libtiff.net.2.4.649.nupkgOK https://api.nuget.org/v3-flatcontainer/bitmiracle.libtiff.net/2.4.649/bitmiracle.libtiff.net.2.4.649.nupkg 172 毫秒
已通過內容哈希 XCEdfCphKo0UAvSg1h/OzOFWtjkIGnPMAziYkNqV7NVrqb/tZJTBxJhxIEX7gpvQwg8GIRYt133SUncfkKfjLA== 從 https://api.nuget.org/v3/index.json 安裝 BitMiracle.LibTiff.NET 2.4.649 。
正在將包“BitMiracle.LibTiff.NET.2.4.649”添加到文件夾“C:\Users\Administrator\Desktop\IRay_CSahep\Raw2Tiff\packages”
已將包“BitMiracle.LibTiff.NET.2.4.649”添加到文件夾“C:\Users\Administrator\Desktop\IRay_CSahep\Raw2Tiff\packages”
已將包“BitMiracle.LibTiff.NET.2.4.649”添加到“packages.config”
已將“BitMiracle.LibTiff.NET 2.4.649”成功安裝到 Raw2Tiff
執行 nuget 操作花費時間 2.52 sec
已用時間: 00:00:03.3026348
========== 已完成 ==========
安裝完成將在項目文件目錄下生成"BitMiracle.LibTiff.NET.2.4.649"文件夾,如下圖:
以下是使用BitMiracle.LibTiff.NET保存16位灰度TIFF圖像的示例代碼:
using System;
using BitMiracle.LibTiff.Classic;namespace Raw2Tiff
{class jn10010537{static void Main(){// 示例 ushort 數組int width = 300;int height = 500;ushort[] ushortArray = new ushort[width * height];Random random = new Random();for (int i = 0; i < ushortArray.Length; i++){ushortArray[i] = (ushort)random.Next(0, 65536);}// 保存為 TIFF 圖片Save16BitGrayscaleTiff("jn10010537.tiff", ushortArray, width, height);Console.WriteLine("圖片已保存成功!");Console.ReadKey();}private static void Save16BitGrayscaleTiff(string fileName, ushort[] imageData, int width, int height){using (Tiff output = Tiff.Open(fileName, "w")){output.SetField(TiffTag.IMAGEWIDTH, width);output.SetField(TiffTag.IMAGELENGTH, height);output.SetField(TiffTag.SAMPLESPERPIXEL, 1);output.SetField(TiffTag.BITSPERSAMPLE, 16);output.SetField(TiffTag.ORIENTATION, Orientation.TOPLEFT);output.SetField(TiffTag.PLANARCONFIG, PlanarConfig.CONTIG);output.SetField(TiffTag.PHOTOMETRIC, Photometric.MINISBLACK);output.SetField(TiffTag.ROWSPERSTRIP, height);int stride = width * sizeof(ushort);byte[] strip = new byte[stride];for (int row = 0; row < height; row++){Buffer.BlockCopy(imageData, row * stride, strip, 0, stride);output.WriteScanline(strip, row);}}}}
}
程序運行后將生成tiff文件,打開Tiff圖片的詳細信息如下圖所示: