💡(Feature Request) Match Output Aspect without rescaling!

Comments

jetdv wrote on 1/18/2023, 12:48 PM

Direct link to the "resizes to original size if smaller than the frame size"

https://www.vegascreativesoftware.info/us/forum/request-match-output-aspect-without-rescaling--139164/?page=3#ca869579

Direct link to the "resizes to fill either the horizontal or vertical no matter the original size"

https://www.vegascreativesoftware.info/us/forum/request-match-output-aspect-without-rescaling--139164/?page=3#ca869594

m3lquixd wrote on 1/18/2023, 1:12 PM

Based on your screen recording, I think you must be from Brazil. It's good to see another Brazilian here on the forum. I am from Brazil too. If not, sorry for the mistake.

@Joelson Sim, sou brasileiro e meu inglês é péssimo. Tudo aqui é passado no Google Tradutor kk

About me:
Hi! Melqui Calheiros Here. I've been using Vegas as my only video editor for over 10 years. I edit professionally for various influencers, public bodies and small businesses. My goal is to squeeze Vegas to the fullest! And end the prejudice that software has here in Brazil.

⬇️ Some of my jobs. ⬇️
https://www.vegascreativesoftware.info/us/forum/post-your-vegas-creations--109464/?page=37#ca872169

PC Specs:
Operating System:
    Windows 11 Pro 64-bit
CPU:
    AMD Ryzen 3 3200G 3.60 GHz
RAM:
    16,0GB Dual-Channel DDR4 2666MHz
Motherboard:
    Gigabyte Technology Co. Ltd. A320M-S2H-CF (AM4)
Graphics:
    4095MB NVIDIA GeForce GTX 1650 (ZOTAC International)
Storage:
    465GB Seagate ST500DM002-1BD142 (SATA )
    238GB Lexar 256GB SSD (SATA (SSD))

m3lquixd wrote on 1/18/2023, 1:15 PM

@jetdv I have a doubt. There were 5 versions of the script. The 5th being the most different. What is the difference between the 2nd, 3th and 4th script? Because you scored the 3th and not the 2nd. So I was curious to know the difference.

Last changed by m3lquixd on 1/18/2023, 1:40 PM, changed a total of 3 times.

About me:
Hi! Melqui Calheiros Here. I've been using Vegas as my only video editor for over 10 years. I edit professionally for various influencers, public bodies and small businesses. My goal is to squeeze Vegas to the fullest! And end the prejudice that software has here in Brazil.

⬇️ Some of my jobs. ⬇️
https://www.vegascreativesoftware.info/us/forum/post-your-vegas-creations--109464/?page=37#ca872169

PC Specs:
Operating System:
    Windows 11 Pro 64-bit
CPU:
    AMD Ryzen 3 3200G 3.60 GHz
RAM:
    16,0GB Dual-Channel DDR4 2666MHz
Motherboard:
    Gigabyte Technology Co. Ltd. A320M-S2H-CF (AM4)
Graphics:
    4095MB NVIDIA GeForce GTX 1650 (ZOTAC International)
Storage:
    465GB Seagate ST500DM002-1BD142 (SATA )
    238GB Lexar 256GB SSD (SATA (SSD))

jetdv wrote on 1/18/2023, 1:32 PM

Each one was building on the previous one fixing issues you found.

The 1st version worked fine for images larger than the frame size and resized logos back to original size but did not support rotated images.

The 2nd version checked the image rotation in the media settings and worked correctly with images rotated 90 degrees on the VEGAS timeline.

The 3rd version is actually correct in that it properly resizes items larger than the frame to the frame size and resizes items smaller than the frame size to be their original size within the frame which is actually what I thought you originally wanted.

The 4th version started adding in support for wider images to get them to properly fit but did not work correctly if one aspect was larger than the frame size and the other one was smaller.

The 5th version is correct for your usage - it properly resizes items larger than the frame to be the frame size and resizes items smaller than the frame size to still be full frame size and takes into account that an image may be larger one way but smaller the other.

Guess I could delete the code out of the three "bad" posts.

m3lquixd wrote on 1/18/2023, 1:43 PM

@jetdv 2 and 3 look the same to me. lol

About me:
Hi! Melqui Calheiros Here. I've been using Vegas as my only video editor for over 10 years. I edit professionally for various influencers, public bodies and small businesses. My goal is to squeeze Vegas to the fullest! And end the prejudice that software has here in Brazil.

⬇️ Some of my jobs. ⬇️
https://www.vegascreativesoftware.info/us/forum/post-your-vegas-creations--109464/?page=37#ca872169

PC Specs:
Operating System:
    Windows 11 Pro 64-bit
CPU:
    AMD Ryzen 3 3200G 3.60 GHz
RAM:
    16,0GB Dual-Channel DDR4 2666MHz
Motherboard:
    Gigabyte Technology Co. Ltd. A320M-S2H-CF (AM4)
Graphics:
    4095MB NVIDIA GeForce GTX 1650 (ZOTAC International)
Storage:
    465GB Seagate ST500DM002-1BD142 (SATA )
    238GB Lexar 256GB SSD (SATA (SSD))

jetdv wrote on 1/18/2023, 2:13 PM

version 2 has this:

float pwid = 0.0F;

if (dFullHeight > scrHeight)
{
    pwid = dFullHeight / dHeight * 100;
}
else
{
    pwid = dHeight / scrHeight * 100;
}

ScaleKeyframe(thisKeyframe, pwid, 0);

version 3 has this:

float pwid = 0.0F;
float wpwid = 0.0F;

if (dFullHeight > scrHeight)
{
    pwid = dFullHeight / dHeight * 100;
}
else
{
    pwid = dHeight / scrHeight * 100;
}

if (dFullWidth > scrWidth)
{
    wpwid = dFullWidth / dWidth * 100;
}
if (wpwid > pwid)
{
    pwid = wpwid;
}

ScaleKeyframe(thisKeyframe, pwid, 0);

That's the only section that changed between the two versions and is, in fact, the main area that changed between all of the versions with the exception of adding in the rotation check in version 2. This is the section that determines how far in/out Pan/Crop needs to zoom to get the image the full width (or, original size, as the first versions were doing.)

m3lquixd wrote on 1/18/2023, 2:14 PM

Nice!

About me:
Hi! Melqui Calheiros Here. I've been using Vegas as my only video editor for over 10 years. I edit professionally for various influencers, public bodies and small businesses. My goal is to squeeze Vegas to the fullest! And end the prejudice that software has here in Brazil.

⬇️ Some of my jobs. ⬇️
https://www.vegascreativesoftware.info/us/forum/post-your-vegas-creations--109464/?page=37#ca872169

PC Specs:
Operating System:
    Windows 11 Pro 64-bit
CPU:
    AMD Ryzen 3 3200G 3.60 GHz
RAM:
    16,0GB Dual-Channel DDR4 2666MHz
Motherboard:
    Gigabyte Technology Co. Ltd. A320M-S2H-CF (AM4)
Graphics:
    4095MB NVIDIA GeForce GTX 1650 (ZOTAC International)
Storage:
    465GB Seagate ST500DM002-1BD142 (SATA )
    238GB Lexar 256GB SSD (SATA (SSD))

jetdv wrote on 3/12/2023, 7:31 AM

It has been pointed out that this script will crash if an audio event is selected. Here's an updated version that verifies the track is a video track before going through the events.
 

using System;
using System.Collections.Generic;
using System.Collections;
using System.IO;
using System.Text;
using System.Windows.Forms;
using System.Globalization;
using System.Drawing;
using System.Runtime;
using System.Xml;
using ScriptPortal.Vegas;

namespace Test_Script
{
    public class Class1
    {
        public Vegas myVegas;

        public void Main(Vegas vegas)
        {
            myVegas = vegas;

            float scrWidth = myVegas.Project.Video.Width;
            float scrHeight = myVegas.Project.Video.Height;

            foreach (Track myTrack in myVegas.Project.Tracks)
            {
                if (myTrack.IsVideo())
                {
                    foreach (VideoEvent evnt in myTrack.Events)
                    {
                        if (evnt.Selected)
                        {
                            MatchAspect(evnt);

                            VideoEvent videoEvent = evnt as VideoEvent;
                            VideoMotionKeyframes keyframes = videoEvent.VideoMotion.Keyframes;
                            int cKeyframes = keyframes.Count;
                            for (int jj = cKeyframes - 1; jj >= 0; jj--)
                            {
                                VideoMotionKeyframe thisKeyframe = keyframes[jj] as VideoMotionKeyframe;

                                float dWidth = Math.Abs(thisKeyframe.TopRight.X - thisKeyframe.TopLeft.X);
                                float dHeight = Math.Abs(thisKeyframe.BottomLeft.Y - thisKeyframe.TopLeft.Y); ;

                                MediaStream mediaStream = GetActiveMediaStream(videoEvent);
                                VideoStream videoStream = mediaStream as VideoStream;
                                VideoOutputRotation vRotation = videoStream.Rotation;

                                float dFullHeight = videoStream.Height;
                                float dFullWidth = videoStream.Width;
                                if ((vRotation == VideoOutputRotation.QuarterTurnClockwise) || (vRotation == VideoOutputRotation.QuarterTurnCounterclockwise))
                                {
                                    dFullHeight = videoStream.Width;
                                    dFullWidth = videoStream.Height;
                                }

                                float pwid = 0.0F;
                                float wpwid = 0.0F;
                                bool smaller = false;

                                if (dFullHeight > scrHeight)
                                {
                                    pwid = dFullHeight / dHeight * 100;
                                }
                                else
                                {
                                    pwid = dHeight / dFullHeight * 100;
                                    smaller = true;
                                }

                                if (dFullWidth > scrWidth)
                                {
                                    smaller = false;
                                    wpwid = dFullWidth / dWidth * 100;
                                }
                                else
                                {
                                    wpwid = dWidth / dFullWidth * 100;
                                }

                                if (wpwid > pwid && !smaller)
                                {
                                    pwid = wpwid;
                                }
                                if (wpwid < pwid && smaller)
                                {
                                    pwid = wpwid;
                                }

                                ScaleKeyframe(thisKeyframe, pwid, 0);
                            }
                        }
                    }
                }
            }
        }

        public void MatchAspect(TrackEvent trackEvent)
        {
            float dWidthProject = myVegas.Project.Video.Width;
            float dHeightProject = myVegas.Project.Video.Height;
            double dPixelAspect = myVegas.Project.Video.PixelAspectRatio;
            double dAspect = dPixelAspect * dWidthProject / dHeightProject;

            MediaStream mediaStream = GetActiveMediaStream(trackEvent);
            if (!(mediaStream == null))
            {
                VideoStream videoStream = mediaStream as VideoStream;

                double dMediaPixelAspect = videoStream.PixelAspectRatio;
                VideoEvent videoEvent = trackEvent as VideoEvent;
                VideoMotionKeyframes keyframes = videoEvent.VideoMotion.Keyframes; ;

                int cKeyframes = keyframes.Count;

                for (int jj = cKeyframes - 1; jj >= 0; jj--)
                {
                    VideoMotionKeyframe thisKeyframe = keyframes[jj] as VideoMotionKeyframe;
                    MatchOutputAspect(thisKeyframe, dMediaPixelAspect, dAspect);
                }
            }
            myVegas.UpdateUI();
        }

        public MediaStream GetActiveMediaStream(TrackEvent trackEvent)
        {
            try
            {
                if (!(trackEvent.ActiveTake.IsValid()))
                {
                    throw new ArgumentException("empty or invalid take");
                }

                Media media = myVegas.Project.MediaPool.Find(trackEvent.ActiveTake.MediaPath);
                if (null == media)
                {
                    MessageBox.Show("missing media");
                    throw new ArgumentException("missing media");
                }

                MediaStream mediaStream = media.Streams.GetItemByMediaType(MediaType.Video, trackEvent.ActiveTake.StreamIndex);
                return mediaStream;
            }
            catch (Exception e)
            {
                MessageBox.Show("{0}", e.Message);
                return null;
            }
        }


        public void MatchOutputAspect(VideoMotionKeyframe keyframe, double dMediaPixelAspect, double dAspectOut)
        {
            VideoMotionKeyframe keyframeSave = keyframe;

            try
            {
                double rotation = keyframe.Rotation;
                keyframe.RotateBy(-rotation);

                float dWidth = Math.Abs(keyframe.TopRight.X - keyframe.TopLeft.X);
                float dHeight = Math.Abs(keyframe.BottomLeft.Y - keyframe.TopLeft.Y);
                double dCurrentAspect = dMediaPixelAspect * dWidth / dHeight;
                float centerY = keyframe.Center.Y;
                float centerX = keyframe.Center.X;
                double dFactor;

                VideoMotionBounds bounds = new VideoMotionBounds(keyframe.TopLeft, keyframe.TopRight, keyframe.BottomRight, keyframe.BottomLeft);
                if (dCurrentAspect < dAspectOut)
                {
                    // alter y coords            
                    dFactor = dCurrentAspect / dAspectOut;

                    bounds.TopLeft.Y = (bounds.TopLeft.Y - centerY) * (float)dFactor + centerY;
                    bounds.TopRight.Y = (bounds.TopRight.Y - centerY) * (float)dFactor + centerY;
                    bounds.BottomLeft.Y = (bounds.BottomLeft.Y - centerY) * (float)dFactor + centerY;
                    bounds.BottomRight.Y = (bounds.BottomRight.Y - centerY) * (float)dFactor + centerY;
                }
                else
                {
                    // alter x coords
                    dFactor = dAspectOut / dCurrentAspect;

                    bounds.TopLeft.X = (bounds.TopLeft.X - centerX) * (float)dFactor + centerX;
                    bounds.TopRight.X = (bounds.TopRight.X - centerX) * (float)dFactor + centerX;
                    bounds.BottomLeft.X = (bounds.BottomLeft.X - centerX) * (float)dFactor + centerX;
                    bounds.BottomRight.X = (bounds.BottomRight.X - centerX) * (float)dFactor + centerX;
                }

                // set it to new bounds
                keyframe.Bounds = bounds;

                // restore rotation.        
                keyframe.RotateBy(rotation);
            }
            catch
            {
                // restore original settings on error
                keyframe = keyframeSave;
            }
        }

        public void ScaleKeyframe(VideoMotionKeyframe keyframe, float szChange, float rotAngle)
        {
            float cWidth = (1 / (szChange / 100));
            float cHeight = (1 / (szChange / 100));

            if (szChange > 100)
            {
                cWidth = (szChange / 100);
                cHeight = (szChange / 100);
            }

            VideoMotionVertex bounds = new VideoMotionVertex(cWidth, cHeight);

            keyframe.ScaleBy(bounds);
            keyframe.RotateBy((rotAngle * (Math.PI / 180)));
        }

    }
}

public class EntryPoint
{
    public void FromVegas(Vegas vegas)
    {
        Test_Script.Class1 test = new Test_Script.Class1();
        test.Main(vegas);
    }
}

 

m3lquixd wrote on 3/12/2023, 12:52 PM

@jetdv I had noticed that when we applied the script to an event that contains a grouped audio, it showed a message on the screen, but the script worked even with this message appearing, so I didn't care about that.
But, I noticed a problem with the script. I don't know if it's possible to fix it.
When we apply the script twice to an event, it tries to adjust the pan crop again, "ruining" the adjustment it had made the first time.

It happens in media where one of the dimensions is larger than the project, it can be vertically or horizontally. If it's a square object with all dimensions the same size, this problem won't occur. It doesn't matter if it's bigger or smaller than the project.

Link to download the images used.

PS. I don't know if this can be resolved. If it's not possible, no problem. It's just us to avoid running the script twice in the same event unintentionally.

About me:
Hi! Melqui Calheiros Here. I've been using Vegas as my only video editor for over 10 years. I edit professionally for various influencers, public bodies and small businesses. My goal is to squeeze Vegas to the fullest! And end the prejudice that software has here in Brazil.

⬇️ Some of my jobs. ⬇️
https://www.vegascreativesoftware.info/us/forum/post-your-vegas-creations--109464/?page=37#ca872169

PC Specs:
Operating System:
    Windows 11 Pro 64-bit
CPU:
    AMD Ryzen 3 3200G 3.60 GHz
RAM:
    16,0GB Dual-Channel DDR4 2666MHz
Motherboard:
    Gigabyte Technology Co. Ltd. A320M-S2H-CF (AM4)
Graphics:
    4095MB NVIDIA GeForce GTX 1650 (ZOTAC International)
Storage:
    465GB Seagate ST500DM002-1BD142 (SATA )
    238GB Lexar 256GB SSD (SATA (SSD))