C#使用游标实现补间函数
作者:RunnerDNA 发布时间:2021-10-13 21:59:35
标签: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();
}
运行结果:
来源:https://blog.csdn.net/dnazhd/article/details/88423844


猜你喜欢
- 问题现象今天在做一个需求:将存入数据库中的数据读到后解析成list遍历分析数据格式:"[1677660600000, 167766
- 这篇文章主要介绍了Java方法参数传递机制原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可
- Android11 读写权限申请Android11系统对应用写入权限做了严格的限制。本文介绍如何获取文件读写权限。项目中 build.gra
- 一、选择结构大纲if单选择结构if双选择结构if多选择结构嵌套的if结构switch多选择结构二、if单选择结构我们很多时候需要去判断一个东
- 最近博主开始在项目中实践MVP模式,却意外发现内存泄漏比较严重,但却很少人谈到这个问题,促使了本文的发布,本文假设读者已了解MVP架构。MV
- 本文实例为大家分享了java实现webservice方式的具体代码,供大家参考,具体内容如下经过测试 jdk1.6.10以下会出现bug 建
- 本文介绍一些Java初学者常问的问题,可以用%除以一个小数吗? a += b 和 a = a + b 的效果有区别吗? 声明一个数组为什么需
- Android中Uri和Path之间的转换原因调用系统拍照应用,拍照后要保存图片,那么我们需要指定一个存储图片路径的Uri。这就涉及到如何将
- 激活码:9MWZD5CC4E-eyJsaWNlbnNlSWQiOiI5TVdaRDVDQzRFIiwibGljZW5zZWVOY
- 1.利用参数出现的顺序利用mapper.xml<select id="MutiParameter" resultT
- 本文实例讲述了Java文本文件操作方法。分享给大家供大家参考。具体分析如下:最初Java是不支持对文本文件的处理的,为了弥补这个缺憾而引入了
- Springboot对配置文件的敏感信息加密前言最近公司对软件的安全问题比较在意,要求对配置文件中的敏感信息如数据库密码等进行加密。但是Sp
- JSONArray删除元素的两种方式我自个磨出来的,难受JSONArray jsonarray = new JSONArray();Set&
- 今天给大家带来的是一块用WPF 实现魔方的小游戏,先看一下效果图 代码如下,先写一个类,用来判断是否可以移动using System;usi
- java实现接口签名为了保证数据传输的安全性,跟其他系统进行数据交互时,双方应该约定好密钥,把数据进行加密,接口签名,这样双方调用接口时,验
- 这篇文章主要介绍了基于Java向zip压缩包追加文件,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友
- eclipse 创建 user library 方法1、Window - Preferences - Java - Build Path -
- 最近有人问我如何实现倒计时的按钮功能,例如发送验证码,我记得有个CountDownTimer,因为好久没用过了,自己就写了一个,代码如下 n
- 由于 * 一般都比较难理解,程序设计者会设计一个 * 接口供开发者使用,开发者只要知道 * 接口的方法、含义和作用即可,无须知道 * 是
- 一般入参我们都会转为vo对象。那么直接在对象的属性上注解即可。 其实spring用的是hibernate的validator.步骤1.配置s