当前位置: 首页 > news >正文

【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 是一个用于图像处理和图形操作的库&#xff0c;它是 System.Drawing 命名空间的一部分。由于 .NET Core 和 .NET 5 的跨平台特性&#xff0c;许多以前内置于 .NET Framework…...

Bug:Linux用户拥有r权限但无法打开文件【Linux权限体系】

Bug&#xff1a;Linux用户拥有r权限但无法打开文件【Linux权限体系】 0 问题描述&解决 问题描述&#xff1a; 通过go编写了一个程序&#xff0c;产生的/var/log/xx日志文件发现普通用户无权限打开 - 查看文件权限发现该文件所有者、所有者组、其他用户均有r权限 - 查看该日…...

【Redis】Widows 和 Linux 下使用 Redis

Redis 简述 1.缓存 缓存就是将数据存放在距离计算最近的位置以加快处理速度。缓存是改善软件性能的第一手段,现代 CPU 越来越快的一个重要因素就是使用了更多的缓存,在复杂的软件设计中,缓存几乎无处不在。大型网站架构设计在很多方面都使用了缓存设计。 2.Redis Redis …...

统计计算四|蒙特卡罗方法(Monte Carlo Method)

系列文章目录 统计计算一|非线性方程的求解 统计计算二|EM算法&#xff08;Expectation-Maximization Algorithm&#xff0c;期望最大化算法&#xff09; 统计计算三|Cases for EM 文章目录 系列文章目录一、基本概念&#xff08;一&#xff09;估算 π \pi π&#xff08;二&…...

大模型时代的具身智能系列专题(三)

清华高阳团队 高阳为清华叉院助理教授&#xff0c;本科毕业于清华大学计算机系&#xff0c;博士毕业于UC Berkeley。博士导师是Vision领域的大牛Trevor Darrell&#xff0c;读博期间和Sergey Levine合作开始强化学习方面的探索&#xff0c;博后跟随Pieter Abbeel做强化学习&am…...

使用 FileZilla 在 Windows 和 Ubuntu 之间传文件

网线一端插在板子的WAN口上&#xff0c;另一段插在电脑上&#xff0c;然后要配一下板子的IP。 板侧&#xff1a; 使用串口链接板子与PC端&#xff1b; 输入指令 ifconfig eth0&#xff08;具体看wan口对应哪一个&#xff09; 192.168.1.99 PC端配置&#xff1a; 打开网络设…...

【C++初阶】—— 类和对象 (上)

&#x1f4dd;个人主页&#x1f339;&#xff1a;EterNity_TiMe_ ⏩收录专栏⏪&#xff1a;C “ 登神长阶 ” &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; 类和对象 1. 初步认识C2. 类的引入3. 类的定义声明和定义全部放在类体中声明和定义分开存放 4.…...

基础—SQL—图形化界面工具的DataGrip使用(2)

一、回顾与引言 &#xff08;1&#xff09; 上次内容&#xff0c;博客讲到了DDL语句的数据库操作、表操作、表字段的操作的相关语法&#xff0c;然而之前都是在MySQL的命令行当中去操作演示的。这种方式可以用&#xff0c;但是使用的话&#xff0c;第一&#xff0c;在我们日常…...

4-主窗口

4-主窗口 1、简介2 菜单栏、工具栏、状态栏2.1 菜单栏2.2 QAction2.3 工具栏2.4 状态栏 3 混合方式UI设计 1、简介 QMainWindow是一个为用户提供主窗口程序的类&#xff0c;包含一个菜单栏、多个工具栏、多个停靠控件、一个状态栏以及一个中心控件&#xff0c;是许多应用程序&…...

四川景源畅信:抖音小店新手如何做?

随着短视频平台的兴起&#xff0c;抖音小店成为了许多创业者的新选择。但是&#xff0c;对于新手来说&#xff0c;如何在抖音上开设并经营好自己的小店呢?本文将围绕这一问题展开讨论。 一、明确目标和定位作为抖音小店的新手&#xff0c;首先要明确自己的经营目标和定位。是想…...

EventSource

什么是EventSource EventSource 是一个用于服务器推送事件&#xff08;Server-Sent Events, SSE&#xff09;的接口&#xff0c;它允许服务器推送实时更新到浏览器。与 WebSocket 不同&#xff0c;SSE 是单向的&#xff08;服务器到客户端&#xff09;&#xff0c;适用于更新频…...

Vue2 Element-UI 分页组件el-pagination 修改 自带的total、跳转等默认文字

场景需求&#xff1a; Vue2 Element-UI 分页组件el-pagination 修改 自带的total、跳转等默认文字。如下图&#xff1a;默认提示字变成了英文&#xff0c;如何将其 变成 汉字提示呢&#xff1f; 解决方案&#xff1a; 1.方案1&#xff1a;修改DOM内容 不提倡此方案&#xf…...

【简单介绍下线性回归模型】

&#x1f308;个人主页: 程序员不想敲代码啊 &#x1f3c6;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f44d;点赞⭐评论⭐收藏 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共…...

有限元法之有限元空间的构造

目录 一、区域Ω的剖分 二、三角形一次元 三、一次元的基函数与面积坐标 四、三角形二次元及其基函数 前两节我们介绍了有限元基本概念和变分理论的推导&#xff0c;本节我们继续探讨有限元空间的构造。 一、区域Ω的剖分 对矩形区域进行三角剖分&#xff0c;其中x方向剖…...

高通车规芯片分析

高通三款芯片 SA8155P 7nm SA8295P 5nm SA8255P 5nm 分析AECQ等级 AECQ100里面定义了5个工作环境温度等级&#xff1a;Grade0&#xff1a;-40-150 Grade1&#xff1a;-40-125 Grade2&#xff1a;-40-105 Grade3&#xff1a;-40-85 Grade4&#xff1a;0-70AEC-Q100整体认证测试…...

Flutter 中的 TextButton 小部件:全面指南

Flutter 中的 TextButton 小部件&#xff1a;全面指南 在Flutter的世界里&#xff0c;TextButton是一个基础的小部件&#xff0c;用于创建只包含文本的按钮。它通常用于对话框、表单以及需要强调主要操作的界面。本文将为您提供一个全面的指南&#xff0c;帮助您了解如何使用T…...

通过键值对访问字典

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 在Python中&#xff0c;如果想将字典的内容输出也比较简单&#xff0c;可以直接使用print()函数。例如&#xff0c;要想打印dictionary字典&#xff…...

海外仓扫码管理系统怎么选?精准,高效管理需求才是核心需求

海外仓对那些想拓展国际市场的商家来说还是非常重要的&#xff0c;大部分的货物都需要先运到海外仓&#xff0c;才能继续进行下一步的物流快递发货。 那对于海外仓本身来说&#xff0c;当面临大量订单的时候&#xff0c;怎么快速的管理订单&#xff0c;拣选货物就变得十分重要…...

基于51单片机的智能灯光控制系统

一.硬件方案 智能灯光控制系统由单片机最小系统、人体感应模块、关照强度模块、灯光控制模块、电源模块和灯泡组成。本文以STC89C52单片机为核心&#xff0c;通过利用光照度和红外人体感应相结合主动与被动的探测方法&#xff0c;现了室内无人或者关照充足时灯光自动光灯&…...

测试开发面试题

简述自动化测试的三大等待 强制等待。直接使用time.sleep()方法让程序暂停指定的时间。优点是实现简单&#xff0c;缺点是不够灵活&#xff0c;可能会导致不必要的等待时间浪费。隐式等待。设置一个固定的等待时间&#xff0c;在这个时间内不断尝试去查找元素&#xff0c;如果…...

FastAPI 教程:从入门到实践

FastAPI 是一个现代、快速&#xff08;高性能&#xff09;的 Web 框架&#xff0c;用于构建 API&#xff0c;支持 Python 3.6。它基于标准 Python 类型提示&#xff0c;易于学习且功能强大。以下是一个完整的 FastAPI 入门教程&#xff0c;涵盖从环境搭建到创建并运行一个简单的…...

基于Uniapp开发HarmonyOS 5.0旅游应用技术实践

一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架&#xff0c;支持"一次开发&#xff0c;多端部署"&#xff0c;可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务&#xff0c;为旅游应用带来&#xf…...

OkHttp 中实现断点续传 demo

在 OkHttp 中实现断点续传主要通过以下步骤完成&#xff0c;核心是利用 HTTP 协议的 Range 请求头指定下载范围&#xff1a; 实现原理 Range 请求头&#xff1a;向服务器请求文件的特定字节范围&#xff08;如 Range: bytes1024-&#xff09; 本地文件记录&#xff1a;保存已…...

【单片机期末】单片机系统设计

主要内容&#xff1a;系统状态机&#xff0c;系统时基&#xff0c;系统需求分析&#xff0c;系统构建&#xff0c;系统状态流图 一、题目要求 二、绘制系统状态流图 题目&#xff1a;根据上述描述绘制系统状态流图&#xff0c;注明状态转移条件及方向。 三、利用定时器产生时…...

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中&#xff0c;新增了一个本地验证码接口 /code&#xff0c;使用函数式路由&#xff08;RouterFunction&#xff09;和 Hutool 的 Circle…...

AGain DB和倍数增益的关系

我在设置一款索尼CMOS芯片时&#xff0c;Again增益0db变化为6DB&#xff0c;画面的变化只有2倍DN的增益&#xff0c;比如10变为20。 这与dB和线性增益的关系以及传感器处理流程有关。以下是具体原因分析&#xff1a; 1. dB与线性增益的换算关系 6dB对应的理论线性增益应为&…...

Linux 内存管理实战精讲:核心原理与面试常考点全解析

Linux 内存管理实战精讲&#xff1a;核心原理与面试常考点全解析 Linux 内核内存管理是系统设计中最复杂但也最核心的模块之一。它不仅支撑着虚拟内存机制、物理内存分配、进程隔离与资源复用&#xff0c;还直接决定系统运行的性能与稳定性。无论你是嵌入式开发者、内核调试工…...

【C++特殊工具与技术】优化内存分配(一):C++中的内存分配

目录 一、C 内存的基本概念​ 1.1 内存的物理与逻辑结构​ 1.2 C 程序的内存区域划分​ 二、栈内存分配​ 2.1 栈内存的特点​ 2.2 栈内存分配示例​ 三、堆内存分配​ 3.1 new和delete操作符​ 4.2 内存泄漏与悬空指针问题​ 4.3 new和delete的重载​ 四、智能指针…...

论文阅读笔记——Muffin: Testing Deep Learning Libraries via Neural Architecture Fuzzing

Muffin 论文 现有方法 CRADLE 和 LEMON&#xff0c;依赖模型推理阶段输出进行差分测试&#xff0c;但在训练阶段是不可行的&#xff0c;因为训练阶段直到最后才有固定输出&#xff0c;中间过程是不断变化的。API 库覆盖低&#xff0c;因为各个 API 都是在各种具体场景下使用。…...

Spring Boot + MyBatis 集成支付宝支付流程

Spring Boot MyBatis 集成支付宝支付流程 核心流程 商户系统生成订单调用支付宝创建预支付订单用户跳转支付宝完成支付支付宝异步通知支付结果商户处理支付结果更新订单状态支付宝同步跳转回商户页面 代码实现示例&#xff08;电脑网站支付&#xff09; 1. 添加依赖 <!…...