C# winform 超简单的花样图片切换

来源:互联网 发布:淘宝助理怎么添加水印 编辑:程序博客网 时间:2024/06/02 17:55

         曾今想过写一个展示图片的winform 但是pictureBox直来直去的切换非常的生硬,上网找了找也没找到特别和自己心意的。

一般想来,展示图片至少得十几种切换效果 百叶窗啊 淡入淡出啊 推送啊 写来写去得累死。


        于是根据某个galgame引擎得到了灵感,使用遮片来进行图片的切换。


        遮片是一张黑白渐变的图片,从中获取渐变的规则,然后对需要切换的两种图片的alpha值进行更改,然后层叠绘制到界面。


       我最开始的想法是使用bitmap的GetPixel 和 SetPixel 加上循环来更改,首先保证三张图片的宽和高一致,然后从头到尾进行循环,获取遮片的R值 并赋值给图片2的A值 再将

图片1的A值设置为255减去遮片的R值,由于A和R值都是从0-255,所以不用担心会溢出。然后遮片的R值加1 在进行循环,这样制造图片的切换效果。

        但是实际操作给了我一个大大的打击,因为太~~~慢了,每刷新一次需要等上差不多10秒钟,我勒个去这根本不能用233。。。


        后面请教了高人,大概知道了拖慢速度的原因,于是开始先把所有的数据放到内存中再进行操作,锁定图片后将所有的数据使用Marshal.Copy放入一个byte数组中,运算完毕后再使用Marshal.Copy放回去,最后解锁图片,进行绘制。

        速度总算是提升上来了,但是图片直接绘制非常的闪,最后加上了缓存。


下面贴源代码  源代码下面贴效果图


using System;using System.Drawing;using System.Drawing.Imaging;using System.Runtime.InteropServices;using System.Windows.Forms;namespace 遮片切图{    public partial class Form1 : Form    {        Graphics g, gb;        Image img1;        Image img2;        Image zp;        Bitmap bitmap1;        Bitmap bitmap2;        Bitmap bitmap;        BufferedGraphics buffer;        Rectangle form_rect;        public Form1()        {            InitializeComponent();        }        byte[] pixels, pixels2;        int width, height;        private void Form1_Load(object sender, EventArgs e)        {            img1 = Image.FromFile(@"1.jpg");            img2 = Image.FromFile(@"2.jpg");            zp = Image.FromFile(@"zp0.png");            bitmap1 = new Bitmap(img1);            bitmap2 = new Bitmap(img2);            bitmap = new Bitmap(zp);            g = Graphics.FromHwnd(this.Handle);            form_rect = new Rectangle(0, 0, bitmap.Width, bitmap.Height);            var bit2 = bitmap2.LockBits(form_rect, ImageLockMode.ReadWrite, bitmap2.PixelFormat);            var bit = bitmap.LockBits(form_rect, ImageLockMode.ReadWrite, bitmap.PixelFormat);            width = bit.Width;            height = bit.Height;            pixels2 = new byte[Math.Abs(bit2.Stride) * bit2.Height];            pixels = new byte[Math.Abs(bit.Stride) * bit.Height];            Marshal.Copy(bit2.Scan0, pixels2, 0, pixels2.Length);            Marshal.Copy(bit.Scan0, pixels, 0, pixels.Length);            bitmap.UnlockBits(bit);            bitmap2.UnlockBits(bit2);            buffer = BufferedGraphicsManager.Current.Allocate(g, form_rect);            gb = buffer.Graphics;        }        private void Form1_KeyDown(object sender, KeyEventArgs e)        {            if (e.KeyCode == Keys.D)            {                var startlong = DateTime.Now;                int alphaa = 255;                Point origin = new Point(0, 0);                while ((alphaa -=35) >= -270)                {                    for (int i = 0; i < height * width * 4; i += 4)                    {                        int alpha = pixels[i + 2] + alphaa;                        alpha = alpha > 255 ? 255 : alpha;                        alpha = alpha < 0 ? 0 : alpha;                        pixels2[i + 3] = (byte)(255 - alpha);                    }                    var bit2 = bitmap2.LockBits(form_rect, ImageLockMode.ReadWrite, bitmap2.PixelFormat);                    Marshal.Copy(pixels2, 0, bit2.Scan0, pixels2.Length);                    bitmap2.UnlockBits(bit2);                    gb.DrawImage(bitmap1, origin);                    gb.DrawImage(bitmap2, origin);                    buffer.Render();                }                var endlong = DateTime.Now;                var space = endlong - startlong;                MessageBox.Show(space.TotalMilliseconds.ToString());            }        }    }}

需要切换的两张图片


遮片0号

使用遮片0号的效果


遮片2号


使用遮片2号的效果


所有的效果都是切换途中的  可别以为代码不能切换完毕啊。。。



耗时



希望大家看看有没有更快的方法

0 0
原创粉丝点击