C# - 转换 8 位或 16 位灰度原始像素数据

2023-12-11

我需要能够将 8 位或 16 位灰度像素数据转换为 .NET 框架可以支持的文件格式。

我拥有的可用数据是宽度、高度、方向(左下角)和像素格式,即 4096 级灰度(12 位分辨率),每个像素封装为 2 个字节。

例如每个像素的范围是 0 到 4096,每个像素是 2 个字节。

我已经尝试过将 PixelFormat.Format16bppGrayScale 与 Bitmap 构造函数一起使用,它会引发 GDI+ 异常。我读到的所有内容都说不支持这种格式,并且 MSDN 是错误的。

我想将此像素缓冲区转换为 .NET 位图格式(例如 Format32bppArgb),同时尽可能减少图像质量损失。

有人知道怎么做吗?


请参阅下面的示例,该示例预先计算查找表 (LUT) 并使用它来转换每个像素。此版本涵盖您的 12 位情况;对于 8 位,代码非常相似,但很难跨像素格式进行推广。

从 12 位 GS 转换为有效的 8 位 GS 将丢失数据。但是,您可以调整 LUT 表以专注于具有更好对比度的较小范围的输入值(例如DICOM 窗口中心/窗口宽度).

class Program
{
    static void Main( string[] args )
    {
        // Test driver - create a Wedge, convert to Bitmap, save to file
        //
        int width = 4095;
        int height = 1200;
        int bits = 12;

        byte[] wedge = Wedge( width, height, bits );

        Bitmap bmp = Convert( wedge, width, height, bits );

        string file = "wedge.png";

        bmp.Save( file );

        Process.Start( file );
    }

    static Bitmap Convert( byte[] input, int width, int height, int bits )
    {
        // Convert byte buffer (2 bytes per pixel) to 32-bit ARGB bitmap

        var bitmap = new Bitmap( width, height, PixelFormat.Format32bppArgb );

        var rect = new Rectangle( 0, 0, width, height );

        var lut = CreateLut( bits );

        var bitmap_data = bitmap.LockBits( rect, ImageLockMode.WriteOnly, bitmap.PixelFormat );

        ConvertCore( width, height, bits, input, bitmap_data, lut );

        bitmap.UnlockBits( bitmap_data );

        return bitmap;
    }

    static unsafe void ConvertCore( int width, int height, int bits, byte[] input, BitmapData output, uint[] lut )
    {
        // Copy pixels from input to output, applying LUT

        ushort mask = (ushort)( ( 1 << bits ) - 1 );

        int in_stride = output.Stride;
        int out_stride = width * 2;

        byte* out_data = (byte*)output.Scan0;

        fixed ( byte* in_data = input )
        {
            for ( int y = 0; y < height; y++ )
            {
                uint* out_row = (uint*)( out_data + ( y * in_stride ) );

                ushort* in_row = (ushort*)( in_data + ( y * out_stride ) );

                for ( int x = 0; x < width; x++ )
                {
                    ushort in_pixel = (ushort)( in_row[ x ] & mask );

                    out_row[ x ] = lut[ in_pixel ];
                }
            }
        }
    }

    static uint[] CreateLut( int bits )
    {
        // Create a linear LUT to convert from grayscale to ARGB

        int max_input = 1 << bits;

        uint[] lut = new uint[ max_input ];

        for ( int i = 0; i < max_input; i++ )
        {
            // map input value to 8-bit range
            //
            byte intensity = (byte)( ( i * 0xFF ) / max_input );

            // create ARGB output value A=255, R=G=B=intensity
            //
            lut[ i ] = (uint)( 0xFF000000L | ( intensity * 0x00010101L ) );
        }

        return lut;
    }

    static byte[] Wedge( int width, int height, int bits )
    {
        // horizontal wedge

        int max = 1 << bits;

        byte[] pixels = new byte[ width * height * 2 ];

        for ( int y = 0; y < height; y++ )
        {
            for ( int x = 0; x < width; x++ )
            {
                int pixel = x % max;

                int addr = ( ( y * width ) + x ) * 2;

                pixels[ addr + 1 ] = (byte)( ( pixel & 0xFF00 ) >> 8 );
                pixels[ addr + 0 ] = (byte)( ( pixel & 0x00FF ) );
            }
        }

        return pixels;
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C# - 转换 8 位或 16 位灰度原始像素数据 的相关文章

  • C语言实现延时函数

    我想使用空循环实现延迟函数 但是完成一次循环所需的时间取决于编译器和机器 我希望我的程序自行确定时间并将程序延迟指定的时间 谁能给我任何想法如何做到这一点 注意 有一个名为delay 的函数可以将系统暂停指定的毫秒 是否可以在不使用此功能的
  • 等待运算符错误

    我的代码有问题 我怎么解决这个问题 这个问题出现在await操作符中 public MyModel HttpClient client new HttpClient HttpResponseMessage response await cl
  • C 中的 '\0' 和 printf()

    在 C 入门课程中 我了解到在存储字符串时存储空字符 0在它的最后 但是如果我想打印一个字符串怎么办 printf hello 虽然我发现它并没有结束 0通过以下声明 printf d printf hello Output 5 但这似乎不
  • C 链表销毁函数

    我正在尝试学习 C 和很多人一样 我对指针有点困惑 无论如何 我创建了一个递归函数来销毁我的链表 但是正如我调试的那样 当我从函数返回时 列表的头部不应该为空 所以我猜这是对指针的一些基本误解 这是函数 void destroy struc
  • 为什么 ObservableCollection 有两个集合构造函数?

    The 可观察集合 T https msdn microsoft com en us library ms668604类有两个构造函数 可以在其中传递项目集合 一个构造函数接受一个IEnumerable T 另一个List T 鉴于List
  • 使用 LINQ 展平嵌套字典

    所以我有一本形式的字典Dictionary
  • UI 线程正在阻塞调用 COM 对象的后台线程

    我正在开发一个通过第三方 COM 库与外部设备通信的应用程序 我试图让与设备的所有通信都通过后台线程 以防止通信问题搞砸我的应用程序 并消除在 UI 线程中进行通信所引入的一些其他复杂性 问题是 每当发生导致主 UI 线程阻塞的情况 即调用
  • 微软怎么能说WinAPI中一个字的大小是16位呢?

    我刚刚开始学习WinAPI 在MSDN中 对WORD数据类型提供了以下解释 WORD16 位无符号整数 范围是十进制 0 到 65535 该类型在 WinDef h 中声明如下 typedef 无符号短 WORD 很简单 而且它与我一直在使
  • 为什么我收到编译错误“使用已删除的函数 'std::unique_ptr ...”

    我收到一条巨大的编译错误消息 c mingw include c 6 1 0 bits predefined ops h 123 18 error use of deleted function std unique ptr lt Tp D
  • 将 std::pair const 转换为 std::pair const 安全吗?

    理论上或实践上 安全吗reinterpret cast a std pair
  • 编译器消息“警告:格式‘%s’需要类型‘char *’,但参数 2 具有类型‘char (*)’”

    我正在尝试运行一个简单的 C 程序 但收到此错误 警告 格式 s 需要类型 char 但参数 2 的类型为 char 20 我在跑步Mac OS X v10 8 https en wikipedia org wiki OS X Mounta
  • 是否自初始化 'A a = a;'允许吗?

    此代码在运行时在复制构造函数中失败 但编译器 MSVS2008 没有发出警告 您能解释一下 最好引用标准 这段代码是否非法或什么 我理解 A a a 永远不应该写在第一位 但我正在寻找理论背景 class A public A p new
  • 如何解析多态 JSON 数组?

    我有一个 JSON 格式的文件 其中包含个人用户的记录 一些用户的记录中间有一个评论字段 我只想解析顶级项目 全名 贡献者姓名 电子邮件 使用 Newtonsoft JSON 解析器 但我似乎无法让它识别单个对象 当我将整个字符串解析为一个
  • 使用信号和槽更新指针

    我对 Qt 很陌生 请帮我解决这个问题 我正在使用线程在后台执行密集操作 同时我想更新 UI 所以我使用 SIGNALS 和 SLOTS 为了更新 UI 我发出一个信号并更新 UI 让我们考虑下面的示例代码 struct sample QS
  • 解析连接字符串

    是否有标准库或代码片段可以使用这样的连接字符串获取值 string connstr DataServiceUrl http localhost foo RemoteServerConnection server http localhost
  • 我的代码哪里有泄漏?

    下面是我的代码 它打开一个 XML 文件 old xml 过滤无效字符并写入另一个 XML 文件 abc xml 最后 我将再次加载 XML abc xml 当执行以下行时 出现异常 表示 xml 文件被另一个进程使用 xDoc Load
  • 如何解决 boost::multi precision::cpp_dec_float 除法错误

    除以boost multiprecision cpp dec float有某种舍入误差 如下 include
  • NSubstitute - 测试特定的 linq 表达式

    我在当前正在开发的 MVC 3 应用程序中使用存储库模式 我的存储库界面如下所示 public interface IRepository
  • 使用 DataGridViewCheckboxCell 真正禁用 DataGridView 中的复选框

    有谁知道如何使用 DataGridViewCheckboxCell 禁用 DataGridView 中的复选框 我可以将其设置为只读 并设置背景颜色 但我无法让复选框本身显示为禁用状态 有什么想法吗 Guess 你必须自己画 http so
  • 从数据库配置中的连接字符串中删除 SSIS 密码

    我有一个 SSIS 包 它使用 SQL 服务器中的 SSIS 配置表来检索 OLE DB 连接管理器的连接字符串属性 问题是我还需要相同的连接字符串来调用使用实体框架的程序集 我尝试访问连接管理器连接字符串属性 但 SSIS 总是删除密码

随机推荐

  • 如何用Python对大文件进行排序?

    我在 activestate com 上发现了一些很有前途的代码来对大文件进行排序 我试图在 Ubuntu 10 04 上的默认 Python 2 6 5 解释器上运行它 当我尝试在一个小测试文件上运行它时 我得到下面的错误跟踪 我在 ac
  • 由文本选择触发的工具提示

    我希望创建一个由选择文本 左键单击并拖动文本 触发的工具提示 最好通过创建一个 JQuery 插件 我的最终目标是当用户选择 突出显示一个句子 短语 段落时 它将触发工具提示 工具提示将包含社交共享按钮 允许用户将选择发布到他们的个人资料状
  • 甜蜜警报功能不显示消息

    我试图在将记录插入数据库后显示一条警报消息 并且正常的 js 警报工作正常 其代码是 echo echo exit 但是 当我使用 sweet Alert 函数而不是普通的 js 函数时 它不会显示
  • 后续:将 vegan 包中的 ordiellipse 函数绘制到 ggplot2 中创建的 NMDS 图上

    我正在尝试做一些类似于旧帖子的事情 绘图 原始帖子 在我的分析中 我感兴趣的是不同的哺乳动物宿主是否有不同的跳蚤群落 我链接到的原始帖子有两种不同的椭圆解决方案 我的问题是 当我运行第一个解决方案和通用解决方案时 我得到的图看起来截然不同
  • h1 和 h2 类未显示在 Internet Explorer 中

    我无法获取h1 and h2标签完全显示在 Internet Explorer 中 我查看了 CSS 文件 但仍然不明白为什么它不能在 IE9 上运行 以下是 IE 中未显示的标题的 CSS 代码 person h1 color 47526
  • EXC_BAD_ACCESS 调用块

    更新 我已经使用面板 上传了一个示例项目并在此处崩溃 http w3style co uk d11wtq BlocksCrash tar gz 我知道 选择 按钮没有任何作用 我还没有实现它 更新2 刚刚发现我什至不需要调用任何东西newF
  • pyparsing - 如何使用比较运算符解析字符串?

    所以 我有一个NumericStringParser类 摘自here 定义如下 from future import division from pyparsing import Literal CaselessLiteral Word C
  • 在 C++ 程序中使用多个 .cpp 文件?

    我最近从 Java 转向 C 但现在当我编写应用程序时 我对在主函数中编写所有代码不感兴趣 我希望在主函数中调用另一个函数 但这个另一个函数位于另一个 cpp 文件中 如果你不明白 让我更好地解释一下 我有一个文件 main cpp在它里面
  • Shiny - 使用基于输入的过滤数据填充静态 HTML 表

    我目前正在开发一个 Shiny 应用程序 它显示一个静态 HTML 表格 由于 HTML 代码的大小 该表格源自另一个文件 该表使用空数据表进行初始化 以便呈现空表 上面的HTML表格都是正常的selectizeInput在后台过滤数据表的
  • android imageView:设置拖动和捏缩放参数

    我目前正在为 Android 我的第一个应用程序 开发一个应用程序 它可以让用户查看地铁地图并能够进行缩放和拖动 我目前正在修改 Hello Android 第 3 版中的代码 并让捏缩放和拖动功能正常工作 我使用 Matrix 作为布局比
  • 如何在 Liferay 6 中以编程方式创建结构和模板

    我需要通过 java 代码以编程方式创建结构和模板 我使用了以下代码片段 结构 public void createStructure String userName long userId log info Inside create s
  • 用户“homestead”@“localhost”的访问被拒绝(使用密码:YES)

    我在 Mac OS Yosemite 上使用 Laravel 5 0 当在我的local环境 我跑php artisan migrate我不断得到 用户 homestead localhost 的访问被拒绝 使用密码 YES 配置 这是我的
  • 关闭 PHP 和 MySQL 上的警告和错误

    我收到了预期的通知和警告 并想在我的 PHP 文件中将其关闭 错误是 Warning fsockopen 并且通知内容是 Notice A non well formed numeric value encountered in 我计划对此
  • 为 hibernate 和 @Transactional 配置 spring 数据源

    目前 我正在使用带有 Transactional 注释的 DriverManagerDataSource 来管理事务 但所有事务都非常非常慢 可能是因为数据源每次打开和关闭与数据库的连接 我应该使用什么数据源来加速交易 我在我的应用程序中结
  • InteropBitmap 到 BitmapImage

    我正在尝试转换Bitmap SystemIcons Question to a BitmapImage所以我可以在 WPF Image 控件中使用它 我有以下方法将其转换为BitmapSource 但它返回一个InteropBitmapIm
  • 如何将参数传递给事件触发器wpf中存在的方法

    实际上 我试图在 Xaml 文件的 ViewModel 中存在的方法 UpdateWord object obj 中传递单词文档的名称 这样就可以打开word文档了
  • 即使遵循了最佳实践,仍然不断达到 GitHub 二级速率限制?

    在我的应用程序中 我使用令牌向 GitHub 搜索 API 发出经过身份验证的请求 我每 2 秒发出一次请求 以保持在每分钟 30 个请求的主要速率限制内 因此不是同时进行 并且在进行实际的搜索 API 调用之前 我还会使用 GitHub
  • 确定 PHP 中缩短的 URL 的最终目的地?

    我怎样才能在 PHP 中做到这一点 例如 bit ly f00b4r gt http www google com search q cute kittens 在Java中 解决方案是这样的 您应该发出 HEAD 请求 使用 HttpWeb
  • 第二个重写规则在 htaccess 中不起作用并显示 404 未找到页面

    嗨 我有这样的链接 www example com a letter a 1 html www example com b letter b 1 html a字母和b字母文件夹下还有3个文件 我删除了a letter包含以下 htacces
  • C# - 转换 8 位或 16 位灰度原始像素数据

    我需要能够将 8 位或 16 位灰度像素数据转换为 NET 框架可以支持的文件格式 我拥有的可用数据是宽度 高度 方向 左下角 和像素格式 即 4096 级灰度 12 位分辨率 每个像素封装为 2 个字节 例如每个像素的范围是 0 到 40