zoukankan      html  css  js  c++  java
  • VB6 GDI+ 入门教程[9] Bitmap魔法(2):数据读写

    本文转自

    http://vistaswx.com/blog/article/category/tutorial/page/2

    导读:

    本节介绍了一下Gdi+中进行数据直接读写的方法

    1.GdipBitmapGetPixel

    2.GdipBitmapSetPixel

    3.GdipBitmapLockBits & GdipBitmapUnlockBits

    1.GdipBitmapGetPixel

    我们似乎一直在纳闷,GDI+中怎么拿到图片的数据呢?(我们之前一直都是绘制)。这一节,你就会拿数据了。

    拿数据,无非就是取得一个点的ARGB值,而且往往我们要获取所有的点的值。

    纵观GDI+的模块中的API,我们寻觅到了这个API:GdipBitmapGetPixel。如名,它是用于得到像素(点)的,事实上的确是。这个函数传出的变量包含了指定点的颜色值(AARRGGBB[16])。

    此函数用起来及其方便,像VB中的Point(X,Y)函数一样。

    例如:

     
    Dim color As Long
    GdipBitmapGetPixel bitmap, 0, 0, color
    Debug.Print Hex(color)

    这样我们就拿到了bitmap中点(0,0)的颜色。

    再说回来,怎么拿到所有颜色呢?无非如此罢了:

     
    Dim color() As Long
    Dim i As Long, j As Long
     
    ReDim color(BitmapWidth - 1, BitmapHeight - 1)
    For i = 0 To BitmapWidth - 1
        For j = 0 To BitmapHeight - 1
            GdipBitmapGetPixel bitmap, i, j, color(i, j)
        Next
    Next

    注意:

    其中,bitmap就是拿颜色的位图;

    BitmapWidth,BitmapHeight分别是用GdipGetImageWidth,GdipGetImageHeight得到的Bitmap的尺寸。

    2.GdipBitmapSetPixel

    类比着,我们设置Bitmap中的某一个点也是很容易的,API是GdipBitmapSetPixel。代码类似于GdipBitmapGetPixel。

    例如:

     
    GdipBitmapSetPixel bitmap, 0, 0, &HFF000000

    这句把bitmap位图中点(0,0)设置为黑色。

    3.GdipBitmapLockBits & GdipBitmapUnlockBits

    看看名字,LockBits,锁定……锁定是什么呢……这个先不要管他。不知你有没有发现前面2个得到颜色/设置颜色的GDI+函数巨慢无比?(不过貌似比VB中的Point快)。为什么呢?其实我也不知道(怎么可能呢?)

    在我这台破烂电脑上,一幅800*800左右的图片,Get所有的Pixel花费了约1s……,那么1024*768怎么办?更大的怎么办?有没有更快的?

    答案是,有。用什么?就是这个——GdipBitmapLockBits。

    GdipBitmapLockBits,GdipBitmapUnlockBits是一对函数,他们可以将Bitmap上数据映射到内存和将内存中位图数据写回Bitmap,这个函数是一整块的,非常适合处理一大片的点——例如整个图像。

    演示代码:

     
    Option Explicit
     
    Dim bitmap As Long, rc As RECTL
    Dim data() As Long
     
    Dim graphics As Long
     
    Private Sub Form_Load()
        InitGDIPlus
     
        GdipCreateBitmapFromFile StrPtr("c:TestImg.png"), bitmap
        GdipGetImageWidth bitmap, rc.Right
        GdipGetImageHeight bitmap, rc.Bottom
     
        ReDim data(rc.Right - 1, rc.Bottom - 1)
     
        Dim BmpData As BitmapData
        With BmpData
            .Width = rc.Right
            .Height = rc.Bottom
     
            .PixelFormat = GpPixelFormat.PixelFormat32bppARGB
            .scan0 = VarPtr(data(0, 0))
            .stride = 4 * CLng(rc.Right)
        End With
     
        GdipBitmapLockBits bitmap, rc, ImageLockModeUserInputBuf Or ImageLockModeWrite Or ImageLockModeRead, GpPixelFormat.PixelFormat32bppARGB, BmpData
     
        Dim i As Long, j As Long, s As String
        For i = 0 To rc.Bottom - 1
            For j = 0 To rc.Right - 1
                data(j, i) = data(j, i) + data(j, i)
            Next
        Next
     
        GdipBitmapUnlockBits bitmap, BmpData
     
        GdipCreateFromHDC Me.hDC, graphics
        GdipDrawImageRectI graphics, bitmap, 0, 0, rc.Right, rc.Bottom
        GdipDeleteGraphics graphics
     
        GdipDisposeImage bitmap
    End Sub
     
    Private Sub Form_Unload(Cancel As Integer)
        TerminateGDIPlus
    End Sub

    我们先注意BmpData结构体,它实际上就是数据的设置。

    scan0内存地址我们写的是VarPtr(data(0,0))。

    stride = 4 * CLng(rc.Right):扫描宽度,这一个实际上就是二维数组每隔多少字节增加第一维,其中4是Long的存储长度,4个字节。

    我们可以把数组的存储想象为一个矩形,gdi+放数据就是从左到右放,放到了边界则从下一行的第一个再从左向右放……

    GdipBitmapLockBits

    我们首先用它来得到位图数据,方式是ImageLockModeWrite Or ImageLockModeRead(ImageLockModeUserInputBuf必须写)。即我们传给他的data(),它将把位图数据写入;而在GdipBitmapUnlockBits时候将data()数据写入位图。注意:如果只是Write模式,那么你将得不到原始数据。

    data(j, i) = data(j, i) + data(j, i) 这句是一句简单的颜色处理变换,让我们能看到处理效果

    GdipBitmapUnlockBits:完成最后的写入&释放工作。后面几句是绘制这个新图片用。

    注意:这里LockBits得到的数据data()是data(y,x),即顺序是(列,行)。Lockbits时候也要按照传入长度和宽度,不然VB会抛给你“Visual Basic 遇到问题需要关闭……

  • 相关阅读:
    PEM_密钥对生成与读取方法
    RandomStringUtils RandomUtils
    Java高级个人笔记(RandomStringUtils工具类)
    如何让eclipse输出结果的console栏自动换行?
    日志框架logj的使用
    IDEA中Git的更新、提交、还原方法
    AWS核心服务概览
    技术资料的几种读法
    李笑来老师在《把时间当作朋友》曾说过:“所有学习上的成功,都只靠两件事:策略和坚持,而坚持本身就应该是最重要的策略之一
    ubuntu如何修改terminal终端的主机名(修改/etc/hostname文件)
  • 原文地址:https://www.cnblogs.com/liuzhaoyzz/p/4035044.html
Copyright © 2011-2022 走看看