【CSharp】将ushort数组保存为3通道位深24bit的Tiff图片

2024-05-27 23:28

本文主要是介绍【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图片的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1008892

相关文章

如何使用CSS3实现波浪式图片墙

《如何使用CSS3实现波浪式图片墙》:本文主要介绍了如何使用CSS3的transform属性和动画技巧实现波浪式图片墙,通过设置图片的垂直偏移量,并使用动画使其周期性地改变位置,可以创建出动态且具有波浪效果的图片墙,同时,还强调了响应式设计的重要性,以确保图片墙在不同设备上都能良好显示,详细内容请阅读本文,希望能对你有所帮助...

Python脚本实现图片文件批量命名

《Python脚本实现图片文件批量命名》这篇文章主要为大家详细介绍了一个用python第三方库pillow写的批量处理图片命名的脚本,文中的示例代码讲解详细,感兴趣的小伙伴可以了解下... 目录前言源码批量处理图片尺寸脚本源码GUI界面源码打包成.exe可执行文件前言本文介绍一个用python第三方库pi

Python爬虫selenium验证之中文识别点选+图片验证码案例(最新推荐)

《Python爬虫selenium验证之中文识别点选+图片验证码案例(最新推荐)》本文介绍了如何使用Python和Selenium结合ddddocr库实现图片验证码的识别和点击功能,感兴趣的朋友一起看... 目录1.获取图片2.目标识别3.背景坐标识别3.1 ddddocr3.2 打码平台4.坐标点击5.图

C++一个数组赋值给另一个数组方式

《C++一个数组赋值给另一个数组方式》文章介绍了三种在C++中将一个数组赋值给另一个数组的方法:使用循环逐个元素赋值、使用标准库函数std::copy或std::memcpy以及使用标准库容器,每种方... 目录C++一个数组赋值给另一个数组循环遍历赋值使用标准库中的函数 std::copy 或 std::

C++初始化数组的几种常见方法(简单易懂)

《C++初始化数组的几种常见方法(简单易懂)》本文介绍了C++中数组的初始化方法,包括一维数组和二维数组的初始化,以及用new动态初始化数组,在C++11及以上版本中,还提供了使用std::array... 目录1、初始化一维数组1.1、使用列表初始化(推荐方式)1.2、初始化部分列表1.3、使用std::

C++ Primer 多维数组的使用

《C++Primer多维数组的使用》本文主要介绍了多维数组在C++语言中的定义、初始化、下标引用以及使用范围for语句处理多维数组的方法,具有一定的参考价值,感兴趣的可以了解一下... 目录多维数组多维数组的初始化多维数组的下标引用使用范围for语句处理多维数组指针和多维数组多维数组严格来说,C++语言没

Python利用PIL进行图片压缩

《Python利用PIL进行图片压缩》有时在发送一些文件如PPT、Word时,由于文件中的图片太大,导致文件也太大,无法发送,所以本文为大家介绍了Python中图片压缩的方法,需要的可以参考下... 有时在发送一些文件如PPT、Word时,由于文件中的图片太大,导致文件也太大,无法发送,所有可以对文件中的图

java获取图片的大小、宽度、高度方式

《java获取图片的大小、宽度、高度方式》文章介绍了如何将File对象转换为MultipartFile对象的过程,并分享了个人经验,希望能为读者提供参考... 目China编程录Java获取图片的大小、宽度、高度File对象(该对象里面是图片)MultipartFile对象(该对象里面是图片)总结java获取图片

使用C++将处理后的信号保存为PNG和TIFF格式

《使用C++将处理后的信号保存为PNG和TIFF格式》在信号处理领域,我们常常需要将处理结果以图像的形式保存下来,方便后续分析和展示,C++提供了多种库来处理图像数据,本文将介绍如何使用stb_ima... 目录1. PNG格式保存使用stb_imagephp_write库1.1 安装和包含库1.2 代码解

Java实战之自助进行多张图片合成拼接

《Java实战之自助进行多张图片合成拼接》在当今数字化时代,图像处理技术在各个领域都发挥着至关重要的作用,本文为大家详细介绍了如何使用Java实现多张图片合成拼接,需要的可以了解下... 目录前言一、图片合成需求描述二、图片合成设计与实现1、编程语言2、基础数据准备3、图片合成流程4、图片合成实现三、总结前