VB6 GDI+ 入门教程[6] 图片
VB自己的绘图语句都需要用LoadPicture载入图片,同样,GDI+中也需要。
1.载入(初始化)图片资源
(1)来自文件:GdipLoadImageFromFile
我们先来看看这个最简单基本的载入图片来自文件:
| Dimimg AsLong, img_W AsLong, img_H AsLongGdipLoadImageFromFile 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修改]。
| DeclareSubCreateStreamOnHGlobal Lib"ole32.dll"(ByValhGlobal AsLong, ByValfDeleteOnRelease AsLong, ByRefppstm AsAny) | 
但是,函数第一个参数需要的是一个内存句柄而不是内存地址,这两个值有时一样有时不一样。当调用申请内存GlobalAlloc函数使用GMEM_FIXED参数时候它们相同,其它时候它们不同,一个数组的内存空间是否是GMEM_FIXED申请的取决于数组的声明位置等各种因素。所以我们可不能这么冒险假定hMem=pMem。那我们如何得到数据的内存句柄呢?新申请一块内存就得到句柄了,然后我们只需要复制数据即可。
示例代码 [2011/8/8 更新 感谢Марков]:
| '声明部分如下PrivateDeclareFunctionGlobalAlloc Lib"kernel32"(ByValwFlags AsLong, ByValdwBytes AsLong) AsLongPrivateDeclareFunctionGlobalUnlock Lib"kernel32"(ByValhMem AsLong) AsLongPrivateDeclareFunctionGlobalLock Lib"kernel32"(ByValhMem AsLong) AsLongPrivateDeclareFunctionGlobalFree Lib"kernel32"(ByValhMem AsLong) AsLongPrivateDeclareSubRtlMoveMemory Lib"kernel32"(ByRefDestination AsAny, ByRefSource AsAny, ByValLength AsLong)ConstGMEM_MOVEABLE AsLong= &H2'实现部分如下Dimimg AsLongDimResData() AsByte, IStream AsObjectResData = LoadResData(101, "CUSTOM")  '获取数据'接下来需要一个内存句柄而不是内存地址DimhMemObj AsLong, pMem AsLonghMemObj = GlobalAlloc(GMEM_MOVEABLE, UBound(ResData) + 1) '申请新内存获得句柄pMem = GlobalLock(hMemObj)IfpMem = 0 Then'分配内存失败    Msgbox "Global alloc failed!"    ExitSubEndIfRtlMoveMemory ByValpMem, ResData(0), UBound(ResData)+1  '复制源数据到新内存GlobalUnlock hMemObjCreateStreamOnHGlobal ByValhMemObj, False, IStream  '根据新内存句柄创建IStreamGdipLoadImageFromStream IStream, img  '建立ImageSetIStream = 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的不同势必就会造成绘制出来的图像有“缩放”,一般呈现为比正常大小大。
分辨率如何调整?以后再说。
| Dimimg AsLongGdipLoadImageFromFile StrPtr("C:TestImage.png"), img'此处请初始化GDI+以及graphicsGdipDrawImage graphics, img, 0, 0 | 
拓展阅读:
(2)GdipDrawImageRect(I) 推荐
这是我们常用的画法,一般Gdi+画图就用这个函数。我们可以对图片的大小进行平滑的拉伸缩放。
| Dimimg AsLongGdipLoadImageFromFile StrPtr("C:TestImage.png"), img'此处请初始化GDI+以及graphicsGdipDrawImageRect graphics, img, 0, 0, 100, 200  '拉伸到100*200 | 
(3)GdipDrawImageRectRect(I)
还有个有点常用的函数就是这个了。通过它我们可以画一个图的一个部分,并且同样可以改变大小(好处:我们可以把所有的图片资源综合到一个图片中),另外它支持一个叫做ImageAttribs的东西,这是图片的滤镜,我们可以改变图片透明度和各种颜色参数(如二值化,灰度化等)。ImageAttrib(utes)会在之后的教程中有所涉及。
代码如下:
| Dimimg AsLongGdipLoadImageFromFile StrPtr("C:TestImage.png"), img'此处请初始化GDI+以及graphicsGdipDrawImageRectRectI graphics, img, 20, 20, 10, 10, 0, 0, 100, 200, UnitPixel | 
注意咯
第三~第六个参数是原来图片中要截取的部分;第七~第十呢则是画到哪里以及画出来多大的设置
第三~第六个参数是为绘制位置和绘制尺寸;第七~第十则是截取位置和截取尺寸。
(4)贴图刷
贴图刷子主要用来绘制平铺的内容。贴图刷子跟其它刷子一样,我们需要创建刷子,另外对于这个刷子我们需要先初始化图片:)
| Dimimg AsLong, textureBrush AsLongGdipLoadImageFromFile 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 别名 #删除别名 设置别名永久生效 ... 
