如果想自己设计一个个性独特的ico图片
然后让它成为如
我的电脑
回收站
这样的图标该怎么做?就只有用一些专门的画图工具
因为Windows的的画图程序无法创建ico文件
于是本人利和GDI+就编写了一个这样的画图工具
虽然现在有很多文章都介绍了GDI+技术
但都只是纯粹的GDI+的简单应用的介绍
至少我还没有看见一篇利用GDI+开发一个完整软件或程序片段的文章
这个程序实现了以下的功能将BMPJPGjpegGIFpngtiff文件转化成ico文件可以对转化后的文件进行编辑创建并编辑一个新的ico文件对已有的ico文件进行编辑所有被编辑的文件都保存为ico文件可以在任何可使用ico文件的地方使用它们
我先说明一下什么是GDI+GDI+ 是GDI(Windows 早期版本提供的图形设备接口)的后续版本是Microsoft Windows XP操作系统即后续版本的图形显示技术它已经集成到开发环境中所以不管你的OS是什么版本只要安装了NET框架就有了GDI+(注意框架而不开发环境所以win中也可以使用GDI+)当然它也提供了传统的api可以或开发工具调用它由于他和GDI的使用有很大的差别所以要使用GDI+就必须从头学GDI+要比GDI简单得多
现在就来看一下如何实现这个软件先添加pictureboxpenfiledialogsavefiledialogcolordialogdomainupdownlabel控件然后添加两个菜单即它们的子菜单添加的菜单如下文件菜单包括新建打开保存退出功能菜单包括直线选择颜色代码如下在代码后给出程序说明
Public Class Form
Inherits SystemWindowsFormsForm
Public imagepen newbit changiamge mpen movepenmovebgrhfilenamesendpen
Dim xd yd xu yu pk ps
Private Sub MenuItem_Click(ByVal sender As SystemObject
ByVal e As SystemEventArgs) Handles MenuItemClick
新建一个ico文件即新建菜单
PictureBoxImage = Nothing
Dim bitnew As New SystemDrawingBitmap(
DrawingImagingPixelFormatFormatbppArgb)建立一个Bitmap对象以便在它上面画图
Dim x y
For x = To
For y = To
bitnewSetPixel(x y ColorTransparent)将Bitmap的背景设置为透明
Next
Next
newbit = bitnew
MenuItemEnabled = False选择颜色菜单不可用
MenuItemEnabled = True直线菜单可用
End Sub
Private Sub MenuItem_Click(ByVal sender As SystemObject
ByVal e As SystemEventArgs) Handles MenuItemClick
打开图片文件即打开菜单
OpenFileDialogFilter = ico文件(*ico)|*ico|图像文件
(*BMP;*JPG;*jpeg;*GIF;*png;*tiff)|*BMP;*JPG;*jpeg;*GIF;*png;*tiff
OpenFileDialogFilterIndex =
OpenFileDialogShowDialog()
OpenFileDialogFileName =
End Sub
Private Sub MenuItem_Click(ByVal sender As SystemObject
ByVal e As SystemEventArgs) Handles MenuItemClick
MeClose()退出
End Sub
Private Sub MenuItem_Click(ByVal sender As SystemObject
ByVal e As SystemEventArgs)
Handles MenuItemClick
保存文件即保存对话筐
PictureBoxCursor = SystemWindowsFormsCursorsDefault
SaveFileDialogFilter = ico文件(*ico)|*ico设置要保存的文件后缀
SaveFileDialogShowDialog()
If SaveFileDialogFileName <> Then
If Not SaveFileDialogShowDialogCancel Then
Dim bmp As New SystemDrawingBitmap(PictureBoxImage
)从PictureBoxImage初始化Bitmap设置保存为图片的大小标准ico图由
*和*两种格式组成此处为*你也可以设置为*
Dim ico As SystemDrawingIcon = icoFromHandle(bmpGetHicon())
用Bitmap的句柄初始化icon他是专门处理ico文件的类
Dim file As New SystemIOFileStream(SaveFileDialogFileName()
IOFileModeCreate)创建文件流
icoSave(file)保存为ico文件
fileClose()关闭流
End If
End If
End Sub
Public Sub MenuItem_Click(ByVal sender As SystemObject
ByVal e As SystemEventArgs)
Handles MenuItemClick
是用直线在新建的ico中画图
PictureBoxCursor =SystemWindowsFormsCursorsCross
在PictureBox中鼠标的样式
ColorDialogShowDialog()
Dim pen As New Pen(ColorDialogColor DomainUpDownText())创建画笔
imagepen = pen
End Sub
Private Sub PictureBox_MouseDown(ByVal sender As SystemObject
ByVal e As SystemWindowsFormsMouseEventArgs)
Handles PictureBoxMouseDown
当按下鼠标左键时获取直线的起点
If eButton = MouseButtonsLeft Then
xd = eX / : yd = eY /
End If
End Sub
Private Sub PictureBox_MouseUp(ByVal sender As SystemObject
ByVal e As SystemWindowsFormsMouseEventArgs)
Handles PictureBoxMouseUp
画出直线
If PictureBoxCursor Is SystemWindowsFormsCursorsCross And ps <> Then
xu = eX : yu = eY
Mek( imagepen yu / xu / xd yd)
Else
If OpenFileDialogFilterIndex = Then
xu = eX : yu = eY
Mek( mpen yu / xu / xd yd)
End If
End If
End Sub
Public Sub k(ByVal k As Integer ByVal drawtool As Object
ByVal x As Integer ByVal y As Integer ByVal xs As Integer
ByVal ys As Integer)
If k = Then
PictureBoxSizeMode = PictureBoxSizeModeStretchImage自动容纳图片
PictureBoxImage = newbit
Dim Graphic As Graphics
Graphic = GraphicFromImage(MePictureBoxImage)在PictureBox上画图
GraphicSmoothingMode = DrawingDrawingDSmoothingModeAntiAlias锯齿削边
GraphicDrawLine(drawtool y x xs ys)画线
End If
If k = Then
PictureBoxSizeMode = PictureBoxSizeModeStretchImage
PictureBoxImage = changiamge
Dim Graphic As Graphics
Graphic = GraphicFromImage(MePictureBoxImage)
GraphicSmoothingMode = DrawingDrawingDSmoothingModeAntiAlias
GraphicDrawLine(drawtool y x xs ys)
End If
End Sub
Private Sub MenuItem_Click(ByVal sender As SystemObject
ByVal e As SystemEventArgs)
Handles MenuItemClick
对打开的ico文件用直线画图
ColorDialogShowDialog()
Dim mpen As New Pen(ColorDialogColor DomainUpDownText())建立画笔
mpen = mpen
End Sub
Private Sub OpenFileDialog_FileOk(ByVal sender As Object ByVal e As
SystemComponentModelCancelEventArgs)
Handles OpenFileDialogFileOk
打开文件
If OpenFileDialogFilterIndex = Then
Dim mpen As New Pen(ColorBlack DomainUpDownText())
mpen = mpen
MenuItemEnabled = False
MenuItemEnabled = True
Else
MenuItemEnabled = False
MenuItemEnabled = False
End If
If OpenFileDialogFileName <> Then
PictureBoxCursor = SystemWindowsFormsCursorsDefault
Dim images As New SystemDrawingBitmap(OpenFileDialogFileName)
changiamge = images
PictureBoxSizeMode = PictureBoxSizeModeStretchImage
PictureBoxImage = images
MeText = OpenFileDialogFileName
End If
End Sub
Private Sub Form_Load(ByVal sender As Object ByVal e As SystemEventArgs)
Handles MyBaseLoad
由于刚运行次程序时没有打开的ico文件和新建立的ico对象所以不可以创建画图工具对象
MenuItemEnabled = False
MenuItemEnabled = False
End Sub
End Class
程序说明
. 如何新建ico文件先初始化bitmap然后在功能》直线菜单代码中创建画笔就可以开始画了此时只是创建的一个bitmap对象是我们在picturebox中画画完后将bitmap对象保存到文件就完成了新建ico的文件
如何打开已有的ico文件并修改后保存它判断打开的文件是否是ico如果不是就只显示他如果是就显示并且初始化一个画笔通过功能》选择颜色来改变画出直线的颜色和宽度然后保存就完成了对原来ico文件的修改
保存文件和对非ico文件转化为ico文件通过打开文件将非ico文件显示在picturebox中在用pictureboximage初始化bitmap对象此句的实际作用是将当前的pictureboximage内容附给bitmap用bitmap的句柄初始icon对象(处理ico文件的对象)作用是将非ico文件转化为ico文件建立文件流对象在其中指定新文件名和访问方法(文件流是save方法的参数)使用icon对象的save保存最后关闭文件流
如何画当完成或后就可以开始画图画图是由sub k过程mousedownmouseup来实现的此时调用mousedown获得直线的起点在mouseup中获得直线终点接着在mouseup 中调用sub k过中程绑定bitmap对象到picturebox的image属性他的作用类似于有了一张可以画画的纸并在sub k中用GraphicFromImage(MePictureBoxImage)语句创建Graphics对象表示是在PictureBoxImage的bitmap对象中画而不是在PictureBox上画他们的区别在于前者是可以保存画画结果的后者不可以K的值表示是在新建的ico文件中画还是修改以有的ico文件(k=是表示修改已有的ico文件)
一些语句说明dim pen …是指用钢笔来画objectrawline(…)表示画直线
文件格式的转换问题你可以使用image对象的save的方法来转换图象的格式但是我发现虽然他提供了icon格式但转化后不是ico文件而是png文件从网上的资料显示这的本身问题顺便提一下image对象无构造函数他虽然标为必须继承才可使用但实际上不行如要使用它要用他的fromfile或fromstream方法来构造它
.关于k的问题当你看懂这篇文章后你一定会提出为什么在每条分支中的PictureBoxSizeMode = PictureBoxSizeModeStretchImagePictureBoxImage = changiamge这两句代码不可以与它后面的代码分开放在其他地方如k=时放在新建菜单中的代码部分k=是放在mouseup中的else后的if语句中!其实这两句就是我在编写这个程序时遇到的最大的难题我用了两个小时才的出这两句代码要放在了现在的位置最后看资料并与朋友探讨后得出个结论
NET本身问题
如果分开使PictureBoxImage对象丢失(PictureBoxImage返回的是bitmap对象)无法绑定到Graphics
PictureBoxImage对象在sub k中不可见虽然我不知道那个结论是对的但我将它写了出来仅供参考
对于程序中的penfiledialogsavefiledialogcolordialogdomainupdown文件流的使用请见msdn这个只是为了辅助这个程序而使用的如果要在这里讲清楚那这片文章就太长了而且这些的使用很简单我在程序中使用的画图工具是钢笔画出的图形是直线这队ico文件已经够有了如果你想使用其他工具画其他图形只要修改功能中的子菜单和sub k代码就够了
运行如图
更换后的我的电脑图标