VB6 GDI+ 入门教程[8] Bitmap魔法(1):创建
其实Bitmap和Image是很像的(位图、图片),事实上他们也可以互相转化,不过他们各有不同特点。Bitmap有很多神奇的魔法,内容比较多,加上开学了,我每次只能说小部分了~~
知识点少,所以代码我会比较充实一点 :).. (其实我很幸运,我们班其他人这会儿不能开电脑)
1.CreateBitmapFromFile
函数是GdipCreateBitmapFromFile。如名,这个函数是从文件载入一个Bitmap。既然bmp和img可以串用,所以说一定程度上这个和GdipLoadImageFromFile差不多。
当然,这两个函数的参数也的确也是几乎一样的。
注意:下例中,载入文件是C:TestImg.png。
Option Explicit Dim bitmap As Long , bmW As Long , bmH As Long Dim graphics As Long Private 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)。 TerminateGDIPlus End Sub |
同样,不要忘记了,Form的AutoRedraw=True.
看到这里,可能有人要问了,以前我一直把Terminate之类的东西放到Form_Unload中,但是这次却放到了Load中,那么到底放在哪里呢?其实,具体放哪里要看实际情况。
首先,Terminate这些东西,是用于释放资源的。因此无论如何我们都要调用一下~。
然后在我们这个例子中,我们其实只绘制了一次,没有后续绘制的需求,因此可以完成任务以后就Terminate/Delete/Dispose掉。
而我前面的例子其实都可以这么做。不过你自己的程序不一定就是这样。
例如我们用GDI+边写一个钟。钟是一个不断重新绘制的过程,因此最后Unload时候释放为宜;而如果我们要用GDI+绘制一个不变的界面,那么一般可以绘制后就释放。不过一般来说因为界面不只一个,一个窗体的界面部分绘制完毕后可以释放相关资源,但是GDI+是不Shutdown的,因为我们还要给他其他窗体的绘制任务……
2.CreateBitmapFromStream
这个函数跟GdipLoadImageFromStream是差不多的。。
下例:载入图片从101号资源。
Option Explicit Private 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 Long Private 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 TerminateGDIPlus End Sub |
3.CreateBitmapFromHBITMAP
这里的HBITMAP就是我们的PictureBox/Form等等的Picture.Handle中获取。具体作用是什么呢?例如,GDI与GDI+的图片的转换。
一般来说,GdipCreateBitmapFromHBITMAP的第二个参数为0.
注意 本函数有个问题……转换得到的Bitmap数据是正确的,但是位图格式是错误的,所以例如只用这个代码创建一个32位hBitmap的Bitmap,绘制时候就会有问题~~
Option Explicit Dim bitmap As Long , bmW As Long , bmH As Long , graphics As Long Private 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 TerminateGDIPlus End Sub |
4.CreateBitmapFromHICON
VB6中用这个呢,主要是为了获取窗体等等的ICON。注意了,虽然看上去VB中Icon属性和Picture属性貌似是一个东西其实不然。因此读取Icon必须要这么读,不能用上面方法。
同上,也有同样的BUG。
Option Explicit Dim bitmap As Long , bmW As Long , bmH As Long , graphics As Long Private 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 TerminateGDIPlus End 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 Explicit Dim bitmap As Long , graphics As Long Private 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 TerminateGDIPlus End 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 Explicit Dim bitmap As Long , graphics As Long , gBmp As Long Private 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 TerminateGDIPlus End 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的ajax向ashx传值,中文乱码问题
从网上查找了很多资料: 有在配置文件里面加如下配置 <globalization responseEncoding="utf-8" requestEncoding=" ...
- mysql 导入导出的几个常用参数
导出命令: mysqldump -t --skip-extended-insert -utest -p testdb tableA > testdb_tableA.sql 参数说明: -t: 仅 ...
- CF 113C
求区间 [l,r] 满足 素数 = a^2+b^2 a b为任意整数 打素数表,如何证明 此时的素数满足 %4==1 #include<iostream> #include&l ...
- uTenux——软件底层驱动组织结构介绍
经过第一节对uTenux初步认识和第二节对uTenux\AT91SAM3S4C开发板的硬件结构的介绍,这一节我们将要学习的是uTenux\AT91SAM3S4C的软件底层驱动. 在悠龙公司的官网或者u ...
- BZOJ 2561 最小生成树(最大流)
题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2561 题意:给定一个边带正权的连通无向图G= (V,E),其中N=|V|,M=|E|,N ...
- Windows安装Python包下载工具pip遇到的问题
到Python的官网下载get-pip.py文件,然后按照说明进行安装. 在安装过程中,我遇到以下问题: cmd的codepage引起的编码错误,提示65001编码错误,通过chcp 936切换到默认 ...
- linux mv命令
mv命令是move的缩写,可以用来移动文件或者将文件改名(move (rename) files),是Linux系统下常用的命令,经常用来备份文件或者目录. 1.命令格式: mv [选项] 源文件或目 ...
- linux unzip命令
zip文件是一种常用的压缩文件格式,WinZip.WinRar等压缩软件都支持zip文件格式,就连java的jar包也是zip格式的,Firefox插件xpi文件也是zip格式的.Linux在zi ...
- Highlighting Text Item On Entry In Oracle Forms
Highlight a Text Item in Oracle Forms With Visual Attribute It is very necessary to highlight the cu ...
- 【转+自己研究】新姿势之Docker Remote API未授权访问漏洞分析和利用
0x00 概述 最近提交了一些关于 docker remote api 未授权访问导致代码泄露.获取服务器root权限的漏洞,造成的影响都比较严重,比如 新姿势之获取果壳全站代码和多台机器root权限 ...