【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

相关文章

使用opencv优化图片(画面变清晰)

文章目录 需求影响照片清晰度的因素 实现降噪测试代码 锐化空间锐化Unsharp Masking频率域锐化对比测试 对比度增强常用算法对比测试 需求 对图像进行优化,使其看起来更清晰,同时保持尺寸不变,通常涉及到图像处理技术如锐化、降噪、对比度增强等 影响照片清晰度的因素 影响照片清晰度的因素有很多,主要可以从以下几个方面来分析 1. 拍摄设备 相机传感器:相机传

hdu2241(二分+合并数组)

题意:判断是否存在a+b+c = x,a,b,c分别属于集合A,B,C 如果用暴力会超时,所以这里用到了数组合并,将b,c数组合并成d,d数组存的是b,c数组元素的和,然后对d数组进行二分就可以了 代码如下(附注释): #include<iostream>#include<algorithm>#include<cstring>#include<stack>#include<que

hdu 1166 敌兵布阵(树状数组 or 线段树)

题意是求一个线段的和,在线段上可以进行加减的修改。 树状数组的模板题。 代码: #include <stdio.h>#include <string.h>const int maxn = 50000 + 1;int c[maxn];int n;int lowbit(int x){return x & -x;}void add(int x, int num){while

MOLE 2.5 分析分子通道和孔隙

软件介绍 生物大分子通道和孔隙在生物学中发挥着重要作用,例如在分子识别和酶底物特异性方面。 我们介绍了一种名为 MOLE 2.5 的高级软件工具,该工具旨在分析分子通道和孔隙。 与其他可用软件工具的基准测试表明,MOLE 2.5 相比更快、更强大、功能更丰富。作为一项新功能,MOLE 2.5 可以估算已识别通道的物理化学性质。 软件下载 https://pan.quark.cn/s/57

Android 10.0 mtk平板camera2横屏预览旋转90度横屏拍照图片旋转90度功能实现

1.前言 在10.0的系统rom定制化开发中,在进行一些平板等默认横屏的设备开发的过程中,需要在进入camera2的 时候,默认预览图像也是需要横屏显示的,在上一篇已经实现了横屏预览功能,然后发现横屏预览后,拍照保存的图片 依然是竖屏的,所以说同样需要将图片也保存为横屏图标了,所以就需要看下mtk的camera2的相关横屏保存图片功能, 如何实现实现横屏保存图片功能 如图所示: 2.mtk

Spring MVC 图片上传

引入需要的包 <dependency><groupId>commons-logging</groupId><artifactId>commons-logging</artifactId><version>1.1</version></dependency><dependency><groupId>commons-io</groupId><artifactId>commons-

C语言:柔性数组

数组定义 柔性数组 err int arr[0] = {0}; // ERROR 柔性数组 // 常见struct Test{int len;char arr[1024];} // 柔性数组struct Test{int len;char arr[0];}struct Test *t;t = malloc(sizeof(Test) + 11);strcpy(t->arr,

C 语言基础之数组

文章目录 什么是数组数组变量的声明多维数组 什么是数组 数组,顾名思义,就是一组数。 假如班上有 30 个同学,让你编程统计每个人的分数,求最高分、最低分、平均分等。如果不知道数组,你只能这样写代码: int ZhangSan_score = 95;int LiSi_score = 90;......int LiuDong_score = 100;int Zhou

Prompt - 将图片的表格转换成Markdown

Prompt - 将图片的表格转换成Markdown 0. 引言1. 提示词2. 原始版本 0. 引言 最近尝试将图片中的表格转换成Markdown格式,需要不断条件和优化提示词。记录一下调整好的提示词,以后在继续优化迭代。 1. 提示词 英文版本: You are an AI assistant tasked with extracting the content of

计算数组的斜率,偏移,R2

模拟Excel中的R2的计算。         public bool fnCheckRear_R2(List<double[]> lRear, int iMinRear, int iMaxRear, ref double dR2)         {             bool bResult = true;             int n = 0;             dou