Sign in to follow this  
Followers 0
TechnoRobbo

TR's KeyFrame v1.2

37 posts in this topic

TechnoRobbo's KeyFrame v1.2

 

an animation assistant for 

Midora's Animated images

http://forums.getpaint.net/index.php?/topic/31629-animated-images/?p=424663

 

 

KeyFrame v1.1 exports frames

 

 

Desert.gif?raw=1

Hidden Content:
// Submenu: Object
// Name: TR's Keyframe
// Title: TR's Keyframe- v1.2
// Author: TechnoRobbo
// URL: http://www.technorobbo.com

#region UICode
Pair<double, double> Amount1 = Pair.Create( 0.0 , 0.0 ); // Start
Pair<double, double> Amount2 = Pair.Create( 0.0 , 0.0 ); // Via Point
Pair<double, double> Amount3 = Pair.Create( 0.0 , 0.0 ); // End
double Amount4 = 0; // [0,1] Time
double Amount5 = 0.75; // [0.1,1.5] Path Shape
bool Amount6 = false; // [0,1] Show Path
int Amount7 = 10; // [1,100] Export count
byte Amount8 = 0; // [255] Export Frames
double Amount9 = 0; // [-2,2] Start Rotation
double Amount10 = 0; // [-2,2] End Rotation
double Amount11 = 1; // [0.01,2] Start Size
double Amount12 = 1; // [0.01,2] End Size
#endregion

byte LastButton=0;
String cboard;

PointF[] spline(PointF p0, PointF p1, PointF p2, float tension)
{
    PointF[] arr = {p0,p1,p2};
    PointF[] PointArray = new PointF[0];
    using (System.Drawing.Drawing2D.GraphicsPath gp = new System.Drawing.Drawing2D.GraphicsPath())
    {
        gp.AddCurve(arr, tension);
        gp.Flatten(null, .01f);
        PointArray = new PointF[gp.PointCount];
        PointArray = gp.PathPoints;
    }
    return PointArray;
}

public void SaveImages()
{
    
     System.Windows.Forms.SaveFileDialog SaveFileDialog1 = new System.Windows.Forms.SaveFileDialog();
     string fp = Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
     SaveFileDialog1.InitialDirectory=fp;
     SaveFileDialog1.Filter = "PNG file (*.png)|*.png"  ;
     SaveFileDialog1.FilterIndex = 1 ;
     SaveFileDialog1.RestoreDirectory = false ;

     if(SaveFileDialog1.ShowDialog() == DialogResult.OK)
     {
        
         cboard = SaveFileDialog1.FileName;
        
     }else{
         cboard = String.Empty;
     }
     
}

void Render(Surface dst, Surface src, Rectangle rect)
{
    if (IsCancelRequested)return;
    SignalCancelRequest();
   
    float hw = (float)src.Width / 2f;
    float hh = (float)src.Height / 2f;
    float timeline = (float)Amount4;
    PointF start= new PointF((float)Amount1.First * hw + hw , (float)Amount1.Second * hh + hh);
    System.Drawing.Point istart= new System.Drawing.Point((int)-start.X,(int)-start.Y);
    PointF via = new PointF((float)Amount2.First * hw + hw , (float)Amount2.Second * hh + hh);
    PointF dest = new PointF((float)Amount3.First * hw + hw , (float)Amount3.Second * hh + hh);
    float idx = 1f / (float)Amount7;
    float rot = (float)Amount10 * timeline + (float)Amount9 - (float)Amount9 * timeline;
    float scale = (float)Amount12 * timeline + (float)Amount11 - (float)Amount11 * timeline;

    PointF[] arr  = spline(start,via,dest,(float)Amount5);
    
    PointF midC = arr[ (int)(timeline * (arr.Length - 1))];
    
    Surface Moved = src.Clone();  
    Surface shift = src.Clone();
    shift.Clear(ColorBgra.Transparent);
    shift.CopySurface(src,new System.Drawing.Point(src.Width / 2 - (int)start.X, src.Height / 2 - (int)start.Y)); 
    
    Moved.Clear(ColorBgra.Transparent);
    dst.Clear(ColorBgra.Transparent);
    
    if (LastButton!=Amount8){
        LastButton=Amount8;
        System.Threading.Thread t = new System.Threading.Thread(new System.Threading.ThreadStart(SaveImages));
        t.SetApartmentState(System.Threading.ApartmentState.STA);
        t.Start();
        t.Join();
        if (cboard != String.Empty)
        {
            int count=0;
            
            for (float i = 0; i<1; i +=idx)
            {
                
                PointF midB = arr[ (int)(i * (arr.Length - 1))];
                rot = (float)Amount10 * i + (float)Amount9 - (float)Amount9 * i;
                scale = (float)Amount12 * i + (float)Amount11 - (float)Amount11 * i;
                Moved.Clear(ColorBgra.Transparent);
                using (Bitmap bmp = new RenderArgs(shift).Bitmap)
                {
                    using(Graphics g = new RenderArgs(Moved).Graphics)
                    {
                        System.Drawing.Imaging.ColorMatrix cm = new System.Drawing.Imaging.ColorMatrix();
                        cm.Matrix33 = 1f;//(Amount6) ? .5f: 1f;
                        System.Drawing.Imaging.ImageAttributes ia = new System.Drawing.Imaging.ImageAttributes();
                        ia.SetColorMatrix(cm, System.Drawing.Imaging.ColorMatrixFlag.Default, System.Drawing.Imaging.ColorAdjustType.Bitmap);
                        RectangleF pa = new RectangleF(0,0,bmp.Size.Width,bmp.Size.Height);
                        g.DrawImage(bmp, rotateimage(midB.X,midB.Y,bmp.Size, scale ,rot),pa,GraphicsUnit.Pixel,ia);
                        ia.Dispose();
                    }
                }
                string dboard = cboard.Replace(".", String.Format("{0}.",count++));
                using (Bitmap tmp =new RenderArgs(Moved).Bitmap )tmp.Save(dboard);
             }
        }
        Moved = src.Clone(); 
    }
    else
    {
        if (Amount6)dst.CopySurface(src);

        using(Graphics g = new RenderArgs(Moved).Graphics)
        {
            using (Bitmap bmp = new RenderArgs(shift).Bitmap)
            {
                
                System.Drawing.Imaging.ColorMatrix cm = new System.Drawing.Imaging.ColorMatrix();
                cm.Matrix33 =(Amount6) ? .5f: 1f;
                System.Drawing.Imaging.ImageAttributes ia = new System.Drawing.Imaging.ImageAttributes();
                ia.SetColorMatrix(cm, System.Drawing.Imaging.ColorMatrixFlag.Default, System.Drawing.Imaging.ColorAdjustType.Bitmap);
                RectangleF pa = new RectangleF(0,0,bmp.Size.Width,bmp.Size.Height);
                g.DrawImage(bmp, rotateimage(midC.X,midC.Y,bmp.Size, scale ,rot),pa,GraphicsUnit.Pixel,ia);
                ia.Dispose();
                if (Amount6)g.DrawCurve(Pens.Red,arr);
            }
        }
    }
    
    
    LastButton=Amount8;

    using (Graphics dg = new RenderArgs(dst).Graphics ) 
    {
        using (Bitmap Dbmp = new RenderArgs(Moved).Bitmap)
        {
            dg.DrawImage(Dbmp ,0f,0f);
        }
 
    }
    Moved.Dispose();
    shift.Dispose();
}

private System.Drawing.PointF[] rotateimage(float x, float y, System.Drawing.Size board,float scale, float rotate)
{
    System.Drawing.PointF[] points = new System.Drawing.PointF[3];
    float rot = rotate * (float)Math.PI;
    float cos = (float)Math.Cos(rot);
    float sin = (float)Math.Sin(rot);
    
    float width = board.Width * scale;
    float height = board.Height * scale;
    float left = width / -2;
    float top =  height / -2;
    float right = width / 2;
    float bottom =  height / 2;  
    points[0] = new System.Drawing.PointF(left *  cos - top * sin + x, top * cos + left * sin + y);
    points[1]= new System.Drawing.PointF(right *  cos - top * sin + x, top * cos + right * sin  + y);
    points[2]= new System.Drawing.PointF(left *  cos - bottom * sin + x, bottom * cos + left * sin  + y);
     
 return points;
} 

TRsKeyFrame.zip

7

Share this post


Link to post
Share on other sites

Great. I guess what we need now is a combined tutorial how to use this in animation.

0

Share this post


Link to post
Share on other sites
Great. I guess what we need now is a combined tutorial how to use this in animation.

 

I agree 

0

Share this post


Link to post
Share on other sites

I figure I'd might as well be the first to try this out. It works fine if you want to do it all within Paint.net.... Nothin' but net.... :lol:

 

ad7KiwB.gif

Edited by racerx
0

Share this post


Link to post
Share on other sites

Nice shot racerx. Training for the NBA?  :D

Edited by Eli
0

Share this post


Link to post
Share on other sites

This works well, but is tedious to create individual frames one at a time. Is there any way you can make it spit out all frames as layers with a push of a button? It clearly works as is, but I would rather create the frames in a video composing  s/w like Aviutl for simplicity sake.. 

0

Share this post


Link to post
Share on other sites

Can be done but due to the limitation of PDN plugins it would export files that would be imported from the Layer menu using "Import from Files" (multiple files can be selected).

1

Share this post


Link to post
Share on other sites

Well that would make it easier, as it would reduce the process to 2 steps instead of multiple steps for each frame. Weather or not people will figure out how to use it is always a question mark. It is a good option to facilitate creating motion frames with an editable curve all within Paint.net. Great job on that... 

1

Share this post


Link to post
Share on other sites

V1.1 ready for download


Exports frames !!!


Thanks to racerX


 


New video coming to show how to use it to create animation


2

Share this post


Link to post
Share on other sites

Perfect video to get all the steps together.

 

My wish: A zoom factor for the start and the end. This would allow to simulate movement from far away to nearby.

0

Share this post


Link to post
Share on other sites

Thanks for the effect and the video TR.

 

I think that there are several assistants that can be created such as: Swivel, Grow and turn, Magnify, Spinner, Faded zoom to name a few.

0

Share this post


Link to post
Share on other sites

 

Perfect video to get all the steps together.

 

My wish: A zoom factor for the start and the end. This would allow to simulate movement from far away to nearby.

My thoughts exactly

 

 

 

Swivel, Grow and turn, Magnify, Spinner, Faded zoom to name a few.

I like the Spin & Fade Idea

0

Share this post


Link to post
Share on other sites

Version 1.2 ready for download


 


It has Grow,Shrink and Rotate 


2

Share this post


Link to post
Share on other sites

TR, is it possible to make this compatible with 3.5.11?

 

I compiled the source code, but when I run the effect I get an error about ranges of valid values. Here's the error I get:

 

 

File: C:\Archivos de programa\Paint.NET\Effects\TR's KeyFrame.dll
      Name: TRsKeyFrameEffect.TRsKeyFrameEffectPlugin
      Version: 1.2.5702.34962
      Author: TechnoRobbo
      Copyright: Copyright © TechnoRobbo
      Website: http://www.technorobbo.com/
      Full error message: System.ArgumentOutOfRangeException: Specified argument was out of the range of valid values.
Parameter name: defaultValue > maxValue
   at PaintDotNet.PropertySystem.ScalarProperty`1..ctor(Object name, T defaultValue, T minValue, T maxValue, Boolean readOnly, ValueValidationFailureResult vvfResult) in D:\src\pdn\pdn_3_5_11\src\Base\PropertySystem\ScalarProperty`1.cs:line 136
   at PaintDotNet.PropertySystem.DoubleProperty..ctor(Object name, Double defaultValue, Double minValue, Double maxValue) in D:\src\pdn\pdn_3_5_11\src\Base\PropertySystem\DoubleProperty.cs:line 27
   at TRsKeyFrameEffect.TRsKeyFrameEffectPlugin.OnCreatePropertyCollection()
   at PaintDotNet.Effects.PropertyBasedEffect.CreateConfigDialog() in D:\src\pdn\pdn_3_5_11\src\Effects\PropertyBasedEffect.cs:line 86
   at PaintDotNet.Menus.EffectMenuBase.RunEffectImpl(Type effectType) in D:\src\pdn\pdn_3_5_11\src\PaintDotNet\Menus\EffectMenuBase.cs:line 799

0

Share this post


Link to post
Share on other sites
I compiled the source code, but when I run the effect I get an error about ranges of valid values. Here's the error I get:

 

Did you change any of the UI values? The error tells me you adjusted a default value manually.

 

try copying the text and make no changes

0

Share this post


Link to post
Share on other sites

Nope, I didn't make any changes at all. I just loaded the source into CodeLab and then I compiled it.

0

Share this post


Link to post
Share on other sites

I think I've found a solution.

 

I changed

double Amount5 = 0.75; // [0.1,1.5] Path Shape

to this:

double Amount5 = 0.1; // [0.1,1.5] Path Shape

and it's running fine, although my range of values for Path Shape are between 1 and 15 instead of 0.1 and 1.5 and I don't know how this affects the path shape in the end scratch_one-s_head.gif

 

Now I remember I've seen this problem before, and I remember someone once told me about it. Not being an expert coder, I tend to forget about these subtle coding issues.

0

Share this post


Link to post
Share on other sites

I must be a dum-dum :D I don't see the download for version 1.2 ?  I downloaded this version of @TR's Key Frame at the beginning of his thread and it doesn't have the Export Frames box in the UI :( .

0

Share this post


Link to post
Share on other sites

 

 I downloaded this version of @TR's Key Frame at the beginning of his thread and it doesn't have the Export Frames box in the UI  :( .

 

Pixey, I Downloaded it and it shows up as 1.2

 

try downloading again 

 

Hover your mouse over th file it should say this 

https://www.dropbox.com/s/c6wbboioq60dlvf/pixeyversion.png?raw=1

0

Share this post


Link to post
Share on other sites

Woot!  It worked after downloading again.  Very odd - but I just downloaded Windows 10 today, so perhaps there was a glitch.  Now to play with this new toy - for which many thanks :D .

0

Share this post


Link to post
Share on other sites

I finally got to play with this new Plugin:

 

X%20gif_zpsbyihuzkj.gif

4

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0