将颜色滤镜应用于位图对象

2023-11-21

I found 这段代码关于如何在 C# 中将颜色滤镜应用到 Bitmap 对象。它的问题是它使用不安全的代码来完成此操作。有没有一种托管的、安全的方法来做同样的事情?我知道我可以使用 AForge.NET 或类似的库,但我希望有一种简单的方法来应用颜色滤镜。我所需要的只是简单的颜色替换,用黄色替换白色像素。有什么建议么?


您始终可以使用安全的 GetPixel 和 SetPixel 方法,但在许多像素上使用它们时速度很慢,这就是您使用不安全方法来使用指向位图内存的指针的原因。 不安全是这样做的方法。

如果您的位图非常小并且您不太关心性能,请使用 GetPixel 和 SetPixel 方法。

    private void ReplaceColor(Bitmap bitmap, Color originalColor, Color replacementColor)
    {
        for (var y = 0; y < bitmap.Height; y++)
        {
            for (var x = 0; x < bitmap.Width; x++)
            {
                if (bitmap.GetPixel(x, y) == originalColor)
                {
                    bitmap.SetPixel(x, y, replacementColor);
                }
            }
        }
    }

    private unsafe void ReplaceColorUnsafe(Bitmap bitmap, byte[] originalColor, byte[] replacementColor)
    {
        if (originalColor.Length != replacementColor.Length)
        {
            throw new ArgumentException("Original and Replacement arguments are in different pixel formats.");
        }

        if (originalColor.SequenceEqual(replacementColor))
        {
            return;
        }

        var data = bitmap.LockBits(new Rectangle(Point.Empty, bitmap.Size),
                                   ImageLockMode.ReadWrite,
                                   bitmap.PixelFormat);

        var bpp = Image.GetPixelFormatSize(data.PixelFormat);

        if (originalColor.Length != bpp)
        {
            throw new ArgumentException("Original and Replacement arguments and the bitmap are in different pixel format.");
        }

        var start = (byte*)data.Scan0;
        var end = start + data.Stride;

        for (var px = start; px < end; px += bpp)
        {
            var match = true;

            for (var bit = 0; bit < bpp; bit++)
            {
                if (px[bit] != originalColor[bit])
                {
                    match = false;
                    break;
                }
            }

            if (!match)
            {
                continue;
            }

            for (var bit = 0; bit < bpp; bit++)
            {
                px[bit] = replacementColor[bit];
            }
        }

        bitmap.UnlockBits(data);
    }

用法是:

        this.ReplaceColor(myBitmap, Color.White, Color.Yellow); // SLOW

OR

        var orgRGB = new byte[] { 255, 255, 255 }; // White (in RGB format)
        var repRGB = new byte[] { 255, 255, 0 }; // Yellow (in RGB format)

        var orgARGB = new byte[] { 255, 255, 255, 255 }; // White (in ARGB format)
        var repARGB = new byte[] { 255, 255, 255, 0 }; // Yellow (in ARGB format)

        var orgRGBA = new byte[] { 255, 255, 255, 255 }; // White (in RGBA format)
        var repRGBA = new byte[] { 255, 255, 0, 255 }; // Yellow (in RGBA format)

        var orgBytes = orgRGB; // or ARGB or RGBA, depending on bitmap's pixel format
        var repBytes = repRGB; // or ARGB or RGBA, depending on bitmap's pixel format

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

将颜色滤镜应用于位图对象 的相关文章

随机推荐

  • 在 Javascript 整数中放置逗号

    所以我在 Javascript 中有一个值 var val Entry val 该值的一个示例是277385 我如何在 Javascript 中将此数字转换为277 385 以及任何数字 以便它在正确的位置有逗号 function addC
  • IE 仅在按 F12 后才运行 JavaScript

    I have a strange problem in Internet Explorer with JavaScript In every browser I did the test the JavaScript is enabled
  • 如何获取分支开始的信息?

    据我所知 提交对象仅包含有关父母的信息 所以如果我遇到这样的情况 branch 1 o o master o 这相当于 branch 1 o o master o 但如果我的主人继续前进怎么办 o master o branch 1 o o
  • Android Room - 处理对象中的对象列表并查询结果

    我正在使用 Android 的 Room 数据库 并且在理解如何执行以下操作时遇到了一些大问题 当我添加一个Person到数据库中 它添加所有变量 例如List
  • mysql 时间戳转换/格式化注意:遇到格式不正确的数值

    在我的数据库中 我已将 发布 行设置为时间戳 但在尝试转换 格式化它时我收到此通知 Notice A non well formed numeric value encountered code posted date d m Y H i
  • 64位.NET性能调优

    我知道 NET is JIT在应用程序运行之前编译为您正在运行的架构 但是 JIT 编译器是否针对 64 位架构进行了优化 在编写将在计算机上运行的应用程序时 有什么需要做或考虑的吗 64bit system 即使用 Int64 会提高性能
  • 在 Web Worker 仍在运行时向其发送消息

    假设我们有一个 Web Worker 引用一个名为 worker js 的文件 我们使用worker来执行 worker js 中的一个函数 该函数执行一些冗长的操作 我们调用将相应的消息发布给工作人员并在主线程中继续 然而 在工作线程完成
  • 用“...”主体缩短字符串

    就像 iPhone 的应用程序名称很长一样 名称也会缩短 我真的很喜欢这种缩短名称或字符串的方法 而不是在其中附加 子句 抱歉 如果我感到困惑 我无法解释我想要做什么 所以我将展示一个例子 这就是我所拥有的 将 附加到缩短的字符串 在 PH
  • 应用程序小部件 setImageViewUri 不更新图像

    我有一个应用程序小部件 其中仅包含一个图像视图 我重新绘制该图像并将其作为 png 存储在应用程序的私有内存中 然后我使用 uri widget setImageViewUri R id widget icon uri 设置 RemoteV
  • 来自查询的 mysqldump

    如何从查询中为表创建 mysql 转储 我需要这样的东西 mysqldump uroot pxxxx mydb select from table where name 1 gt tmp a Thanks mysqldump 有一个 whe
  • 如何在 Yii2 中设置默认模式

    我的 Yii2 安装了 PostgreSQL 我喜欢为每个项目使用架构 而不是为每个项目使用单独的数据库 稍后设置的问题是我无法弄清楚如何通过配置选择默认架构 defaultSchema 我的迁移表有问题 因为当我运行迁移命令时它默认为 公
  • 替换包含特定字符串的整个表达式

    我的数据框有一列包含大量文件名 例如 d lt c harry11 scott80 norm avi harry11 norm avi harry11 scott80 lpf avi joel51 lpf avi rich82 joel51
  • 酸洗数据框

    我正在尝试使用以下命令来pickle DataFrame import pandas as pd from pandas import DataFrame data pd read table Purchases tsv index col
  • 将 PHP PDO 查询编写为 `dbName`.`tableName` 而不是 `tableName` - 为什么?

    我正在 PHP PDO 中编写一个用户注册函数 我发现我的查询只有这样编写才能正常运行
  • 用于拨打电话的Java API [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 目前不接受答案 是否有任何 Java API 可以给手机打电话 前提是服务提供商支持会安排拨打该电话 myProgram A gt Java API to make
  • 显式导入实例

    如何显式导入类型类实例 另外 如何通过合格的进口来做到这一点 目前 我正在做 import Control Monad Error 导入我可以使用的 monad 实例 Either String 以前 我用过 import Control
  • iOS - 检测 UIView 中的触摸?

    所以我有一个 UIView 的子类 它应该检测触摸 仅当触摸在当前视图内开始时 视图才会检测触摸 当触摸在视图之外开始并且它们在我的自定义视图内移动时 touchesMoved 不会被调用 有什么解决方案可以检测当前视图中尚未开始的移动触摸
  • 如何在客户端处理SignalR服务器异常?

    错误处理程序在客户端添加如下 connection hub url signalr connection hub logging true connection hub error function error console log Si
  • 在事务期间锁定 MYSQL 表中的行

    我有一批这样的查询 START TRANSACTION SELECT amount FROM piggybank WHERE id 2 UPDATE piggybank SET amount amount 5 WHERE id 1 COMM
  • 将颜色滤镜应用于位图对象

    I found 这段代码关于如何在 C 中将颜色滤镜应用到 Bitmap 对象 它的问题是它使用不安全的代码来完成此操作 有没有一种托管的 安全的方法来做同样的事情 我知道我可以使用 AForge NET 或类似的库 但我希望有一种简单的方