因自己的程序中需对一个窗体区域频繁进行彩色转灰度处理,为此专门写了个函数。处理对象是一块经常变化的动态区域,且是一系列绘图中的一部分,速度要求较高,算法上力求简单,所以采用以下两步方案:

1、基于DDB来写,虽然转入DIB,可不必面对各种色深,会统一算法,但转换过程会让速度上慢很多,再者这只是针对屏幕位图的函数,并无保存需要。
考虑实际情况,我只写了16、24、32位三种色深下的算法,其实4、8两种位图是最快的了,不管多大的图只需处理16与256次运算,可是现在哪有人的屏幕,还使用这两种显示模式呢?想想就没这个必要了。
相比之下,32位时最快,16位时最慢,心里有点不满意,但好在速度都不慢。差距也不超过50%。

2、灰度算法本来就不复杂,但我还是做了简化,正常处理时一般需对RGB做加权平均,取个值来统一三基色,但这需涉及浮点运算,速度上不去,效果却不见得有多好。
我的方法很简单,就是取三基色之一的值,统一起来,考虑人眼对绿色最敏感,所以算法就成RGB转GGG了。严格的说,这不叫彩转灰,叫绿转灰更合适。RGB的排列G是在中间的,想利用高速Long运算,用B值最快的,但已经够简化了,再简下去,自己都过意不去。(用B值时32位下,速度还可快1/3)
这种算法当然有缺陷,主要是对一些偏色图效果不好,但好在这种情况在色彩丰富的界面中不存在。

C2.4G 256M WinXP SP2下的测试情况
IDE环境下
1024 X 768的位图
32位屏幕 219毫秒
16位屏幕 314毫秒

N代码编译,全部优化打开
1024 X 768的位图
32位屏幕 62毫秒
16位屏幕 75毫秒

注:没有24位环境,所以也就没测了

Option Explicit
Private Type BITMAP
    bmType As Long
    bmWidth As Long
    bmHeight As Long
    bmWidthBytes As Long
    bmPlanes As Integer
    bmBitsPixel As Integer
    bmBits As Long
End Type
Private Type MemHdc
    hdc As Long
    Bmp As Long
    obm As Long
End Type
Private Declare Function GetObj Lib "gdi32" Alias "GetObjectA" (ByVal hObject As Long, ByVal nCount As Long, lpObject As Any) As Long
Private Declare Function SelectObject Lib "gdi32" (ByVal hdc As Long, ByVal hObject As Long) As Long
Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long
Private Declare Function DeleteDC Lib "gdi32" (ByVal hdc As Long) As Long
Private Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long

Private Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hdc As Long) As Long
Private Declare Function CreateCompatibleBitmap Lib "gdi32" (ByVal hdc As Long, ByVal nWidth As Long, ByVal nHeight As Long) As Long
Private Declare Function GetBitmapBits Lib "gdi32" (ByVal hBitmap As Long, ByVal dwCount As Long, lpBits As Any) As Long
Private Declare Function SetBitmapBits Lib "gdi32" (ByVal hBitmap As Long, ByVal dwCount As Long, lpBits As Any) As Long

Private Declare Function GetTickCount Lib "kernel32" () As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDest As Any, pSource As Any, ByVal dwLength As Long)
'平时常做图形处理,自己的两个公用函数也就用上了
Private Function NewMyHdc(dHdc As Long, w As Long, h As Long, Optional Bm As Long) As MemHdc
    With NewMyHdc
        .hdc = CreateCompatibleDC(dHdc)
        If Bm = 0 Then
            .Bmp = CreateCompatibleBitmap(dHdc, w, h)
        Else
            .Bmp = Bm
        End If
        .obm = SelectObject(.hdc, .Bmp)
    End With
End Function

Private Function DelMyHdc(MyHdc As MemHdc, Optional nobmp As Boolean) As MemHdc
    With MyHdc
        If .hdc <> 0 And .obm <> 0 Then SelectObject .hdc, .obm
        If nobmp = False And .Bmp <> 0 Then DeleteObject .Bmp
        If .hdc <> 0 Then DeleteDC .hdc
    End With
End Function

'灰度处理主函数
Private Function GrayBmp(dHdc As Long, x As Long, y As Long, w As Long, h As Long) As Long
    Dim tmpdc As MemHdc
    Dim i As Long, j As Long, m As Long, k As Byte, l As Long
    Dim Bm As BITMAP, AllBytes As Long, LineBytes As Long
    Dim dBits() As Byte
    Dim dBits1() As Integer
    Dim dBits2() As Long
    On Error GoTo last
    With tmpdc
        tmpdc = NewMyHdc(dHdc, w, h)
        GetObj .Bmp, Len(Bm), Bm
        If Bm.bmBitsPixel < 16 Then GoTo last
        BitBlt .hdc, 0, 0, w, h, dHdc, x, y, vbSrcCopy
        LineBytes = Bm.bmWidthBytes
        AllBytes = LineBytes * h
        Select Case Bm.bmBitsPixel
        Case 32
            ReDim dBits2(AllBytes / 4 - 1)
            GetBitmapBits .Bmp, AllBytes, dBits2(0)
            For i = 0 To AllBytes / 4 - 1
                dBits2(i) = ((dBits2(i) And &HFF00&) / &H100) * &H10101
                'dBits2(i) = (dBits2(i) And &HFF) * &H10101'用B值运算
            Next
            SetBitmapBits .Bmp, AllBytes, dBits2(0)
            GrayBmp = 32
        Case 24
            ReDim dBits(AllBytes - 1)
            GetBitmapBits .Bmp, AllBytes, dBits(0)
            For j = 0 To h - 1
                m = j * LineBytes
                For i = m To m + w * 3 - 1 Step 3
                    dBits(i) = dBits(i + 1)
                    dBits(i + 2) = dBits(i)
                Next
            Next
            SetBitmapBits .Bmp, AllBytes, dBits(0)
            GrayBmp = 24
        Case 16
            '按565格式运算
            ReDim dBits1(AllBytes / 2 - 1)
            GetBitmapBits .Bmp, AllBytes, dBits1(0)
            For j = 0 To h - 1
                m = j * LineBytes / 2
                For i = m To m + w - 1
                    l = dBits1(i) And &H7C0&
                    l = l * 32 + l + l / 64
                    CopyMemory dBits1(i), l, 2  '这句没办法,不用CopyMemory,会溢出,低效源于此
                Next
            Next
            SetBitmapBits .Bmp, AllBytes, dBits1(0)
            GrayBmp = 16
        End Select
        BitBlt dHdc, x, y, w, h, .hdc, 0, 0, vbSrcCopy
    End With
last:
    DelMyHdc tmpdc
End Function
Private Sub Form_Load()
    ScaleMode = 3
    AutoRedraw = True
    Picture = LoadPicture("f:/1.jpg")
    Command1.Caption = "测试"
End Sub

'测试用代码
Private Sub Form_Resize()
    PaintPicture Picture, 0, 0, ScaleWidth, ScaleHeight
End Sub

Private Sub Command1_Click()
    Dim t As Long, s As String, s1 As String, i As Long
    t = GetTickCount
    GrayBmp hdc, 0, 0, ScaleWidth, ScaleHeight
    Refresh
    MsgBox GetTickCount - t & s
End Sub

一种简单而快速的灰度图处理法相关推荐

  1. Python中使用PIL快速实现灰度图

    效果 原图 效果图 实现 新建文件夹grayImage,在此文件夹下新建gray.py from PIL import Image img=Image.open('1111.jpg') img=img ...

  2. 快速处理灰度图转彩色图方法

    之前看一篇博文,里面有转的过程,从Fast and Robust Pyramid-based Image Processing 2011论文里也有相关的处理过程,我就编写了下来. close all; ...

  3. 鱼骨图技能详解+13张精选模板,让你3分钟快速掌握鱼骨图分析法!

    鱼骨图看似很简单,其实有很多操作要点,它是一个非定量的工具,可以帮助我们找出引起问题的根本原因,使我们问自己:问题为什么会发生?促使人把目光聚焦于问题的原因,而非问题的症状. 接下来从鱼骨图的定义.鱼 ...

  4. 一种简单快速的方式实现 Android App 的夜间模式

    博主声明: 转载请在开头附加本文链接及作者信息,并标记为转载.本文由博主 威威喵 原创,请多支持与指教. 本文首发于此   博主:威威喵  |  博客主页:https://blog.csdn.net/ ...

  5. 图像处理中涉及的灰度图、彩色图以及深度图概念

    图像处理中涉及最多的概念就是图像的类型,为了很好的理解图像的概念以及处理图片,我们就需要对常见的图像具有一定的概念. 我们首先介绍一下生活中常见的图像格式: 1.bmp格式:这是一种不常见的图像格式, ...

  6. 灰度图、黑白图,彩色图理解

    黑白图,是指每个像素的颜色用二进制的1位来表示,颜色只有"1"和"0"这两个值 ,(Data值为0或者255)这也就是说,要么是黑,要么是白.例如: CvInv ...

  7. 一种简单快速有效的低照度图像增强方法

    一种简单快速有效的低照度图像增强方法 一.本文介绍的是一种比较实用并且去阴影效果很好的方法,选自2004年Tao的一篇论文,名称是<An Integrated Neighborhood Depe ...

  8. 一种简单快速有效的图像暗部增强/亮度均衡算法

    2020/10/27更新:之前为克服光晕效应尝试过引导滤波,惜哉其他地方犯了个小错误以致未达到目标,处理的结果虽然保边但却过于模糊.后期修正之后再次尝试便得到了预期的效果.现将引入了引导滤波去光晕的程 ...

  9. Tensorflow2学习笔记:简单灰度图分类

    Tensorflow2学习笔记:简单灰度图分类 相关介绍 实验环境 实验步骤 导入相关库 导入数据集 浏览数据 预处理数据 构建模型 设置层 编译模型 训练模型 向模型馈送数据 评估准确率 进行预测 ...

最新文章

  1. 【Git】git系统学习(一):常用指令
  2. php过滤敏感词实例代码
  3. 四十、Scrapyd的安装及使用
  4. 配置源码管理工具(2)
  5. jodd忽略ssl证书_关于java访问https资源时,忽略证书信任问题
  6. 老师也不是什么好东西
  7. round()和trunc()函数的应用
  8. ctfmon是什么启动项_win7系统启动项中没有ctfmon进程的解决方法
  9. Linux无法下载GCC
  10. pytorch(6)--深度置信网络
  11. 2500个常用汉字及繁体对应
  12. 补码1位乘法和补码2位乘法(Booth算法)(三栏式)详解学习
  13. 贴吧怎么引流_教您如何快速搭建自己的引流池-万能的小胡
  14. 关于连接同一wifi,手机可以上网,电脑无法上网问题
  15. Java常用工具类-发短信(集成河南华夏通信短信网关)
  16. 基于CAS的单点登录的下载和demo
  17. appollo-二次规划ST速度优化
  18. java Android OKHttp HTTPS 请求证书验证 PEM证书(1)
  19. 想要应聘银行工作,这些分析你都清楚吗?
  20. 手机卡顿别瞎清理,删掉这两个英文文件夹,就地释放5个G

热门文章

  1. python 微博图片爬虫 不用cookie
  2. 程设刷题 | 程序设计实践II-2017(部分)
  3. UE5 Lumen实现分析
  4. python下载,python依赖下载(用镜像),python依赖手动下载安装
  5. 百度网盘解析加速网页版[演示站可用]
  6. 超时锁定计算机,Win10电脑设置锁定屏幕超时怎么办
  7. hdu1425 sort
  8. ROS配置和使用“北通”无线手柄,主从机远程控制JP-Chassis底盘
  9. STM32的脉冲宽度调制(PWM)
  10. 万字起底澳本聪:一个正在崩溃的谎言