VB6 GDI+ 入门教程[8] Bitmap魔法(1):创建
其实Bitmap和Image是很像的(位图、图片),事实上他们也可以互相转化,不过他们各有不同特点。Bitmap有很多神奇的魔法,内容比较多,加上开学了,我每次只能说小部分了~~
知识点少,所以代码我会比较充实一点 :).. (其实我很幸运,我们班其他人这会儿不能开电脑)
1.CreateBitmapFromFile
函数是GdipCreateBitmapFromFile。如名,这个函数是从文件载入一个Bitmap。既然bmp和img可以串用,所以说一定程度上这个和GdipLoadImageFromFile差不多。
当然,这两个函数的参数也的确也是几乎一样的。
注意:下例中,载入文件是C:TestImg.png。
Option ExplicitDim bitmap As Long, bmW As Long, bmH As LongDim graphics As LongPrivate Sub Form_Load() InitGDIPlus '从文件载入Bitmap GdipCreateBitmapFromFile StrPtr("C:TestImg.png"), bitmap GdipGetImageWidth bitmap, bmW GdipGetImageHeight bitmap, bmH '以下是用于绘制Bitmap的 GdipCreateFromHDC Me.hDC, graphics GdipDrawImageRectI graphics, bitmap, 0, 0, bmW, bmH '扫地工作 GdipDeleteGraphics graphics GdipDisposeImage bitmap 'Bitmap没有释放函数,直接拿Image的来用。这是允许的,因为这样做返回0(OK)。 TerminateGDIPlusEnd Sub |
同样,不要忘记了,Form的AutoRedraw=True.
看到这里,可能有人要问了,以前我一直把Terminate之类的东西放到Form_Unload中,但是这次却放到了Load中,那么到底放在哪里呢?其实,具体放哪里要看实际情况。
首先,Terminate这些东西,是用于释放资源的。因此无论如何我们都要调用一下~。
然后在我们这个例子中,我们其实只绘制了一次,没有后续绘制的需求,因此可以完成任务以后就Terminate/Delete/Dispose掉。
而我前面的例子其实都可以这么做。不过你自己的程序不一定就是这样。
例如我们用GDI+边写一个钟。钟是一个不断重新绘制的过程,因此最后Unload时候释放为宜;而如果我们要用GDI+绘制一个不变的界面,那么一般可以绘制后就释放。不过一般来说因为界面不只一个,一个窗体的界面部分绘制完毕后可以释放相关资源,但是GDI+是不Shutdown的,因为我们还要给他其他窗体的绘制任务……
2.CreateBitmapFromStream
这个函数跟GdipLoadImageFromStream是差不多的。。
下例:载入图片从101号资源。
Option ExplicitPrivate Declare Sub CreateStreamOnHGlobal Lib "ole32.dll" (ByRef hGlobal As Any, ByVal fDeleteOnRelease As Long, ByRef ppstm As Any)Dim img As Long, imgW As Long, imgH As Long, graphics As LongPrivate Sub Form_Load() InitGDIPlus Dim ResData() As Byte, IStream As Object ResData = LoadResData(101, "CUSTOM") CreateStreamOnHGlobal ResData(0), False, IStream GdipCreateBitmapFromStream IStream, bitmap GdipGetImageWidth img, imgW GdipGetImageHeight img, imgH Set IStream = Nothing '不要忘记把他释放了 GdipCreateFromHDC Me.hDC, graphics GdipDrawImageRectI graphics, img, 0, 0, imgW, imgH GdipDeleteGraphics graphics GdipDisposeImage img TerminateGDIPlusEnd Sub |
3.CreateBitmapFromHBITMAP
这里的HBITMAP就是我们的PictureBox/Form等等的Picture.Handle中获取。具体作用是什么呢?例如,GDI与GDI+的图片的转换。
一般来说,GdipCreateBitmapFromHBITMAP的第二个参数为0.
注意 本函数有个问题……转换得到的Bitmap数据是正确的,但是位图格式是错误的,所以例如只用这个代码创建一个32位hBitmap的Bitmap,绘制时候就会有问题~~
Option ExplicitDim bitmap As Long, bmW As Long, bmH As Long, graphics As LongPrivate Sub Form_Load() InitGDIPlus GdipCreateBitmapFromHBITMAP Picture1.Picture.Handle, 0, bitmap GdipGetImageWidth bitmap, bmW GdipGetImageHeight bitmap, bmH GdipCreateFromHDC Me.hDC, graphics GdipDrawImageRectI graphics, bitmap, 0, 0, bmW, bmH GdipDeleteGraphics graphics GdipDisposeImage bitmap TerminateGDIPlusEnd Sub |
4.CreateBitmapFromHICON
VB6中用这个呢,主要是为了获取窗体等等的ICON。注意了,虽然看上去VB中Icon属性和Picture属性貌似是一个东西其实不然。因此读取Icon必须要这么读,不能用上面方法。
同上,也有同样的BUG。
Option ExplicitDim bitmap As Long, bmW As Long, bmH As Long, graphics As LongPrivate Sub Form_Load() InitGDIPlus GdipCreateBitmapFromHICON Me.Icon.Handle, bitmap GdipGetImageWidth bitmap, bmW GdipGetImageHeight bitmap, bmH GdipCreateFromHDC Me.hDC, graphics GdipDrawImageRectI graphics, bitmap, 0, 0, bmW, bmH GdipDeleteGraphics graphics GdipDisposeImage bitmap TerminateGDIPlusEnd Sub |
5.CreateBitmapFromGraphics
这个是从一个现存的Graphics创建位图。这个和GdipGetImageGraphicsContext不一样,GdipGetImageGraphicsContext创建出来的Graphics修改后会影响原来的Image(绑定),而这个GdipCreateBitmapFromGraphics就不会,完全是创建一个副本。
Declare Function GdipCreateBitmapFromGraphics Lib "gdiplus" (ByVal Width As Long, ByVal Height As Long, ByVal graphics As Long, bitmap As Long) As GpStatus |
参数说明:
Width,Height:新创建的位图的长、宽
graphics:从哪个Graphic创建Bitmap
bitmap:创建出来的Bitmap指针放到哪里
Option ExplicitDim bitmap As Long, graphics As LongPrivate Sub Form_Load() InitGDIPlus GdipCreateFromHDC Me.hDC, graphics GdipGraphicsClear graphics, &HFFFF0000 '为了显示点内容 GdipCreateBitmapFromGraphics 100, 100, graphics, bitmap '创建一个现存的副本 GdipDrawImageRectI graphics, bitmap, 0, 0, 100, 100 '绘制这个副本 GdipDeleteGraphics graphics GdipDisposeImage bitmap TerminateGDIPlusEnd Sub |
6.CreateBitmapFromScan0 [Important]
说了那么多,我们可以发现,貌似所有的CreateBitmap都要有一个现存的蓝本……那么如何凭空创建一个Bitmap呢(其实是从内存)?就是这个函数了!
Declare Function GdipCreateBitmapFromScan0 Lib "gdiplus" (ByVal Width As Long, ByVal Height As Long, ByVal stride As Long, ByVal PixelFormat As Long, scan0 As Any, bitmap As Long) As GpStatus |
参数说明:
Width,Height:新位图的长、宽
stride:这个参数是在从一个指定数据创建Graphics时候设置数据扫描行间隔的。如果不是从已知内存创建创建的话则是0
PixelFormat:设定这个Bitmap的色深,我比较喜欢GpPixelFormat.PixelFormat32bppARGB。
scan0:这个参数是在从一个指定数据创建Graphics时候设置数据地址的,一定要用ByVal方式!如果是0就是从内存新创建一个而不是已知内容中数据。注意 得用ByVal 0
bitmap:传回的位图指针
Option ExplicitDim bitmap As Long, graphics As Long, gBmp As LongPrivate Sub Form_Load() InitGDIPlus GdipCreateBitmapFromScan0 100, 100, 0, GpPixelFormat.PixelFormat32bppARGB, ByVal 0, bitmap GdipGetImageGraphicsContext bitmap, gBmp GdipGraphicsClear gBmp, &HFFFF0000 GdipCreateFromHDC Me.hDC, graphics GdipDrawImageRectI graphics, bitmap, 0, 0, 100, 100 GdipDeleteGraphics gBmp GdipDeleteGraphics graphics GdipDisposeImage bitmap TerminateGDIPlusEnd Sub |
现在基本上所有常用的创建Bitmap方式都结束了。好累啊。。。
VB6 GDI+ 入门教程[8] Bitmap魔法(1):创建的更多相关文章
- VB6 GDI+ 入门教程[9] Bitmap魔法(2):数据读写
本文转自 http://vistaswx.com/blog/article/category/tutorial/page/2 VB6 GDI+ 入门教程[9] Bitmap魔法(2):数据读写 200 ...
- VB6 GDI+ 入门教程[7] Graphics 其他内容
http://vistaswx.com/blog/article/category/tutorial/page/2 VB6 GDI+ 入门教程[7] Graphics 其他内容 2009 年 9 月 ...
- VB6 GDI+ 入门教程[1] GDI+介绍
http://vistaswx.com/blog/article/category/tutorial/page/2 VB6 GDI+ 入门教程[1] GDI+介绍 2009 年 6 月 18 日 17 ...
- VB6 GDI+ 入门教程[2] GDI+初始化
http://vistaswx.com/blog/article/category/tutorial/page/2 VB6 GDI+ 入门教程[2] GDI+初始化 2009 年 6 月 18 日 7 ...
- VB6 GDI+ 入门教程[3] 笔、刷子、矩形、椭圆绘制
http://vistaswx.com/blog/article/category/tutorial/page/2 VB6 GDI+ 入门教程[3] 笔.刷子.矩形.椭圆绘制 2009 年 6 月 1 ...
- VB6 GDI+ 入门教程[4] 文字绘制
http://vistaswx.com/blog/article/category/tutorial/page/2 VB6 GDI+ 入门教程[4] 文字绘制 2009 年 6 月 18 日 7条评论 ...
- VB6 GDI+ 入门教程[5] 基础绘图小结
http://vistaswx.com/blog/article/category/tutorial/page/2 VB6 GDI+ 入门教程[5] 基础绘图小结 2009 年 6 月 18 日 4条 ...
- VB6 GDI+ 入门教程[6] 图片
http://vistaswx.com/blog/article/category/tutorial/page/2 VB6 GDI+ 入门教程[6] 图片 2009 年 6 月 19 日 15条评论 ...
- WCF入门教程(二)如何创建WCF服务
WCF入门教程(二)从零做起-创建WCF服务 通过最基本的操作看到最简单的WCF如何实现的.这是VS的SDK默认创建的样本 1.创建WCF服务库 2.看其生成结构 1)IService1.cs(协议) ...
随机推荐
- (转)jquery对表单元素的取值和赋值
/*获得text的值*/ var textval =$("#text_id").attr("value"); //或者 var textval =$(" ...
- flume ng之TailSource
在它里面自带了一个TailSource以及TailDirSource,这个Source是负责读取一个文件,并一行一行的发送到sink端,而在flume-ng 1.4.0里面没有自带TailSource ...
- libevent系列之一——libevent介绍
摘自:http://libevent.org/ libevent概述:一套事件通知库. libevent提供一套机制完成以下功能:当指定的事件发生在file descriptor时或者超时后执行一个回 ...
- java中局部变量和成员变量主要是他们作用域的区别
成员变量个是类内部:局部变量是定义其的方法体内部(或者方法体内部的某一程序块内——大括号,主要看定义的位置).另外,成员变量可以不显式初始化,它们可以由系统设定默认值:局部变量没有默认值,所以必须设定 ...
- 双击Button按钮后执行的函数
在MFC中,当在用户界面拖入一个button后,双击会进入cpp文件,实现一个按钮点击的方法如: void CtestcontorlDlg::OnBnClickedButton() { : } 理解: ...
- 谢启鸿谈"如何学好高等代数"
高等代数和数学分析.空间解析几何一起,并称为数学系本科生的三大基础课.所谓基础课,顾名思义,就是本科四年学习的所有数学课程,都是以上述三门课作为基础的.因此对一年级新生而言,学好这三门基础课,其重要性 ...
- iOS中3种正则表达式的使用与比较
正则表达式在用户注册和登录中应用很广,通过正则表达式可以判断用户输入的数据正确与否. 在iOS4.0以前开发者一般是通过谓词(NSPredicate)和加入正则表达式的第三方库(如:RegexKitL ...
- 01scala环境搭建和基础
1.环境搭建 1.下载安装jdk1.7以上版本,并进行环境变量的配置 2.下载scala-2.10.4.msi,安装后进行环境变量的配置 3.下载scala-SDK-4.1.1-vfinal-2.11 ...
- 【leetcode❤python】 112. Path Sum
#-*- coding: UTF-8 -*-# Definition for a binary tree node.# class TreeNode(object):# def __init_ ...
- 【leetcode❤python】 374. Guess Number Higher or Lower
#-*- coding: UTF-8 -*-# The guess API is already defined for you.# @param num, your guess# @return - ...