本文主要是介绍【CSharp】将ushort数组保存为3通道位深24bit的Tiff图片,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
【CSharp】将ushort数组保存为3通道位深24bit的Tiff图片
- 1.背景
- 2.接口
- 3.示例
1.背景
我们的相机或者探测器是一个感光的传感器,一般将光波打到闪烁体上,闪烁体发光后进行光电转换得到电信号,您可以这么简单的去理解。
这里就设计相机传感器上的AD转换器(模拟信号->数字信号)的bit数,我手里探测器的AD转化器是16bit的即灰阶范围是65536个层次(0~65535),因为长度16位的bit最大可以表示65535;
通过SDK获得探测器获得raw原始数据,C#通过api得到是IntPtr指针,它指向ushort数组。
通过Marshal.Copy(IntPtr, Int16[], Int32, Int32)将数据从非托管内存指针复制到托管 16 位带符号整数数组。
本博客将ushort[] 即16 位带符号整数数组保存为tiff存储到本地磁盘中。
ushort:代表有符号的16位整数,范围从0 到 65,535(2的16次方-1)
Short:代表有符号的16位整数,范围从-32768 ~ 32767(2的15次方-1)
2.接口
需要导入包:
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices; // Marshal.Copy
即使用 System.Drawing 命名空间中的类来处理图像,
并使用 System.Drawing.Imaging 命名空间中的类来保存 TIFF 图像。
下面编辑ushortArraySaveTiff方法,如下:
public void ushortArraySaveTiff(ushort[] ushortArray,int width,int height,string filePath){// 创建位图并锁定内存区域Bitmap bitmap = new Bitmap(width, height, PixelFormat.Format24bppRgb);BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, bitmap.PixelFormat);// 将 ushort 数组转换为 byte 数组并填充到位图中byte[] byteArray = new byte[bitmapData.Stride * height];for (int y = 0; y < height; y++){for (int x = 0; x < width; x++){// 简单缩放至 8 位ushort value = ushortArray[y * width + x];byte scaledValue = (byte)(value >> 8); // 将16位值缩放到8位int position = y * bitmapData.Stride + x * 3;byteArray[position] = scaledValue;byteArray[position + 1] = scaledValue;byteArray[position + 2] = scaledValue;}}// 复制数据到位图Marshal.Copy(byteArray, 0, bitmapData.Scan0, byteArray.Length);bitmap.UnlockBits(bitmapData);// 保存为 TIFF 文件bitmap.Save(filePath, ImageFormat.Tiff);// 清理资源bitmap.Dispose();Console.WriteLine("TIFF 文件已保存到: " + filePath);}
3.示例
C# 代码示例如下:
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices; // Marshal.Copynamespace SaveTiff
{class Class1{public void ushortArraySaveTiff(ushort[] ushortArray, int width, int height, string filePath){// 创建位图并锁定内存区域Bitmap bitmap = new Bitmap(width, height, PixelFormat.Format24bppRgb);BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, bitmap.PixelFormat);// 将 ushort 数组转换为 byte 数组并填充到位图中byte[] byteArray = new byte[bitmapData.Stride * height];for (int y = 0; y < height; y++){for (int x = 0; x < width; x++){// 简单缩放至 8 位ushort value = ushortArray[y * width + x]; byte scaledValue = (byte)(value >> 8); // 将16位值缩放到8位int position = y * bitmapData.Stride + x * 3;byteArray[position] = scaledValue;byteArray[position + 1] = scaledValue;byteArray[position + 2] = scaledValue;}}// 复制数据到位图Marshal.Copy(byteArray, 0, bitmapData.Scan0, byteArray.Length);bitmap.UnlockBits(bitmapData);// 保存为 TIFF 文件bitmap.Save(filePath, ImageFormat.Tiff);// 清理资源bitmap.Dispose();Console.WriteLine("TIFF 文件已保存到: " + filePath);}static void Main(){// 创建一个示例的 ushort 数组 -------------- //int width = 537;int height = 537;ushort[] ushortArray = new ushort[width * height];// 填充数组,生成一些测试数据for (int i = 0; i < ushortArray.Length; i++){ushortArray[i] = (ushort)(i % 65536);}// --------------------------------------- //Class1 obj = new Class1();string filePath = "jn10010537.tiff";obj.ushortArraySaveTiff(ushortArray,width, height,filePath);}}
}
以上代码说明:
1.上面创建的位图格式PixelFormat.Format24bppRgb, 是RGB图,即3个通道位深度24bit,即R、G、B各占8个bit。
2.写入数据之前先锁定位图的内存区域:使用 LockBits 方法锁定位图的内存区域,以便写入数据。
3.关于数据转化:将 ushort 数组的数据转换为 byte 数组,并缩放到8位(每个像素的高8位)。填充 byte 数组以适应24位 RGB 图像格式。
4.关于复制数据到位图:使用 Marshal.Copy 方法将 byte 数组的数据复制到位图的内存区域。
5.内存数据操作完后解锁内存区域:使用 UnlockBits 方法解锁位图的内存区域。
6.保存为 TIFF 文件后释放资源:释放位图对象以清理资源。
这篇关于【CSharp】将ushort数组保存为3通道位深24bit的Tiff图片的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!