C#使用游标实现补间函数

 更新时间:2022年02月21日 16:22:39   作者:RunnerDNA  
这篇文章主要为大家详细介绍了C#使用游标实现补间函数,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

补间可以实现两个图形之间颜色、形状、大小、位置等的线性变化。

例如A...AB...BC...C,其中A、B、C是三幅图片,两个A的宽分别是10cm和50cm,两个A之间共5帧,那么使用补间操作后,A图片的宽分别是10cm、20cm、30cm、40cm、50cm,B和C图片的宽度计算同理。对于A...ABC...C或者A...ABBC...C这种情况,B不进行补间操作。

下面新建一个控制台处理程序,添加图片类ImageClass.cs。

public class ImageClass
{
    //宽
    public int Width { get; set; }
    //高
    public int Height { get; set; }
    //模拟判断是否是同一张图片
    public string Path { get; set; }
    public ImageClass(int _width,int _height,string _path)
    {
        Width = _width;
        Height = _height;
        Path = _path;
    }
}

新建图片帧类ImgFrameClass.cs。

public class ImgFrameClass
{
    public ImageClass FramesImg { get; set; }
    public int Frames { get; set; }//图片位于的帧数
 
    public ImgFrameClass(ImageClass _frameImg, int _frames)
    {
        FramesImg = _frameImg;
        Frames = _frames;
    }
}

新建补间算法类,需要引用Newtonsoft.Json。

using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace TweenDemo
{
    public class Utility
    {
        public static List<ImgFrameClass> SetTween(List<ImgFrameClass> _imgFrameList)
        {
            List<ImgFrameClass> imgFrameResultList = new List<ImgFrameClass>();
            List <ImgFrameClass> imgFrameList = DeepCopyWithSerialization(_imgFrameList);
            //定义两个游标,初始化为相邻游标
            int b = 0, a = 1;
            int len = imgFrameList.Count;
            //存在相同元素的个数
            int count = 0;
            string samePath = string.Empty;
            while (a < len)
            {
                ImgFrameClass itemb = imgFrameList[b];
                ImgFrameClass itema = imgFrameList[a];
 
                while (b >= 0 && a < len && (imgFrameList[b].FramesImg.Path == imgFrameList[a].FramesImg.Path))
                {
                    samePath = imgFrameList[b].FramesImg.Path;
                    while (a < len && (imgFrameList[a].FramesImg.Path == samePath))
                    {
                        a++;
                    }
                    count = count + 2;
                }
 
                if (count != 0)
                {
                    ImgFrameClass tweenStartItem = imgFrameList[b];
                    ImgFrameClass tweenStopItem = imgFrameList[a - 1];
                    //添加初始图片
                    imgFrameResultList.Add(tweenStartItem);
 
                    ImageClass tweenStartImg = DeepCopyWithSerialization(tweenStartItem.FramesImg);
                    ImageClass tweenStopImg = DeepCopyWithSerialization(tweenStopItem.FramesImg);
                    double tweenFrame = tweenStopItem.Frames - tweenStartItem.Frames;
                    double tweenImgW = (double)(tweenStopImg.Width - tweenStartImg.Width) / tweenFrame;
                    double tweenImgH = (double)(tweenStopImg.Height - tweenStartImg.Height) / tweenFrame;
 
                    int coutStart = tweenStartItem.Frames;
                    int coutStop = tweenStopItem.Frames;
                    //插入补间图片
                    for (int i = coutStart + 1; i < coutStop; i++)
                    {
                        ImageClass tweenAddImg = new ImageClass((int)(tweenStartImg.Width + tweenImgW * (i - coutStart)), (int)(tweenStartImg.Height + tweenImgH * (i - coutStart)),samePath);
                        imgFrameResultList.Add(new ImgFrameClass(tweenAddImg,i));
                    }
 
                    //添加末尾图片
                    imgFrameResultList.Add(tweenStopItem);
                }
                else
                {
                    imgFrameResultList.Add(imgFrameList[b]);
                }
                //不满足则正常移动游标,都向前移动一个,相同元素的个数置0
                b = a++;
                count = 0;
            }
            return imgFrameResultList;
        }
 
        public static T DeepCopyWithSerialization<T>(T obj)
        {
            string json = JsonConvert.SerializeObject(obj);
            T copy = JsonConvert.DeserializeObject<T>(json);
            return copy;
        }
    }
}

模拟生成AAAAABBBBCBB结构的数据,Main函数如下:

static void Main(string[] args)
{
    //模拟生成测试数据
    List<ImgFrameClass> imgFrameList = new List<ImgFrameClass>();
    imgFrameList.Add(new ImgFrameClass(new ImageClass(10, 10, "A"),1));
    imgFrameList.Add(new ImgFrameClass(new ImageClass(50, 50, "A"), 5));
    imgFrameList.Add(new ImgFrameClass(new ImageClass(10, 10, "B"), 6));
    imgFrameList.Add(new ImgFrameClass(new ImageClass(80, 80, "B"), 9));
    imgFrameList.Add(new ImgFrameClass(new ImageClass(10, 10, "C"), 10));
    imgFrameList.Add(new ImgFrameClass(new ImageClass(10, 10, "B"), 11));
    imgFrameList.Add(new ImgFrameClass(new ImageClass(30, 30, "B"), 12));
 
    List<ImgFrameClass> imgFrameResultList = Utility.SetTween(imgFrameList);
    foreach (ImgFrameClass item in imgFrameResultList)
    {
        Console.WriteLine(string.Format("Img{0},width:{1},height:{2}", item.FramesImg.Path, item.FramesImg.Width, item.FramesImg.Height));
    }
    Console.ReadLine();
}

运行结果:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • C#中Timer实现Tick使用精度的问题

    C#中Timer实现Tick使用精度的问题

    这篇文章主要介绍了C#中Timer实现Tick使用精度的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-08-08
  • UnityShader3实现2D描边效果

    UnityShader3实现2D描边效果

    这篇文章主要为大家详细介绍了UnityShader3实现2D描边效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-02-02
  • C#使用随机数编写班级点名器的示例代码

    C#使用随机数编写班级点名器的示例代码

    本文主要介绍了C#使用随机数编写班级点名器的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-05-05
  • C# DataSet的内容写成XML时如何格式化字段数据

    C# DataSet的内容写成XML时如何格式化字段数据

    许多读者经常询问一个问题,那就是在将DataSet的内容写成XML时,如何格式化字段数据。最常见的需求,就是希望日期时间值与数值数据能够以所需的格式呈现于XML中。
    2009-02-02
  • C#用表达式树构建动态查询的方法

    C#用表达式树构建动态查询的方法

    这篇文章主要介绍了C#用表达式树构建动态查询的方法,帮助大家更好的理解和学习c#,感兴趣的朋友可以了解下
    2020-12-12
  • c#中LINQ的基本用法(三)

    c#中LINQ的基本用法(三)

    这篇文章介绍了c#中LINQ的基本用法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下的相关资料
    2022-04-04
  • 3种C# 加载Word的方法

    3种C# 加载Word的方法

    本次经验内容分享通过C#程序来加载Word文档的3种不同方法。分别是:加载本地Word文档、以只读模式加载Word文档、从流加载Word 想具体了解的小伙伴请参考下文
    2021-09-09
  • C#自定义控件指示灯效果

    C#自定义控件指示灯效果

    在C#中实现一个指示灯控件,可以通过GDI+技术绘制,首先使用Pen对象绘制外环,然后用SolidBrush对象填充内圆,通过RectangleF定义绘制和填充的边界,控件的属性包括颜色、间隙、外环宽度等,本文给大家介绍C#自定义控件指示灯效果,感兴趣的朋友跟随小编一起看看吧
    2024-09-09
  • C#实现简单学生信息管理系统

    C#实现简单学生信息管理系统

    这篇文章主要为大家详细介绍了C#实现简单学生信息管理系统,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-06-06
  • C#中new的用法及与override的区别分析

    C#中new的用法及与override的区别分析

    这篇文章主要介绍了C#中new的用法,及与override的区别,需要的朋友可以参考下
    2017-05-05

最新评论