利用C#实现超酷动态图像按钮

继续我们的.Net控件开发之旅….

前一阵子参与一个项目开发,好友总是抱怨工具栏按钮太简陋了:要是弄得炫一点该多好啊,看看人家mac的桌面工具栏!事实也的确如此,现在越来越多的程序界面做的是相当的酷啊,无论是什么平台macwindows还是linux,其界面元素越来越丰富,一个小小的button背景都要在鼠标的不同事件激活下渐变来渐变去。但是,遍历VS IDE中默认的工具集合我们是无论如何也找不到如此复杂的控件的,所以,我们必须借助强大的.Net框架以及GDI+自己动手来制作类似的工具栏按钮控件。

我们要创建的控件简单说就是一个动态渐变的图片按钮,示例程序界面如下:

bb

这个button控件依旧继承自UserControlUserControl是制作自定义UI控件绝对的父类,这里不再细说。我们为这个button取名为DynamicImageButton制作图像按钮当然离不开绘制,所以还得用到GDI+,我曾经写过多篇关于界面元素的文章,比如利用.Net绘图技术制作水晶按钮控件利用C#实现任务栏通知窗口利用C#为数码照片添加拍照日期” C#实现运行时拖动控件并调整控件大小等等,其中都会涉及到GDI+的诸多方面,可见GDI+在设计制作UI上是多么的重要啊!

对于按钮图片透明度渐变的操作则比较有技巧,采取了个人认为比较另类却极其高效的方法。制作图片按钮肯定是要为这个button赋值一个图像文件的,我们需要公开一个属性,代码如下:

public Bitmap Image

{

get { return bmp[0]; }

       set

       {

      bmp[0] = value;

             bmp[1] = returnAlpha(value, 60);

             bmp[2] = returnAlpha(value, 120); ;

             bmp[3] = returnAlpha(value, 180); ;

            draw();               

     }

}

大家注意到,当给这个DynamicImageButtonimage属性赋值一幅图片后,立即就会对这个原始图片经过4种不同的alpha过滤后分别存放到bmp位图数组下。bmp[0]保存原始图像,bmp[3]的图像则最透明。这就是本程序的特点所在,也就是在运行时是不进行图像透明度渐变计算的,在给image属性赋值时计算工作同时也已经完成了,这样可以省下鼠标移动事件的巨大计算量。returnAlpha方法就是将原始图像中的每一个像素按照相应的alpha值进行重新绘制后保存在bmp数组中,不同透明度的图像作为bmp数组的不同元素进行保存。代码如下:

public static Bitmap returnAlpha(Bitmap bmp, int alpha)

{

Color col;

       Bitmap bmp2 = new Bitmap(bmp);

for (int i = 0; i < bmp.Width; i++)

            for (int j = 0; j < bmp.Height; j++)

           {

                  col = bmp.GetPixel(i, j);

                  if (col.A > 0)

                       bmp2.SetPixel(i, j, Color.FromArgb(min(col.A - alpha), col.R, col.G, col.B));

           }

       return bmp2;

}

到这里大家可能就已经明白我的用意了,没错!从原始图像到最终图像的透明渐变我只设计了4帧!其实,这对于一个小小的button动画来说已经完全足够了。对于图像的绘制方法我们仍旧采用双缓冲区绘制,也就是内存复制,实际上就是双bitmap对象交替使用,这样可以更好的防止图像闪烁(参见我的另一篇文章 .NET框架下使用双缓冲技术绘图”)。相关代码如下:

private void DynamicImageButton_Paint(object sender, System.EventArgs e)

{

g2 = Graphics.FromImage(dblbuffer);

g2.Clear(this.BackColor);

       curx = (int)((double)Width) / 6;

       cury = (int)((double)Height) / 6;

       curwidth = (int)((double)Width) / 3 * 2;

       curheight = (int)((double)Height) / 3 * 2;

       itvwidth = (Width - curwidth) / 2;

       g2.DrawImage(bmp[3], curx, cury, curwidth, curheight);

       g.DrawImageUnscaled(dblbuffer, 0, 0);

}

然后就是对图像大小渐变的控制了,如下图所示:

bb

    a
bcd四个矩形代表不同大小的4个帧,a帧是装载图像时的默认大小,就是bmp[0]的图像,也是4帧中最大的一帧,width=75height=72是我们示例程序控件的大小,网友可以随意对长宽进行重新设定。这两个数值是基础,bmp[0]的图像会完全填充到这个区域内,在这个给定的长和宽的基础上我们计算出bcd三帧的图像大小和位置。然后创建一个计数器,当鼠标Enter或者Leave我们创建的这个DynamicImageButton时对图像的透明度和大小的渐变进行控制。相关代码如下: 

private void timer1_Tick(object sender, EventArgs e)

        {

            if (mp == enumMousePosition.Enter)

            {

                if ((curx <= 0) || (cury <= 0) || (Width == curwidth) || (Height == curheight))

                {

                    return;

                }

                g2 = Graphics.FromImage(dblbuffer);

                g2.Clear(this.BackColor);

                //g2.Clear(Color.White);

                if (curx >= itvwidth-2)

                {

                    g2.DrawImage(bmp[3], curx - 1, cury - 1, curwidth + 2, curheight + 2);

                }

                else if ((curx>= itvwidth / 3 * 2) && (curx < itvwidth))

                {

                    g2.DrawImage(bmp[2], curx - 1, cury - 1, curwidth + 2, curheight + 2);

                }

                else if ((curx >= itvwidth / 3) && (curx <= itvwidth / 3 * 2))

                {

                    g2.DrawImage(bmp[1], curx - 1, cury - 1, curwidth + 2, curheight + 2);

                }

                else if ((curx >= 0) && (curx <= itvwidth / 3))

                {

                    g2.DrawImage(bmp[0], curx - 1, cury - 1, curwidth + 2, curheight + 2);

                }

                g.DrawImageUnscaled(dblbuffer, 0, 0);

                curx--;

                cury--;

                curwidth = curwidth + 2;

                curheight = curheight + 2;

                if ((curx <= 0) || (cury <= 0) || (Width == curwidth) || (Height == curheight))

                {

                    timer1.Stop();

                }

            }

            else if (mp == enumMousePosition.Leave)

            {

                if ((curx >= (int)((double)Width) / 6) ||

                    (cury >= (int)((double)Height) / 6) ||

                    (curwidth <= (int)((double)Width) / 3 * 2) ||

                    (curheight == (int)((double)Height) / 3 * 2))

                {

                    return;

                }

                g2 = Graphics.FromImage(dblbuffer);

                g2.Clear(this.BackColor);

                //g2.Clear(Color.White);

                if (curx >= itvwidth-2)

                {

                    g2.DrawImage(bmp[3], curx - 1, cury - 1, curwidth + 2, curheight + 2);

                }

                else if ((curx >= itvwidth / 3 * 2) && (curx < itvwidth))

                {

                    g2.DrawImage(bmp[2], curx - 1, cury - 1, curwidth + 2, curheight + 2);

                }

                else if ((curx >= itvwidth / 3) && (curx <= itvwidth / 3 * 2))

                {

                    g2.DrawImage(bmp[1], curx - 1, cury - 1, curwidth + 2, curheight + 2);

                }

                else if ((curx >= 0) && (curx <= itvwidth / 3))

                {

                    g2.DrawImage(bmp[0], curx - 1, cury - 1, curwidth + 2, curheight + 2);

                }

                g.DrawImageUnscaled(dblbuffer, 0, 0);

                curx++;

                cury++;

                curwidth = curwidth - 2;

                curheight = curheight - 2;

                if ((curx >= (int)((double)Width) / 6) ||

                    (cury >= (int)((double)Height) / 6) ||

                    (curwidth <= (int)((double)Width) / 3 * 2) ||

                    (curheight == (int)((double)Height) / 3 * 2))

                {

                    timer1.Stop();

                }

            }

}

至此,一个超酷的动态图像按钮就制作完毕了,该程序在Windows XP SP3 +VS2005 C# SP1环境下编译调试通过。

【本文附带源码】

fj.pngDynamicImageButton1.jpg

fj.pngDynamicImageButton2.jpg

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/14325734/viewspace-426850/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/14325734/viewspace-426850/

WinForms自定义控件:打造炫酷旋转开关按钮的实战指南 本文介绍了一个用C#实现的自定义旋转开关按钮控件,具备平滑动画、金属质感和智能交互功能。该控件通过Timer实现360°旋转动画,使用Graphics绘制动态图形和金属光泽效果,并利用Invalidate()方法触发重绘。核心功能包括:1)点击时播放旋转动画;2)状态切换逻辑(_isOn变量记录状态);3)交互反馈机制(重写OnMouseClick方法)。代码超过300行,包含完整实现和详细注释,支持自定义颜色、尺寸和动画时长,适用于提升Windows Forms应用程序的视觉体验。 阅读详情

相关推荐

动态创建和管理C#按钮的技巧

本文还有配套的精品资源,点击获取 简介:在C#中,动态添加按钮是创建交互式用户界面的一个重要方面,尤其是在需要根据程序运行时条件或用户输入来生成控件的情况下。本文详细介绍了如何在Windows Forms应用程序中实例化Button类对象,并将其添加到容器控件中,如Form或Panel。同时,本文还展示了如何为这些动态创建的按钮添加点击事件处理器,并处理按钮事件。此外,还讨...

weixin_42598278的博客 1885

C#自定义控件之-winform美化

对于系统自带的窗体,博主实在不敢恭维,测试时使用方便快捷,但真正项目中无法使用,只因不美观的外表,每次都很头疼窗体的美化,这里列出一些需要解决的问题和自己收集到的解决方法,如有错误请指出。

C#实现PictureBox图片缩放与拖动交互功能

C# Windows Forms 是 .NET Framework 提供的一个用于构建桌面应用程序的图形界面框架,适用于快速开发具有交互性的 Windows 桌面应用。本章将引导读者了解 Windows Forms 的基本结构、开发环境的搭建流程,以及如何使用 Visual Studio 创建一个基础的 Windows Forms 应用程序。

weixin_28721743的博客 1113

C#制作的渐变Button控件

一个用C#制作的控件,GDI 可以自定义渐变色,对编程非常实用

C# 动态创建按钮

动态创建按钮,加按钮事件响应

weixin_45053845的博客 1628

C#中使用GDI+绘制一把漂亮的直尺(带透明度)

这是三年前研究C#与GDI+时的作品,它使用C#与GDI+绘制一把有透明度、带刻度 (以像素为单位)的直尺。最终效果:横向直尺:(注:设置了80%不透明度)竖向直尺:(注:设置了100%不透明度,即完全不透明)C#代码:using System;using System.Drawing;using System.Drawing.Drawing2D;using System.Re

祝紫山(大可山人)博客[GDI+,WPF, .Net图形图像] 1万+

WPF C# 个性按钮实现

运行结果:   1、资源设置、绑定 &lt;Window.Resources&gt; &lt;Style x:Key="NoneStyleBtn" TargetType="{x:Type Button}"&gt; &lt;Setter Property="Background" Value="Transparent"/&

坐听风雨 1891

视频转为GIF怎么做 如何做GIF动态图

GIF是我们日常聊天中少不了的一个娱乐工具,不仅是QQ、微信这些常用的聊天工具,很多短视频中也是有GIF动态图的存在的,那我们平时使用的应该都是这些工具中自带的吧!很少会自己动手制作,那像这样的GIF制作工具有什么呢?视频转为GIF怎么做,如何做GIF动态图呢? 1、首先这不仅是一个可以将视频转为GIF的工具,还可以直接录制电脑中出现的内容,自己想要什么样的GIF都可以打开播放源直接录制; ...

夏末的博客 2573

ArcGIS动态图

ArcGIS Server 10.1新特性里面有几个新功能是非常棒的,其中有一个就是动态图层。动态图层不是一种新发明的图层,而是说在arcgis server的web应用中可以动态的配置其渲染和内容功能的图层,动态mapservice中的图层都可以通过相应的配置使其成为动态图层。动态图层的功能的产生是mapservice的核心功能进行增强的结果。 动态图层功能的产生背景: 先提出两个需

engineer_he的博客 6879

atitit.GUI图片非规则按钮动态图片切换的实现模式总结java .net c# c++ web html js

atitit.GUI图片非规则按钮动态图片切换的实现模式总结java .net c# c++ web html js    1. 图片按钮的效果总结 1 1.1. 按钮图片自动缩放的。 1 1.2. 不要边框,如果用自定义图片做按钮背景可以设为 false。 2 1.3. 异形按钮 2 1.4. 不绘制焦点 2 1.5. 鼠标经过时的图标 2 1.6. 选中时的图标 2 1.7

attilax的专栏 2239

录制的短视频怎么转为GIF动态图

视频已经成为我们生活和工作中必不可少的一个传递信息的方式,周末追剧似乎是不约而同的一个打发时间的方式,近几年GIF也成为了聊天交流的一个方式,其实视频和GIF是有很多的相似性的,可以将视频转为GIF,今天小编就带大家一起看看录制的短视频怎么转为GIF动态图吧! 1、今天要说的GIF制作工具支持屏幕录制,支持视频图片编辑,高质量生成GIF并且可以迅速生成预览,操作也比较简单快速;2、打开迅捷GIF...

weixin_33955681的博客 712

C#实现漂亮按钮

C#实现的透明半圆按钮,使初学者提高漂亮控件的学习

如何用C#实现漂亮的动态图按钮

如何用C#实现漂亮的动态图按钮 很详细

漂亮的插件csharp:漂亮的C#插件

:construction: 工作正在进行中! :construction: 漂亮的C#插件 介绍 Prettier C#将C#支持添加到代码格式化程序中。 像Prettier一样,它自以为是并将样式选项限制到最小。 它在Prettier运行的地方运行,包括CI和预提交挂钩。 工作正在进行中 请注意,此插件正在积极开发中,可能尚未准备好在生产代码上运行。 它将破坏您的代码。 使用此预览结果。 安装 yarn add --dev --exact prettier prettier-plugin-csharp 利用 prettier --write " **/*.cs " 这个怎么运作 该插件是用JavaScript编写的。 它依赖于ANTLR

图像眼睛怎么眨眼c语言,可牛影像怎么制作眨眼动态图 可牛影像制作眨眼动态图教程...

在聊天时候发一些动态图非常生动可爱。今天小编就给大家讲讲用可牛影像怎么制作眨眼动态图,让你可以轻松制作出眨眼动图,当表情包来使用。类别:图像制作 大小:12.57M 语言:简体中文评分:6可牛影像制作眨眼动态图教程第一步:运行可牛影像,点击“打开一张图片”按钮,打开一张正面照。牛牛建议大家,不要选用眼睛特别大的照片,否则不便于编辑。如图所示:第二步:要做出眨眼效果,牛牛首先要让美眉把美丽...

weixin_42469649的博客 922

如何截取视频中的一部分,制作成GIF动态图

怎么把视频做成gif 截取视频中的一部分内容,制作成GIF动态图?是先用播放器进行截取,还是说先转换视频格式,然后用相应的GIF编辑器呢。网上关于怎样把视频截取转化成gif动态图片的方法有很多,林林总总可谓看的是眼花缭乱...

cite5110的博客 443

C#结合Halcon实现视觉软件窗体控件设计

Halcon软件作为一个功能强大的机器视觉软件平台,图像采集与处理是其核心功能之一。用户可以利用它来完成图像的捕获、预处理、分析和结果输出。图像采集可以是静态的,也可以是动态的。静态图像采集常用于文档扫描或静态物体的检测,而动态图像采集则用于视频监控、工业流水线检测等场景。Halcon提供了与多种工业相机通讯的接口,能够实时获取高质量的图像数据。在图像预处理环节,Halcon提供了丰富的滤波、校正、增强等算法。例如,通过去噪滤波器可以清除图像中的噪点,提高后续分析的准确性;

weixin_42610010的博客 1009

Unity3d笔记——利用Animator使模型动起来

Unity3d笔记——利用Animator使模型动起来一. 从Asset Store中下载合适的模型 本篇记录了一个小demo的制作过程,从找模型并下载,到创建Animator,绑定C#脚本,最后实现按下左箭头模型向我们的左边旋转,按下右箭头模型向我们右边旋转的全部过程。希望大家能共同学习共同进步。 一. 从Asset Store中下载合适的模型 首先点击菜单栏中的window -&amp;amp;amp;amp;amp;amp;amp;gt; ass...

github_37462634的博客 1万+
上一篇: 实战.Net多线程(四)
下一篇: delegate_event.rar
clj2012
博客等级 码龄11年 0粉丝 0原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值