【CSharp】将ushort数组保存为1通道位深16bit的Tiff图片
【CSharp】将ushort数组保存为1通道位深16bit的Tiff图片
- 1.背景
- 2.接口
1.背景
System.Drawing.Common 是一个用于图像处理和图形操作的库,它是 System.Drawing 命名空间的一部分。由于 .NET Core 和 .NET 5+ 的跨平台特性,许多以前内置于 .NET Framework 中的库被移到了独立的NuGet包中,以便更好地管理和跨平台使用。
System.Drawing.Common 提供了处理图像的基础设施,包括创建、修改和保存图像的功能。
在使用与图像相关的类(如 Bitmap 和 Graphics)时,需要引用这个包。
通过 NuGet 包管理器安装:System.Drawing.Common
如下图所示:

安装完成后,将在项目下的packages目录下生成System.Drawing.Common.8.0.5文件夹,如下图:

使用如下代码创建16位深的Tiff图:
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;namespace Raw2Tiff
{class jn10010537{static void Main(){// 示例 ushort 数组int width = 100;int height = 100;ushort[] ushortArray = new ushort[width * height];Random random = new Random();for (int i = 0; i < ushortArray.Length; i++){ushortArray[i] = (ushort)random.Next(0, 65536);}// 将 ushort 数组转换为 byte 数组byte[] byteArray = new byte[ushortArray.Length * 2];Buffer.BlockCopy(ushortArray, 0, byteArray, 0, byteArray.Length);// 创建 Bitmap 对象Bitmap bitmap = new Bitmap(width, height, PixelFormat.Format16bppGrayScale);// 获取 BitmapData 对象// 使用LockBits方法可以更快地设置像素,该方法允许您将托管数据快速封送到非托管位图字节。BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, bitmap.PixelFormat);// 将 byte 数组拷贝到 BitmapData 对象Marshal.Copy(byteArray, 0, bitmapData.Scan0, byteArray.Length);// 解锁 BitmapData 对象bitmap.UnlockBits(bitmapData);// 保存为 TIFF 图片bitmap.Save("output.tiff", ImageFormat.Tiff);Console.WriteLine("图片已保存为 output.tiff");}}
}
运行如下:

原因:请注意,GDI+似乎不支持16bpp灰度,这意味着。net无法将16bpp灰度位图保存到文件或流中。
2.接口
在Windows上使用System.Drawing.Common处理16位灰度图像保存为TIFF时,目前(2024-05-27)会遇到问题!
因为默认情况下System.Drawing库不直接支持16位灰度图像的处理。
本博客采用的替代解决方案是使用BitMiracle.LibTiff.NET库,这是一个强大的库,专门用于处理TIFF图像格式。
通过 NuGet 包管理器安装: BitMiracle.LibTiff.NET 包,
如下图:

安装日志:
正在尝试收集与目标为“.NETFramework,Version=v4.7.2”的项目“Raw2Tiff”有关的包“BitMiracle.LibTiff.NET.2.4.649”的依赖项信息
收集依赖项信息花费时间 665 ms
正在尝试解析程序包“BitMiracle.LibTiff.NET.2.4.649”的依赖项,DependencyBehavior 为“Lowest”
解析依赖项信息花费时间 0 ms
正在解析操作以安装程序包“BitMiracle.LibTiff.NET.2.4.649”
已解析操作以安装程序包“BitMiracle.LibTiff.NET.2.4.649”GET https://api.nuget.org/v3-flatcontainer/bitmiracle.libtiff.net/2.4.649/bitmiracle.libtiff.net.2.4.649.nupkgOK https://api.nuget.org/v3-flatcontainer/bitmiracle.libtiff.net/2.4.649/bitmiracle.libtiff.net.2.4.649.nupkg 172 毫秒
已通过内容哈希 XCEdfCphKo0UAvSg1h/OzOFWtjkIGnPMAziYkNqV7NVrqb/tZJTBxJhxIEX7gpvQwg8GIRYt133SUncfkKfjLA== 从 https://api.nuget.org/v3/index.json 安装 BitMiracle.LibTiff.NET 2.4.649 。
正在将包“BitMiracle.LibTiff.NET.2.4.649”添加到文件夹“C:\Users\Administrator\Desktop\IRay_CSahep\Raw2Tiff\packages”
已将包“BitMiracle.LibTiff.NET.2.4.649”添加到文件夹“C:\Users\Administrator\Desktop\IRay_CSahep\Raw2Tiff\packages”
已将包“BitMiracle.LibTiff.NET.2.4.649”添加到“packages.config”
已将“BitMiracle.LibTiff.NET 2.4.649”成功安装到 Raw2Tiff
执行 nuget 操作花费时间 2.52 sec
已用时间: 00:00:03.3026348
========== 已完成 ==========
安装完成将在项目文件目录下生成"BitMiracle.LibTiff.NET.2.4.649"文件夹,如下图:

以下是使用BitMiracle.LibTiff.NET保存16位灰度TIFF图像的示例代码:
using System;
using BitMiracle.LibTiff.Classic;namespace Raw2Tiff
{class jn10010537{static void Main(){// 示例 ushort 数组int width = 300;int height = 500;ushort[] ushortArray = new ushort[width * height];Random random = new Random();for (int i = 0; i < ushortArray.Length; i++){ushortArray[i] = (ushort)random.Next(0, 65536);}// 保存为 TIFF 图片Save16BitGrayscaleTiff("jn10010537.tiff", ushortArray, width, height);Console.WriteLine("图片已保存成功!");Console.ReadKey();}private static void Save16BitGrayscaleTiff(string fileName, ushort[] imageData, int width, int height){using (Tiff output = Tiff.Open(fileName, "w")){output.SetField(TiffTag.IMAGEWIDTH, width);output.SetField(TiffTag.IMAGELENGTH, height);output.SetField(TiffTag.SAMPLESPERPIXEL, 1);output.SetField(TiffTag.BITSPERSAMPLE, 16);output.SetField(TiffTag.ORIENTATION, Orientation.TOPLEFT);output.SetField(TiffTag.PLANARCONFIG, PlanarConfig.CONTIG);output.SetField(TiffTag.PHOTOMETRIC, Photometric.MINISBLACK);output.SetField(TiffTag.ROWSPERSTRIP, height);int stride = width * sizeof(ushort);byte[] strip = new byte[stride];for (int row = 0; row < height; row++){Buffer.BlockCopy(imageData, row * stride, strip, 0, stride);output.WriteScanline(strip, row);}}}}
}
程序运行后将生成tiff文件,打开Tiff图片的详细信息如下图所示:

相关文章:
【CSharp】将ushort数组保存为1通道位深16bit的Tiff图片
【CSharp】将ushort数组保存为1通道位深16bit的Tiff图片 1.背景2.接口 1.背景 System.Drawing.Common 是一个用于图像处理和图形操作的库,它是 System.Drawing 命名空间的一部分。由于 .NET Core 和 .NET 5 的跨平台特性,许多以前内置于 .NET Framework…...
Bug:Linux用户拥有r权限但无法打开文件【Linux权限体系】
Bug:Linux用户拥有r权限但无法打开文件【Linux权限体系】 0 问题描述&解决 问题描述: 通过go编写了一个程序,产生的/var/log/xx日志文件发现普通用户无权限打开 - 查看文件权限发现该文件所有者、所有者组、其他用户均有r权限 - 查看该日…...
【Redis】Widows 和 Linux 下使用 Redis
Redis 简述 1.缓存 缓存就是将数据存放在距离计算最近的位置以加快处理速度。缓存是改善软件性能的第一手段,现代 CPU 越来越快的一个重要因素就是使用了更多的缓存,在复杂的软件设计中,缓存几乎无处不在。大型网站架构设计在很多方面都使用了缓存设计。 2.Redis Redis …...
统计计算四|蒙特卡罗方法(Monte Carlo Method)
系列文章目录 统计计算一|非线性方程的求解 统计计算二|EM算法(Expectation-Maximization Algorithm,期望最大化算法) 统计计算三|Cases for EM 文章目录 系列文章目录一、基本概念(一)估算 π \pi π(二&…...
大模型时代的具身智能系列专题(三)
清华高阳团队 高阳为清华叉院助理教授,本科毕业于清华大学计算机系,博士毕业于UC Berkeley。博士导师是Vision领域的大牛Trevor Darrell,读博期间和Sergey Levine合作开始强化学习方面的探索,博后跟随Pieter Abbeel做强化学习&am…...
使用 FileZilla 在 Windows 和 Ubuntu 之间传文件
网线一端插在板子的WAN口上,另一段插在电脑上,然后要配一下板子的IP。 板侧: 使用串口链接板子与PC端; 输入指令 ifconfig eth0(具体看wan口对应哪一个) 192.168.1.99 PC端配置: 打开网络设…...
【C++初阶】—— 类和对象 (上)
📝个人主页🌹:EterNity_TiMe_ ⏩收录专栏⏪:C “ 登神长阶 ” 🌹🌹期待您的关注 🌹🌹 类和对象 1. 初步认识C2. 类的引入3. 类的定义声明和定义全部放在类体中声明和定义分开存放 4.…...
基础—SQL—图形化界面工具的DataGrip使用(2)
一、回顾与引言 (1) 上次内容,博客讲到了DDL语句的数据库操作、表操作、表字段的操作的相关语法,然而之前都是在MySQL的命令行当中去操作演示的。这种方式可以用,但是使用的话,第一,在我们日常…...
4-主窗口
4-主窗口 1、简介2 菜单栏、工具栏、状态栏2.1 菜单栏2.2 QAction2.3 工具栏2.4 状态栏 3 混合方式UI设计 1、简介 QMainWindow是一个为用户提供主窗口程序的类,包含一个菜单栏、多个工具栏、多个停靠控件、一个状态栏以及一个中心控件,是许多应用程序&…...
四川景源畅信:抖音小店新手如何做?
随着短视频平台的兴起,抖音小店成为了许多创业者的新选择。但是,对于新手来说,如何在抖音上开设并经营好自己的小店呢?本文将围绕这一问题展开讨论。 一、明确目标和定位作为抖音小店的新手,首先要明确自己的经营目标和定位。是想…...
EventSource
什么是EventSource EventSource 是一个用于服务器推送事件(Server-Sent Events, SSE)的接口,它允许服务器推送实时更新到浏览器。与 WebSocket 不同,SSE 是单向的(服务器到客户端),适用于更新频…...
Vue2 Element-UI 分页组件el-pagination 修改 自带的total、跳转等默认文字
场景需求: Vue2 Element-UI 分页组件el-pagination 修改 自带的total、跳转等默认文字。如下图:默认提示字变成了英文,如何将其 变成 汉字提示呢? 解决方案: 1.方案1:修改DOM内容 不提倡此方案…...
【简单介绍下线性回归模型】
🌈个人主页: 程序员不想敲代码啊 🏆CSDN优质创作者,CSDN实力新星,CSDN博客专家 👍点赞⭐评论⭐收藏 🤝希望本文对您有所裨益,如有不足之处,欢迎在评论区提出指正,让我们共…...
有限元法之有限元空间的构造
目录 一、区域Ω的剖分 二、三角形一次元 三、一次元的基函数与面积坐标 四、三角形二次元及其基函数 前两节我们介绍了有限元基本概念和变分理论的推导,本节我们继续探讨有限元空间的构造。 一、区域Ω的剖分 对矩形区域进行三角剖分,其中x方向剖…...
高通车规芯片分析
高通三款芯片 SA8155P 7nm SA8295P 5nm SA8255P 5nm 分析AECQ等级 AECQ100里面定义了5个工作环境温度等级:Grade0:-40-150 Grade1:-40-125 Grade2:-40-105 Grade3:-40-85 Grade4:0-70AEC-Q100整体认证测试…...
Flutter 中的 TextButton 小部件:全面指南
Flutter 中的 TextButton 小部件:全面指南 在Flutter的世界里,TextButton是一个基础的小部件,用于创建只包含文本的按钮。它通常用于对话框、表单以及需要强调主要操作的界面。本文将为您提供一个全面的指南,帮助您了解如何使用T…...
通过键值对访问字典
自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 在Python中,如果想将字典的内容输出也比较简单,可以直接使用print()函数。例如,要想打印dictionary字典ÿ…...
海外仓扫码管理系统怎么选?精准,高效管理需求才是核心需求
海外仓对那些想拓展国际市场的商家来说还是非常重要的,大部分的货物都需要先运到海外仓,才能继续进行下一步的物流快递发货。 那对于海外仓本身来说,当面临大量订单的时候,怎么快速的管理订单,拣选货物就变得十分重要…...
基于51单片机的智能灯光控制系统
一.硬件方案 智能灯光控制系统由单片机最小系统、人体感应模块、关照强度模块、灯光控制模块、电源模块和灯泡组成。本文以STC89C52单片机为核心,通过利用光照度和红外人体感应相结合主动与被动的探测方法,现了室内无人或者关照充足时灯光自动光灯&…...
测试开发面试题
简述自动化测试的三大等待 强制等待。直接使用time.sleep()方法让程序暂停指定的时间。优点是实现简单,缺点是不够灵活,可能会导致不必要的等待时间浪费。隐式等待。设置一个固定的等待时间,在这个时间内不断尝试去查找元素,如果…...
第19节 Node.js Express 框架
Express 是一个为Node.js设计的web开发框架,它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用,和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...
JavaScript 中的 ES|QL:利用 Apache Arrow 工具
作者:来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗?了解下一期 Elasticsearch Engineer 培训的时间吧! Elasticsearch 拥有众多新功能,助你为自己…...
连锁超市冷库节能解决方案:如何实现超市降本增效
在连锁超市冷库运营中,高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术,实现年省电费15%-60%,且不改动原有装备、安装快捷、…...
Python爬虫(二):爬虫完整流程
爬虫完整流程详解(7大核心步骤实战技巧) 一、爬虫完整工作流程 以下是爬虫开发的完整流程,我将结合具体技术点和实战经验展开说明: 1. 目标分析与前期准备 网站技术分析: 使用浏览器开发者工具(F12&…...
Nginx server_name 配置说明
Nginx 是一个高性能的反向代理和负载均衡服务器,其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机(Virtual Host)。 1. 简介 Nginx 使用 server_name 指令来确定…...
Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)
参考官方文档:https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java(供 Kotlin 使用) 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...
Unity UGUI Button事件流程
场景结构 测试代码 public class TestBtn : MonoBehaviour {void Start(){var btn GetComponent<Button>();btn.onClick.AddListener(OnClick);}private void OnClick(){Debug.Log("666");}}当添加事件时 // 实例化一个ButtonClickedEvent的事件 [Formerl…...
ubuntu系统文件误删(/lib/x86_64-linux-gnu/libc.so.6)修复方案 [成功解决]
报错信息:libc.so.6: cannot open shared object file: No such file or directory: #ls, ln, sudo...命令都不能用 error while loading shared libraries: libc.so.6: cannot open shared object file: No such file or directory重启后报错信息&…...
热烈祝贺埃文科技正式加入可信数据空间发展联盟
2025年4月29日,在福州举办的第八届数字中国建设峰会“可信数据空间分论坛”上,可信数据空间发展联盟正式宣告成立。国家数据局党组书记、局长刘烈宏出席并致辞,强调该联盟是推进全国一体化数据市场建设的关键抓手。 郑州埃文科技有限公司&am…...
人工智能 - 在Dify、Coze、n8n、FastGPT和RAGFlow之间做出技术选型
在Dify、Coze、n8n、FastGPT和RAGFlow之间做出技术选型。这些平台各有侧重,适用场景差异显著。下面我将从核心功能定位、典型应用场景、真实体验痛点、选型决策关键点进行拆解,并提供具体场景下的推荐方案。 一、核心功能定位速览 平台核心定位技术栈亮…...
