VB6 GDI+ 入门教程[6] 图片
VB自己的绘图语句都需要用LoadPicture载入图片,同样,GDI+中也需要。
1.载入(初始化)图片资源
(1)来自文件:GdipLoadImageFromFile
我们先来看看这个最简单基本的载入图片来自文件:
Dim img As Long, img_W As Long, img_H As LongGdipLoadImageFromFile StrPtr("C:TestImage.png"), img'如果你希望得到长宽信息,可以使用下面的语句:GdipGetImageWidth img, img_WGdipGetImageHeight img, img_HMsgbox "长为:" & CStr(img_W) & "px, 宽为:" & CStr(img_H) & "px."'GdipDisposeImage img |
载入图像之后别忘记释放Image,否则会造成MemoryLeak内存泄漏(另外如果没有Dispose掉的话这个文件是被占用的)。
(2)来自资源文件:GdipLoadImageFromStream (2010/2/9修改)
这个函数主要是用来从资源文件(RES)载入图像的,怎么载入呢?我们来看函数,函数是从Stream载入,但是我们VB6没有集成Stream对象,从RES读取出来(LoadResData)也只是返回Byte()。不过很好,OLE提供了一个函数能够将Byte()变为一个IStream对象——我们需要这个API [注:声明已于2011/2/9修改]。
Declare Sub CreateStreamOnHGlobal Lib "ole32.dll" (ByVal hGlobal As Long, ByVal fDeleteOnRelease As Long, ByRef ppstm As Any) |
但是,函数第一个参数需要的是一个内存句柄而不是内存地址,这两个值有时一样有时不一样。当调用申请内存GlobalAlloc函数使用GMEM_FIXED参数时候它们相同,其它时候它们不同,一个数组的内存空间是否是GMEM_FIXED申请的取决于数组的声明位置等各种因素。所以我们可不能这么冒险假定hMem=pMem。那我们如何得到数据的内存句柄呢?新申请一块内存就得到句柄了,然后我们只需要复制数据即可。
示例代码 [2011/8/8 更新 感谢Марков]:
'声明部分如下Private Declare Function GlobalAlloc Lib "kernel32" (ByVal wFlags As Long, ByVal dwBytes As Long) As LongPrivate Declare Function GlobalUnlock Lib "kernel32" (ByVal hMem As Long) As LongPrivate Declare Function GlobalLock Lib "kernel32" (ByVal hMem As Long) As LongPrivate Declare Function GlobalFree Lib "kernel32" (ByVal hMem As Long) As LongPrivate Declare Sub RtlMoveMemory Lib "kernel32" (ByRef Destination As Any, ByRef Source As Any, ByVal Length As Long)Const GMEM_MOVEABLE As Long = &H2'实现部分如下Dim img As LongDim ResData() As Byte, IStream As ObjectResData = LoadResData(101, "CUSTOM") '获取数据'接下来需要一个内存句柄而不是内存地址Dim hMemObj As Long, pMem As LonghMemObj = GlobalAlloc(GMEM_MOVEABLE, UBound(ResData) + 1) '申请新内存获得句柄pMem = GlobalLock(hMemObj)If pMem = 0 Then '分配内存失败 Msgbox "Global alloc failed!" Exit SubEnd IfRtlMoveMemory ByVal pMem, ResData(0), UBound(ResData)+1 '复制源数据到新内存GlobalUnlock hMemObjCreateStreamOnHGlobal ByVal hMemObj, False, IStream '根据新内存句柄创建IStreamGdipLoadImageFromStream IStream, img '建立ImageSet IStream = NothingGlobalFree hMemObj '释放新内存'GdipDisposeImage img '图片不要忘记释放了 |
2.绘制图片
(1)GdipDrawImage(I)
这是Gdi+绘图的一种基础画法,不需要进行长宽设置,不过我们平时不怎么用它。它按照图片的物理大小绘制,完全无视所有Graphics的Scale等缩放参数。这个函数支持32位透明通道绘制。(技巧:有I的一般 坐标、长宽都是Long型 没有I的一般都是Single型)
什么是物理大小?这个就要跟图像的分辨率(dpi)有关了。打开你的Photoshop或者是Fireworks或者是AI或者其他专业绘图软件,新建一个文档,你就会发现有分辨率选项,一般你看到的是72像素/英寸。但是,请注意,一般屏幕的分辨率是96像素/英寸。
96这个值可以在系统的显示设置中看到。在Windows7中的查看步骤是:桌面右键->屏幕分辨率->放大或缩小文本和其他项目->(左侧)设置自定义文本大小(DPI),在弹出对话框中有显示“每英寸 X 像素”。
图片一般的分辨率与屏幕的分辨率不一致,这会有什么结果?一般不会有问题,因为我们一般图像的绘制以px为单位,无论分辨率多高(结果是物理尺寸变小),图像都是包含了同样数量的像素点。可是现在这个函数是按照物理大小绘制的,这样Dpi的不同势必就会造成绘制出来的图像有“缩放”,一般呈现为比正常大小大。
分辨率如何调整?以后再说。
Dim img As LongGdipLoadImageFromFile StrPtr("C:TestImage.png"), img'此处请初始化GDI+以及graphicsGdipDrawImage graphics, img, 0, 0 |
拓展阅读:
(2)GdipDrawImageRect(I) 推荐
这是我们常用的画法,一般Gdi+画图就用这个函数。我们可以对图片的大小进行平滑的拉伸缩放。
Dim img As LongGdipLoadImageFromFile StrPtr("C:TestImage.png"), img'此处请初始化GDI+以及graphicsGdipDrawImageRect graphics, img, 0, 0, 100, 200 '拉伸到100*200 |
(3)GdipDrawImageRectRect(I)
还有个有点常用的函数就是这个了。通过它我们可以画一个图的一个部分,并且同样可以改变大小(好处:我们可以把所有的图片资源综合到一个图片中),另外它支持一个叫做ImageAttribs的东西,这是图片的滤镜,我们可以改变图片透明度和各种颜色参数(如二值化,灰度化等)。ImageAttrib(utes)会在之后的教程中有所涉及。
代码如下:
Dim img As LongGdipLoadImageFromFile StrPtr("C:TestImage.png"), img'此处请初始化GDI+以及graphicsGdipDrawImageRectRectI graphics, img, 20, 20, 10, 10, 0, 0, 100, 200, UnitPixel |
注意咯
第三~第六个参数是原来图片中要截取的部分;第七~第十呢则是画到哪里以及画出来多大的设置
第三~第六个参数是为绘制位置和绘制尺寸;第七~第十则是截取位置和截取尺寸。
(4)贴图刷
贴图刷子主要用来绘制平铺的内容。贴图刷子跟其它刷子一样,我们需要创建刷子,另外对于这个刷子我们需要先初始化图片:)
Dim img As Long, textureBrush As LongGdipLoadImageFromFile StrPtr("C:TestImage.png"), img'此处请初始化GDI+以及graphicsGdipCreateTexture img, WrapModeTileFlipX, textureBrushGdipFillRectangle graphics, textureBrush, 0, 0, 100, 100 |
贴图刷子跟其它刷子有什么区别呢?普通的图片绘制(如DrawImageRectI)支持的是拉伸,贴图刷则是平铺。另外贴图刷还要注意定位问题。因为贴图刷纹理起始点是Graphics的0,0,而不是绘制内容的左上角坐标。
贴个图,直观明了。

那么贴图刷子中如何调整图片起始位置呢?我们可以平移图片——GdipTranslateTextureTransform。参数很简单 是平移量。(注意:这是个相对平移,也就是这个平移是参照之前量的,而不是原图片;因此建议更改平移量要先Reset下:GdipResetTextureTransform)
VB6 GDI+ 入门教程[6] 图片的更多相关文章
- VB6 GDI+ 入门教程[7] Graphics 其他内容
http://vistaswx.com/blog/article/category/tutorial/page/2 VB6 GDI+ 入门教程[7] Graphics 其他内容 2009 年 9 月 ...
- VB6 GDI+ 入门教程[8] Bitmap魔法(1):创建
http://vistaswx.com/blog/article/category/tutorial/page/2 VB6 GDI+ 入门教程[8] Bitmap魔法(1):创建 2009 年 9 月 ...
- VB6 GDI+ 入门教程[9] Bitmap魔法(2):数据读写
本文转自 http://vistaswx.com/blog/article/category/tutorial/page/2 VB6 GDI+ 入门教程[9] Bitmap魔法(2):数据读写 200 ...
- 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条 ...
- GDI+_入门教程【一】
GDI For VisualBasic6.0 [一]文件下载:GDI+ For VB6[一] 简单绘图实例演示百度网盘 1 '以下为作者[vIsiaswx]的教程 '(该教程发布的原地址已无法访问,此 ...
随机推荐
- datagrid 重写属性
$.fn.panel.defaults.loadMsg = '数据加载中请稍后--'; //设置默认的分页参数 if ($.fn.datagrid) { $.fn.datagrid.defaults. ...
- 编译android源码官方教程(2)建立编译环境「linux & mac osx」
https://source.android.com/source/initializing.html Establishing a Build Environment IN THIS DOCUMEN ...
- CentOS6.6系统源代码安装mysql5.5.28教程(附源码包下载地址)+sysbench的安装
mysql从5.5版本开始,不再使用./configure编译,而是使用cmake编译器,具体的cmake编译参数可以参考mysql官网文档(※ 非常重要) http://dev.mysql.com/ ...
- SqlSever基础 union 联合查询,厉害的并集 重复项只显示一个 两个查询结果并在一起后排序
镇场诗:---大梦谁觉,水月中建博客.百千磨难,才知世事无常.---今持佛语,技术无量愿学.愿尽所学,铸一良心博客.------------------------------------------ ...
- WINCE+6410 拨号上网
我们现在的模块用的是USB接口,然后模拟成一个COM6进行通信,在CE的: 控制面板->网络连接 里要新建一个连接,选择"拨号连接"然后设置好区域代码,还有附加解调器命令+C ...
- SQL Server常用函数
---------数学函数 ) --开平方 ) --区绝对值 ) --保留小数点后1位 四舍五入保留 select COUNT(*)/5.0 from Car select CEILING(COUNT ...
- CSS3弹力球
如下代码实现方块在限定区域内不停弹跳. <!DOCTYPE html> <html> <head> <style> div { width:100px; ...
- CentOS 6.5 64位下安装MySQL 5.7.11
昨天花了一下午在CentOS6.5 上安装了MySQL,版本为5.7.11,下面介绍一下我安装时候出现的问题 以及解决方法,供大家参考. 1/清除残留 rpm -qa | grep mysql // ...
- EntityFramework 开始小试
1 Install-Package EntityFramework 2 创建实体类 public class Blog { public int BlogId { get; set; } public ...
- 别名alias
alias #查看已设置的别名 alias 别名='原命令' #暂时设定别名(重启失效):alias ls='ls --color=never' unalias 别名 #删除别名 设置别名永久生效 ...