本文转自

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 遇到问题需要关闭……

VB6 GDI+ 入门教程[9] Bitmap魔法(2):数据读写的更多相关文章

  1. VB6 GDI+ 入门教程[8] Bitmap魔法(1):创建

    http://vistaswx.com/blog/article/category/tutorial/page/2 VB6 GDI+ 入门教程[8] Bitmap魔法(1):创建 2009 年 9 月 ...

  2. VB6 GDI+ 入门教程[7] Graphics 其他内容

    http://vistaswx.com/blog/article/category/tutorial/page/2 VB6 GDI+ 入门教程[7] Graphics 其他内容 2009 年 9 月 ...

  3. VB6 GDI+ 入门教程[1] GDI+介绍

    http://vistaswx.com/blog/article/category/tutorial/page/2 VB6 GDI+ 入门教程[1] GDI+介绍 2009 年 6 月 18 日 17 ...

  4. VB6 GDI+ 入门教程[2] GDI+初始化

    http://vistaswx.com/blog/article/category/tutorial/page/2 VB6 GDI+ 入门教程[2] GDI+初始化 2009 年 6 月 18 日 7 ...

  5. VB6 GDI+ 入门教程[3] 笔、刷子、矩形、椭圆绘制

    http://vistaswx.com/blog/article/category/tutorial/page/2 VB6 GDI+ 入门教程[3] 笔.刷子.矩形.椭圆绘制 2009 年 6 月 1 ...

  6. VB6 GDI+ 入门教程[4] 文字绘制

    http://vistaswx.com/blog/article/category/tutorial/page/2 VB6 GDI+ 入门教程[4] 文字绘制 2009 年 6 月 18 日 7条评论 ...

  7. VB6 GDI+ 入门教程[5] 基础绘图小结

    http://vistaswx.com/blog/article/category/tutorial/page/2 VB6 GDI+ 入门教程[5] 基础绘图小结 2009 年 6 月 18 日 4条 ...

  8. VB6 GDI+ 入门教程[6] 图片

    http://vistaswx.com/blog/article/category/tutorial/page/2 VB6 GDI+ 入门教程[6] 图片 2009 年 6 月 19 日 15条评论 ...

  9. testng入门教程16数据驱动(把数据写在xml)

    testng入门教程16数据驱动(把数据写在xml) testng入门教程16数据驱动(把数据写在xml)把数据写在xml文件里面,在xml文件右键选择runas---testng执行 下面是case ...

随机推荐

  1. Xcode关闭ARC

    开启了ARC则不能显示调用dealloc/retain/release等手动内存管理操作,所以很多情况下需要关闭. Xcode中有两种途径可以关闭ARC. 1.创建项目时将ARC选项的勾取消掉. 2. ...

  2. js获取鼠标位置

    1.PageX/PageX:鼠标在页面上的位置,从页面左上角开始,即是以页面为参考点,不随滑动条移动而变化2.clientX/clientY:鼠标在页面上可视区域的位置,从浏览器可视区域左上角开始,即 ...

  3. cert

  4. JAVA帮助文档全系列 JDK1.5 JDK1.6 JDK1.7 官方中英完整版下载

    JAVA帮助文档全系列 JDK1.5 JDK1.6 JDK1.7 官方中英完整版下载JDK(Java Development Kit,Java开发包,Java开发工具)是一个写Java的applet和 ...

  5. [SAP ABAP开发技术总结]逻辑数据库

    声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...

  6. git bash下的选择、复制、粘贴

      1. 打开git bash     2.点击左上角,选择属性,打钩     3.回到界面,选择一行文字,然后点击 “右键”,这样就复制到剪切板了.再点 “右键”,可以粘贴到命令窗口中了.    

  7. javascript权威指南笔记--javascript语言核心(一)

    1.javascript的数据类型分为两类:原始类型和对象类型. 原始类型包括字符串.数字.布尔值.null.undefined. 对象是属性的集合,每个对象都由“名/值”对构成.数组和函数是特殊的对 ...

  8. yii 常用路径

    yii::app()->homeurl //主页的网址 yii系统变量. //得到proteced目录的物理路径 Yii::app()->basePath; 调用YII框架中jquery: ...

  9. 2013年5月~2013年11月份(转接关于ns51服务平台项目)相关资料:

    <1> [平台首页] 界面截图:(网络游客所看到的界面首页) <2>[注册] 有需求则注册会员(略...) <3>[个人空间] 注册成功后进入个人空间(有深层次的需 ...

  10. SAP供应商和客户的创建

    进来遇到一个创建供应商的需求,由于在系统中关于供应商和客户的创建比较特殊,且没有相关函数进行创建, 找到一个类和方法来创建,类名:VMD_EI_API  方法名:MAINTAIN_DIRECT_INP ...