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(协议) ...
随机推荐
- sql 邮件发送测试情况
sql 邮件发送测试情况 select * from msdb.dbo.sysmail_allitems select * from msdb.dbo.sysmail_event_log
- HTTP请求&响应、POST与GET
HTTP请求&响应 既然说从入门级开始就说说Http请求包的结构.一次请求就是向目标服务器发送一串文本.什么样的文本?有下面结构的文本.HTTP请求包结构 请求包例子: POST /meme. ...
- CodeForces 670D2 Magic Powder 二分
D2. Magic Powder - 2 The term of this problem is the same as the previous one, the only exception — ...
- 不同分辨率的LCM进行兼容
1.读取不同LCM ID的时序不同,如何处理? 2.开机后android会自动resize图片资源的大小,但开机logo无法自行resize,如何操作?保证识别到不同分辨率的LCM后开机logo可以正 ...
- 分别向Set集合以及List集合中添加"A"、"a"、"c"、"C"、"a",观察重复值"a"能否添加成功
package lianxi; import java.util.*; public class JhSet { public static void main(String[] args) { Se ...
- CodeForces 131A cAPS lOCK
cAPS lOCK Time Limit:500MS Memory Limit:262144KB 64bit IO Format:%I64d & %I64u Submit St ...
- Devexpress TreeList选择父级联动
Treelist当显示复选框后,父级和子级的复选框没有关联,使用过程中很不便,如图所示 自己给treelist添加父子级联动 /// <summary> /// 初始化TreeList,父 ...
- JAVA查找--[二分查找]
package com.array; public class BinaryFind { /* * 项目名称:二分查找 ; * 项目要求:用JAVA对数组进行查找,并运用快速查找算法; * 作者:Se ...
- C# WPF – 利用“Attached Property” 把 RoutedEvent 接上 ICommand
本文说明怎样把 DoubleClick 连接至 ICommand.方法很多.推荐使用 Attach Property 方式,因为它能把任何 RoutedEvent 接上任何 ICommand. 之前写 ...
- herf窗口点击跳转
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...