【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 文件后释放资源:释放位图对象以清理资源。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/17057.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux系统更改SSH端口号配置

1.编写sshd.config cd /etc/ssh sudo cp sshd_config sshd_config.bak vim sshd_config2.重启服务 systemctl restart sshd 结束&#xff01;&#xff01;

【UE5.1 角色练习】08-物体抬升、抛出技能

前言 在上一篇&#xff08;【UE5.1 角色练习】08-传送技能&#xff09;的基础上继续实现控制物体抬升、抛出的功能。 效果 步骤 一、准备技能动画 1. 在项目设置中新建一个操作映射&#xff0c;这里命名为“Skill_GravityControl”&#xff0c;用按键4触发 2. 通过IK重定向…

aws emr启动standalone的flink集群

关键组件 Client&#xff0c;代码由客户端获取并做转换&#xff0c;之后提交给JobMangerJobManager&#xff0c;对作业进行中央调度管理&#xff0c;获取到要执行的作业后&#xff0c;会进一步处理转换&#xff0c;然后分发任务给众多的TaskManager。TaskManager&#xff0c;数…

【mysql】ubuntu下安装数据库

1更新软件包 sudo apt update //更新软件包2安装数据库 sudo apt install mysql-server//安装数据库注意后面mysql-server是个整体 3安全设置配置 sudo mysql_secure_installation//安全设置配置你要设置验证密码吗&#xff1f; 输入设置密码安全等级&#xff08;0,1&am…

nginx文件解析漏洞测试

环境条件:ubuntu14,已安装docker,docker pull ubuntu:14.04.5 一、Nginx配置 1、使用docker启动容器&#xff1a; docker run -itd --name ubuntu -p 8088:80 ubuntu:14.04.5 2、进入容器&#xff1a; docker exec -it ubuntu /bin/bash 3、然后使用以下语句安装相关环境…

C++基础:类的继承,public,private,protected

三种继承模式 在上图中: 派生继承 三种继承模式 protected模式中 父类的公有属性和保护属性的成员在子类中都会变为保护属性,只能通过父类或者子类的成员函数调用. 代码示例: #include <iostream> #include <string> using namespace std; //protected class per…

RBA认证是什么?申请RBA认证的流程是什么?

RBA认证&#xff0c;全称为Responsible Business Alliance&#xff08;责任商业联盟&#xff09;认证&#xff0c;是一个全球性的企业社会责任&#xff08;CSR&#xff09;倡议&#xff0c;旨在通过推动供应链中的社会和环境责任实践&#xff0c;确保供应链的可持续性。该认证要…

stm32cubeMX简单使用(轻松配置时钟和中断等)ST图形代码生成器

大大加快代码编写速度的图形编译工具 需要的准备材料 需要注意的几点操作 1&#xff0c;管理固件库和软件&#xff0c;方便对应不同系列的硬件 2&#xff0c;新建工程 3&#xff0c;整体流程 这个软件的本质是用来生成代码&#xff0c;方便前期初始化操作 4&#xff0c;对引…

暴雨公司受邀参加中国图象图形大会

5月24日至26日&#xff0c;备受瞩目的中国图象图形大会&#xff08;CCIG 2024&#xff09;在古都西安圆满落幕。本届大会主题为“图聚智生&#xff0c;象合慧成”&#xff0c;由中国图象图形学学会主办&#xff0c;空军军医大学、西安交通大学、西北工业大学承办&#xff0c;陕…

List基本使用(C++)

目录 1.list的介绍 2.list的使用 list的构造 list的size() 和 max_size() list遍历操作 list元素修改操作 assign()函数 push_front(),push_back 头插&#xff0c;尾插 pop_front() pop_back 头删尾删 insert()函数 swap()函数 resize()函数 clear()函数 list类数…

微信小程序图片懒加载如何实现?

微信小程序开发时&#xff0c;对于有图片的列表在加载时&#xff0c;为了用户体验更好&#xff0c;必需要对图片做懒加载。 如下图所示&#xff0c;页面在打开时&#xff0c;图片会按需加载&#xff0c;这样用户体验没有那么生硬。 以下将介绍图片懒加载的步骤&#xff1a; 1.…

什么?电脑内存又不够用了?我来拯救你!

什么&#xff1f;电脑内存又不够用了&#xff1f;我来拯救你&#xff01; 现在手机电脑的内存越来越大&#xff0c;各个公司开发的软件也是越来越肆无忌惮的挥霍这些内存空间&#xff0c;QQ 微信啥的动辄占用好几个 G 的内存。对于新购买的电脑来说&#xff0c;这也不是什么大…

算法训练营day41

动态规划理论基础&#xff08;主要就是确定动态规划的几个步骤&#xff09; 题目1&#xff1a;509. 斐波那契数 - 力扣&#xff08;LeetCode&#xff09; class Solution { public:int fib(int n) {if(n 0) return 0;if(n 1) return 1;int dp1 0;int dp2 1;int dp3 0;fo…

构建镜像时候出现奇怪的现象时候

一、背景 构建镜像时候&#xff0c;昨天还好好的&#xff0c;今天出现奇怪的现象 二、查看现象 docker system df#cache 显示600G 三、步骤 这操作比较轻微&#xff0c;20以前的缓存清理掉 docker builder prune --filter until480h # 清除20填以前的构建缓

clickhouse——ck目录介绍

一、ck目录 1、/etc/clickhouse-server: 服务端的配置文件目录&#xff0c;包括全局配置config.xml和用户配置users.xml等。 2、/var/lib/clickhouse 默认的数据存储目录&#xff08;通常会修改默认路径配置&#xff0c;将数据保存到大容量磁盘挂载的路径&#xff09; 3、/var…

图片提取表格要怎么做?7个软件教你快速进行图片识别

图片提取表格要怎么做&#xff1f;7个软件教你快速进行图片识别 要从图片中提取表格&#xff0c;您可以使用以下七款软件来快速进行图片识别和表格提取&#xff1a; 1.一键识别王&#xff1a;这是一款专业的OCR&#xff08;光学字符识别&#xff09;软件&#xff0c;可以帮助…

重生之 SpringBoot3 入门保姆级学习(05、 Bean 装配)

重生之 SpringBoot3 入门保姆级学习&#xff08;05、 Bean 装配&#xff09; [TOC](重生之 SpringBoot3 入门保姆级学习&#xff08;05、 Bean 装配&#xff09;)2.2.1 通过 ioc.xml 文件配置2.1.2 通过 Configuration 注解配置2.2.4 测试 Bean 是否生效 新建 User 类 package…

【HarmonyOS4学习笔记】《HarmonyOS4+NEXT星河版入门到企业级实战教程》课程学习笔记(十二)

课程地址&#xff1a; 黑马程序员HarmonyOS4NEXT星河版入门到企业级实战教程&#xff0c;一套精通鸿蒙应用开发 &#xff08;本篇笔记对应课程第 19节&#xff09; P19《18.ArkUI组件-页面路由》 以访问京东页面为例&#xff0c;访问过的页面并没有消失&#xff0c;而是进入了…

使用LabVIEW开发RFID读卡器程序

使用LabVIEW开发RFID读卡器程序&#xff0c;涵盖硬件选择、初始化、数据读取与处理的整个流程。通过详细的开发步骤和示例代码&#xff0c;展示LabVIEW在快速开发和调试RFID应用中的优势&#xff0c;使用户能有效实现RFID技术在各类项目中的应用。 工作原理 RFID&#xff08;…

EMQX 的初始IP改为自己的实际IP

分类 EMQX Dashboard&#xff08;控制台&#xff09;: Dashboard提供了一个Web界面&#xff0c;用于管理和监控EMQX的运行状态。您可以通过配置dashboard.listeners.http.bind来设置Dashboard的监听地址和端口。例如&#xff0c;如果您想要Dashboard在所有网络接口上监听&#…