【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

相关文章

Java中数组与栈和堆之间的关系说明

《Java中数组与栈和堆之间的关系说明》文章讲解了Java数组的初始化方式、内存存储机制、引用传递特性及遍历、排序、拷贝技巧,强调引用数据类型方法调用时形参可能修改实参,但需注意引用指向单一对象的特性... 目录Java中数组与栈和堆的关系遍历数组接下来是一些编程小技巧总结Java中数组与栈和堆的关系关于

Java使用Thumbnailator库实现图片处理与压缩功能

《Java使用Thumbnailator库实现图片处理与压缩功能》Thumbnailator是高性能Java图像处理库,支持缩放、旋转、水印添加、裁剪及格式转换,提供易用API和性能优化,适合Web应... 目录1. 图片处理库Thumbnailator介绍2. 基本和指定大小图片缩放功能2.1 图片缩放的

Java中的数组与集合基本用法详解

《Java中的数组与集合基本用法详解》本文介绍了Java数组和集合框架的基础知识,数组部分涵盖了一维、二维及多维数组的声明、初始化、访问与遍历方法,以及Arrays类的常用操作,对Java数组与集合相... 目录一、Java数组基础1.1 数组结构概述1.2 一维数组1.2.1 声明与初始化1.2.2 访问

基于Python实现一个图片拆分工具

《基于Python实现一个图片拆分工具》这篇文章主要为大家详细介绍了如何基于Python实现一个图片拆分工具,可以根据需要的行数和列数进行拆分,感兴趣的小伙伴可以跟随小编一起学习一下... 简单介绍先自己选择输入的图片,默认是输出到项目文件夹中,可以自己选择其他的文件夹,选择需要拆分的行数和列数,可以通过

MySQL查询JSON数组字段包含特定字符串的方法

《MySQL查询JSON数组字段包含特定字符串的方法》在MySQL数据库中,当某个字段存储的是JSON数组,需要查询数组中包含特定字符串的记录时传统的LIKE语句无法直接使用,下面小编就为大家介绍两种... 目录问题背景解决方案对比1. 精确匹配方案(推荐)2. 模糊匹配方案参数化查询示例使用场景建议性能优

关于集合与数组转换实现方法

《关于集合与数组转换实现方法》:本文主要介绍关于集合与数组转换实现方法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、Arrays.asList()1.1、方法作用1.2、内部实现1.3、修改元素的影响1.4、注意事项2、list.toArray()2.1、方

利用Python脚本实现批量将图片转换为WebP格式

《利用Python脚本实现批量将图片转换为WebP格式》Python语言的简洁语法和库支持使其成为图像处理的理想选择,本文将介绍如何利用Python实现批量将图片转换为WebP格式的脚本,WebP作为... 目录简介1. python在图像处理中的应用2. WebP格式的原理和优势2.1 WebP格式与传统

基于 HTML5 Canvas 实现图片旋转与下载功能(完整代码展示)

《基于HTML5Canvas实现图片旋转与下载功能(完整代码展示)》本文将深入剖析一段基于HTML5Canvas的代码,该代码实现了图片的旋转(90度和180度)以及旋转后图片的下载... 目录一、引言二、html 结构分析三、css 样式分析四、JavaScript 功能实现一、引言在 Web 开发中,

Python如何去除图片干扰代码示例

《Python如何去除图片干扰代码示例》图片降噪是一个广泛应用于图像处理的技术,可以提高图像质量和相关应用的效果,:本文主要介绍Python如何去除图片干扰的相关资料,文中通过代码介绍的非常详细,... 目录一、噪声去除1. 高斯噪声(像素值正态分布扰动)2. 椒盐噪声(随机黑白像素点)3. 复杂噪声(如伪

Python中图片与PDF识别文本(OCR)的全面指南

《Python中图片与PDF识别文本(OCR)的全面指南》在数据爆炸时代,80%的企业数据以非结构化形式存在,其中PDF和图像是最主要的载体,本文将深入探索Python中OCR技术如何将这些数字纸张转... 目录一、OCR技术核心原理二、python图像识别四大工具库1. Pytesseract - 经典O