Jump to content
How to Install Plugins ×

TR's KeyFrame v1.2


TechnoRobbo

Recommended Posts

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

  • Upvote 6

Go out there and be amazing. Have Fun, TR
TRsSig.png?raw=1
Some Pretty Pictures Some Cool Plugins

Link to comment
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

Plane_Sig2.gif

Link to comment
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.. 

Plane_Sig2.gif

Link to comment
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... 

  • Upvote 1

Plane_Sig2.gif

Link to comment
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.

midoras signature.gif

Link to comment
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.

Link to comment
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

Go out there and be amazing. Have Fun, TR
TRsSig.png?raw=1
Some Pretty Pictures Some Cool Plugins

Link to comment
Share on other sites

  • 2 weeks later...

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

Link to comment
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

Go out there and be amazing. Have Fun, TR
TRsSig.png?raw=1
Some Pretty Pictures Some Cool Plugins

Link to comment
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.

Edited by Maximilian
Link to comment
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 :( .

30b8T8B.gif

How I made Jennifer & Halle in Paint.net

My Gallery | My Deviant Art

"Rescuing one animal may not change the world, but for that animal their world is changed forever!" anon.

 
Link to comment
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

Go out there and be amazing. Have Fun, TR
TRsSig.png?raw=1
Some Pretty Pictures Some Cool Plugins

Link to comment
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 .

30b8T8B.gif

How I made Jennifer & Halle in Paint.net

My Gallery | My Deviant Art

"Rescuing one animal may not change the world, but for that animal their world is changed forever!" anon.

 
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...