【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.nupkg
  OK 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图片的详细信息如下图所示:
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

10.SpringBoot 统一处理功能

文章目录 1.拦截器1.1在代码中的应用1.1.1定义拦截器1.1.2注册配置拦截器 1.2拦截器的作用1.3拦截器的实现 2.统一数据返回格式2.1 为什么需要统⼀数据返回格式&#xff1f;2.2 统⼀数据返回格式的实现 3.统一异常处理4.SpringBoot专业版创建项目无Java8版本怎么办&#xff1f;…

[转载]同一台电脑同时使用GitHub和GitLab

原文地址&#xff1a;https://developer.aliyun.com/article/893801 简介&#xff1a; 工作中我们有时可能会在同一台电脑上使用多个git账号&#xff0c;例如&#xff1a;公司的gitLab账号&#xff0c;个人的gitHub账号。怎样才能在使用gitlab与github时&#xff0c;切换成对应…

Vue.js - 计算属性与侦听器 【0基础向 Vue 基础学习】

文章目录 计算属性 computedcomputed 的使用方法computed 与 method 的区别计算属性完整写法 watch 侦听器&#xff08;监视器&#xff09;简单写法 → 简单类型数据&#xff0c;直接监视完整写法 → 添加额外配置项 计算属性 computed computed 的使用方法 **概念&#xff1…

红外超声波雷达测距

文章目录 一HC-SR04介绍1HC-SR04简介及工作原理 二用HAL库实现HC-SR04测量距离1STM32CubeMX配置2keil53代码的添加 三效果 一HC-SR04介绍 1HC-SR04简介及工作原理 超声波是振动频率高于20kHz的机械波。它具有频率高、波长短、绕射现象小、方向性好、能够成为射线而定向传播等…

如何使用 Re-Ranking 改进大模型 RAG 检索

基于大型语言模型&#xff08;LLMs&#xff09;的聊天机器人可以通过检索增强生成&#xff08;RAG&#xff09;提供外部知识来改进。 这种外部知识可以减少错误答案&#xff08;幻觉&#xff09;&#xff0c;并且使模型能够访问其训练数据中未包含的信息。 通过RAG&#xff0…

【Docker学习】详细讲解docker ps

docker ps是我们操作容器次数最多的命令之一&#xff0c;但我们往往使用docker ps或是docker ps -a&#xff0c;对于该命令的其它选项&#xff0c;我们关注比较少。那么这一讲&#xff0c;我给大家详细讲讲该命令的全部方法。 命令&#xff1a; docker container ls 描述&am…

web题解,基础知识巩固(qsnctf)

1.文章管理系统 1&#xff09;打开题目&#xff0c;把它页面翻完了&#xff0c;没看懂它有啥用 2&#xff09;看了看源码&#xff0c;也是一样的&#xff0c;没找到有用的东西 3&#xff09;想着可能还是在隐藏文件里找&#xff0c;那我就直接用dirsearch扫扫看 4&#xff09;…

常见API(JDK7时间、JDK8时间、包装类、综合练习)

一、JDK7时间——Date 1、事件相关知识点 2、Date时间类 Data类是一个JDK写好的Javabean类&#xff0c;用来描述时间&#xff0c;精确到毫秒。 利用空参构造创建的对象&#xff0c;默认表示系统当前时间。 利用有参构造创建的对象&#xff0c;表示指定的时间。 练习——时间计…

Flink 数据源

原理 在 Flink 中&#xff0c;数据源&#xff08;Source&#xff09;是其中一个核心组件&#xff0c;负责从各种来源读取数据供 Flink 程序处理。 Flink 的数据源类型丰富&#xff0c;涵盖了从简单测试到生产环境使用的各种场景。Kafka、Socket、文件和集合是 Flink 中最常见…

Java后端面经

1.可重复读&#xff0c;已提交读&#xff0c;这两个隔离级别表现的现象是什么&#xff0c;区别是什么样的&#xff1f; 可重复读&#xff1a;表示整个事务看到的事务和开启后的事务能看到的数据是一致的&#xff0c;既然数据是一致的&#xff0c;所以不存在不可重复读。而且不…

【傻呱呱】VirtualHere共享局域网中的USB设备(使用Pavadan老毛子固件搭建篇)

前期准备 SSH工具&#xff08;FinalShell&#xff09;老毛子固件路由器一台 搭建VirtualHere服务端 进入VirtualHere官网下载对应处理器架构的包&#xff0c;我的是RT-N14U-GPIO路由器刷的老毛子固件&#xff0c;这种一般选择最后一个或者倒数第二个包&#xff0c;这里我选择…

[NOIP 2014] 寻找道路

[NOIP 2014] 寻找道路 在有向图 G 中&#xff0c;每条边的长度均为 11&#xff0c;现给定起点和终点&#xff0c;请你在图中找一条从起点到终点的路径&#xff0c;该路径满足以下条件&#xff1a; 路径上的所有点的出边所指向的点都直接或间接与终点连通。在满足条件 11 的情…

01Python相关基础学习

Python基础 模块相关导入模块sys模块 模块相关 导入模块 1. import 模块名 2. import 模块名 as 别名 3. from 模块名 import 成员名 as 别名sys模块 1. sys.argv 介绍: 实现从程序的外部想程序传递参数返回的是一个列表,第一个元素是程序文件名,第二个元素是程序外部传入的…

景源畅信:新手做抖音运营难不难?

在这个信息爆炸的时代&#xff0c;社交媒体平台如抖音已经成为了人们日常生活中不可或缺的一部分。随着抖音的兴起&#xff0c;越来越多的人开始尝试进入这个领域&#xff0c;希望通过抖音运营实现自己的价值。然而&#xff0c;对于新手来说&#xff0c;抖音运营是否真的容易呢…

网络安全等级保护2.0(等保)是什么

等保的全称是信息安全等级保护&#xff0c;是《网络安全法》规定的必须强制执行的&#xff0c;保障公民、社会、国家利益的重要工作。 通俗来讲就是&#xff1a;公司或者单位因为要用互联网&#xff0c;但是网上有坏人&#xff0c;我们不仅要防御外部坏人&#xff0c;还要看看…

我的世界开服保姆级教程

前言 Minecraft开服教程 如果你要和朋友联机时&#xff0c;可以选择的方法有这样几种&#xff1a; 局域网联机&#xff1a;优点&#xff1a;简单方便&#xff0c;在MC客户端里自带。缺点&#xff1a;必须在同一局域网内。 有些工具会带有联机功能&#xff1a;优点&#xff1a;一…

云原生Kubernetes: 云主机部署K8S 1.30版本 单Master架构

目录 一、实验 1.环境 2.Termius连接云主机 3.网络连通性与安全机制 4.云主机部署docker 5.云主机配置linux内核路由转发与网桥过滤 6.云主机部署cri-dockerd 7.云主机部署kubelet,kubeadm,kubectl 8.kubernetes集群初始化 9.容器网络&#xff08;CNI&#xff09;部署…

力扣刷题--LCR 075. 数组的相对排序【简单】

题目描述 给定两个数组&#xff0c;arr1 和 arr2&#xff0c; arr2 中的元素各不相同 arr2 中的每个元素都出现在 arr1 中 对 arr1 中的元素进行排序&#xff0c;使 arr1 中项的相对顺序和 arr2 中的相对顺序相同。未在 arr2 中出现过的元素需要按照升序放在 arr1 的末尾。 …

5.27作业

定义自己的命名空间my_sapce&#xff0c;在my_sapce中定义string类型的变量s1&#xff0c;再定义一个函数完成对字符串的逆置。 #include <iostream> #include <string.h>using namespace std; namespace my_space {string s1;void RevString(string &s1); } v…

本地镜像文件怎么导入docker desktop

docker tag d1134b7b2d5a new_repo:new_tag