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();
}

运行结果:

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

(0)

相关推荐

  • C#中加载dll并调用其函数的实现方法

    C#编程中,调用封装dll中的函数是高频使用的.那么,如何在程序中加载dll并调用其中的函数呢?更进一步的,如何在主程序中对自己封装的dll中的函数进行调试呢? 加载dll-添加引用 添加引用的意思是让程序生成时根据配置的路径去加载相应的dll.其引用的步骤如下图所示: 解决方案->引用-> 添加引用-> 浏览-> 选择dll所在的路径->确定 导入命名空间.实例化对象.调用函数 只有导入该dll的命名空间,才能使用该空间下的类.因此,在引用了dll之后的第一步是导入命名空间

  • C# 中如何取绝对值函数

    话不多说,请看代码: System.Math.Abs(float value); System.Math.Abs(decimal value); System.Math.Abs(int value); System.Math.Abs(double value); System.Math.Abs(sbyte value); System.Math.Abs(long value); System.Math.Abs(short value); PS:下面看下c++ 取绝对值函数 int abs(int

  • C# Math.Round()函数问题

    Math.Round ()在四舍五入时有个问题: Math.Round(2.5,0) = 2; Math.Round(3.5,0) = 4; 2.5应该等于3才对! 在ASP中也存在这个问题,不过ASP中还有个FormatNumber可以用,但目前还不知道怎么使用? 解释: Math.Round()准确的说,这个函数不是四舍五入,而是四舍六入五凑偶,就是说小于4或大于6的该舍该入是没有争议的,而5处在正中间,如果四舍五入则会造成数据的整体偏差,所以采取的原则是:如果舍入位为5,则舍入后最后一位为

  • 详解C#中通过委托来实现回调函数功能的方法

    委托(delegate)是一种可以把引用存储为函数的类型,这类似于c++中的函数指针. 回调函数 c++中的回调函数,就是用函数指针来实现的.类似的,c#中用委托,来实现回调函数的功能. 回调函数为什么被称为回调函数?比如你调用了一个函数,那么就叫调用,但是如果你在调用一个函数的时候,还需要把一个函数提供给该函数,让这个函数来调用你的函数,那么你提供的这个函数就被称为回调函数(callback). 对于python这样的动态语言而言,就没有c#,c++提供特殊的语法实现回调函数,因为在pytho

  • C# 递归函数详细介绍及使用方法

    什么是递归函数/方法? 任何一个方法既可以调用其他方法也可以调用自己,而当这个方法调用自己时,我们就叫它递归函数或递归方法. 通常递归有两个特点: 1. 递归方法一直会调用自己直到某些条件被满足 2. 递归方法会有一些参数,而它会把一些新的参数值传递给自己. 那什么是递归函数?函数和方法没有本质区别,但函数仅在类的内部使用.以前C#中只有方法,从.NET 3.5开始才有了匿名函数. 所以,我们最好叫递归方法,而非递归函数,本文中将统一称之为递归. 在应用程序中为什么要使用递归?何时使用递归?如何

  • C# 使用匿名函数解决EventHandler参数传递的难题

    首先,动态生成PictureBox,很简单, PictureBox box = new PictureBox() ; box.ImageLocation = imageRoad ; 其次,给PictureBox添加右键菜单,也不难, ContextMenu menu = new ContextMenu(); box.ContextMenu = menu ; 然后,要给右键菜单增加"删除"项,并实现删除图片事件.这个,比较麻烦. MenuItem item = new MenuItem(

  • C#采用mouse_event函数实现模拟鼠标功能

    下面我通过代码为大家分享下C#模拟鼠标,具体内容如下: 想必有很多人在项目开发中可能遇见需要做模拟鼠标点击的小功能,很多人会在百度过后采用mouse_event这个函数,不过我并不想讨论如何去使用mouse_event函数怎么去使用,因为那没有多大意义. static void mouse_event(int dwFlags, int dx, int dy, int cButtons, int dwExtraInfo) { int x = dx, y = dy; edit_position(dw

  • 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 {    

  • Android动画之补间动画(Tween Animation)实例详解

    本文实例讲述了Android动画之补间动画.分享给大家供大家参考,具体如下: 前面讲了<Android动画之逐帧动画(Frame Animation)>,今天就来详细讲解一下Tween动画的使用. 同样,在开始实例演示之前,先引用官方文档中的一段话: Tween动画是操作某个控件让其展现出旋转.渐变.移动.缩放的这么一种转换过程,我们称为补间动画.我们可以以XML形式定义动画,也可以编码实现. 如果以XML形式定义一个动画,我们按照动画的定义语法完成XML,并放置于/res/anim目录下,文

  • android 帧动画,补间动画,属性动画的简单总结

    帧动画--FrameAnimation 将一系列图片有序播放,形成动画的效果.其本质是一个Drawable,是一系列图片的集合,本身可以当做一个图片一样使用 在Drawable文件夹下,创建animation-list为根节点的资源文件 <animation-list android:oneshot="false"> <item android:drawable="@drawable/img1" android:duration="100

  • tween.js缓动补间动画算法示例

    一.理解tween.js 如果看到上面的已经理解了,可以跳过下面的部分.下面为对Tween.js的解释 下面就介绍如何使用这个Tween了,首先b.c.d三个参数(即初始值,变化量,持续时间)在缓动开始前,是需要先确定好的. 首先引入一个概念就补间动画 Flash做动画时会用到Tween类,利用它可以做很多动画效果,例如缓动.弹簧等等. tween.js在Flash中可以解释为补间动画. 那么问题来了,什么是补间动画呢? 相信学过Flash的都知道补间动画是flash主要的非常重要的表现手段之一

  • PHP文章采集URL补全函数(FormatUrl)

    写采集必用的函数,URL补全函数,也可叫做FormatUrl. 写此函数作用就是为了开发采集程序,采集文章的时候会经常遇到页面里的路径是 "相对路径" 或者 "绝对根路径" 不是"绝对全路径"就无法收集URL. 所以,就需要本功能函数进行对代码进行格式化,把所有的超链接都格式化一遍,这样就可以直接收集到正确的URL了. 路径知识普及 相对路径:"../" "./" 或者前面什么都不加 绝对根路径:/path

  • Android动画之补间动画(Tween Animation)基础学习

    前言 之前说过了在Android中,动画Animation的实现有两种方式:Tween Animation(渐变动画)和Frame Animation(帧动画).渐变动画是通过对场景里的对象不断做图像变换(平移.缩放.旋转等)产生动画效果.帧动画则是通过顺序播放事先准备好的图像来产生动画效果,和电影类似. 小编也和大家分享了逐帧动画的基础知识,下面我们就来学习下Android中逐帧动画的基础知识. 原理 : 给出开始和结束两个关键帧,两个关键帧之间的插补帧是由计算机自动运算而得到的. 分类 :

  • Android帧动画、补间动画、属性动画用法详解

    在安卓开发中,经常会使用到一些动画,那么在开发中,如何使用这些动画呢? 帧动画:不是针对View做出一些形状上的变化,而是用于播放一张张的图片,例如一些开机动画,类似于电影播放,使用的是AnimationDrawable来播放帧动画 res/drawable <?xml version="1.0" encoding="utf-8"?> <animation-list xmlns:android="http://schemas.androi

  • Android控件Tween动画(补间动画)实现方法示例

    本文实例讲述了Android控件Tween动画(补间动画)实现方法.分享给大家供大家参考,具体如下: Android动画中的Tween动画:是把控件对象不断的进行图像变化来产生旋转.平移.放缩和渐变等动画效果. /** * 控件Tween动画 * * @description: * @author ldm * @date 2016-6-22 下午5:26:24 */ public class TweenActivity extends Activity { private SeekBar see

  • C#自定义字符串补0函数实例

    本文实例讲述了C#自定义字符串补0函数.分享给大家供大家参考.具体分析如下: 这个函数用于在字符串前面进行补0操作,直到字符串达到需要的长度,比如字符串:8476,限定长度为8,则需要在前面补足4个0,结果为:00008476 /// <summary> /// 指定字符串的固定长度,如果字符串小于固定长度, /// 则在字符串的前面补足零,可设置的固定长度最大为9位 /// </summary> /// <param name="text">原始字

  • Android补间动画基本使用(位移、缩放、旋转、透明)

    本文讲述了Android补间动画基本使用(位移.缩放.旋转.透明).分享给大家供大家参考,具体如下: 补间动画 原形态变成新形态时为了过渡变形过程,生成的动画就叫补间动画 位移.旋转.缩放.透明 位移: 参数10指的是X的起点坐标,但不是指屏幕x坐标为10的位置,而是imageview的 真实X + 10 参数150指的是X的终点坐标,它的值是imageview的 真实X + 150 //创建为位移动画对象,设置动画的初始位置和结束位置 TranslateAnimation ta = new T

随机推荐