C#使用游标实现补间函数
时间:2022-12-08 12:56:11|栏目:.NET代码|点击: 次
补间可以实现两个图形之间颜色、形状、大小、位置等的线性变化。
例如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(); }
运行结果: