💡(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.

@Vegas_Pro_Brasil 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:
    32,0GB Dual-Channel DDR4 2666MHz
Motherboard:
    BIOSTAR Group B450MX-S (AM4)
Graphics:
    4095MB NVIDIA GeForce GTX 1650 (ZOTAC International)
Storage:
    465GB Seagate ST500DM002-1BD142 (SATA )
    238GB Lexar 256GB SSD (SATA (SSD))
  931GB KINGSTON SNV2S1000G (SATA-2 (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:
    32,0GB Dual-Channel DDR4 2666MHz
Motherboard:
    BIOSTAR Group B450MX-S (AM4)
Graphics:
    4095MB NVIDIA GeForce GTX 1650 (ZOTAC International)
Storage:
    465GB Seagate ST500DM002-1BD142 (SATA )
    238GB Lexar 256GB SSD (SATA (SSD))
  931GB KINGSTON SNV2S1000G (SATA-2 (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:
    32,0GB Dual-Channel DDR4 2666MHz
Motherboard:
    BIOSTAR Group B450MX-S (AM4)
Graphics:
    4095MB NVIDIA GeForce GTX 1650 (ZOTAC International)
Storage:
    465GB Seagate ST500DM002-1BD142 (SATA )
    238GB Lexar 256GB SSD (SATA (SSD))
  931GB KINGSTON SNV2S1000G (SATA-2 (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:
    32,0GB Dual-Channel DDR4 2666MHz
Motherboard:
    BIOSTAR Group B450MX-S (AM4)
Graphics:
    4095MB NVIDIA GeForce GTX 1650 (ZOTAC International)
Storage:
    465GB Seagate ST500DM002-1BD142 (SATA )
    238GB Lexar 256GB SSD (SATA (SSD))
  931GB KINGSTON SNV2S1000G (SATA-2 (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:
    32,0GB Dual-Channel DDR4 2666MHz
Motherboard:
    BIOSTAR Group B450MX-S (AM4)
Graphics:
    4095MB NVIDIA GeForce GTX 1650 (ZOTAC International)
Storage:
    465GB Seagate ST500DM002-1BD142 (SATA )
    238GB Lexar 256GB SSD (SATA (SSD))
  931GB KINGSTON SNV2S1000G (SATA-2 (SSD))

Former user wrote on 12/4/2023, 1:00 PM

@jetdv Hi, I've been trying to find a script that does the same as Match Output Aspect in Pan/Crop. I've watched a few of your videos & to be honest I get a bit lost, at the moment they're way beyond me 🥴🤣

The image in this vid is smaller then the project, as sometimes videos are but bigger or smaller Match Output Aspect in Pan/Crop 'trims' the black bars off 👍

I already have Logo Resize script, on small images it makes them the correct size in the preview 👍

I've tried a couple of other scripts without success, (they were old ones)

This is the script directly above @m3lquixd last comment ↑, This what i want to happen -

 

m3lquixd wrote on 12/4/2023, 7:39 PM

@Former user Natively in Vegas, there is already a script that does this.

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:
    32,0GB Dual-Channel DDR4 2666MHz
Motherboard:
    BIOSTAR Group B450MX-S (AM4)
Graphics:
    4095MB NVIDIA GeForce GTX 1650 (ZOTAC International)
Storage:
    465GB Seagate ST500DM002-1BD142 (SATA )
    238GB Lexar 256GB SSD (SATA (SSD))
  931GB KINGSTON SNV2S1000G (SATA-2 (SSD))

Former user wrote on 12/4/2023, 8:39 PM

@m3lquixd Excellent, thankyou, renamed it & gave it M for Match 😁

Former user wrote on 12/5/2023, 12:22 AM

@lan-mLMC That one above 5 comments up does if I'm reading your comment correctly, this is what it does to a big picture

Here's a 2160x2160 clip on a 1920x1080 project with that script applied

m3lquixd wrote on 12/5/2023, 8:23 AM

@lan-mLMC The idea is that you don't apply it more than once, it will work perfectly​​​​​​​

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:
    32,0GB Dual-Channel DDR4 2666MHz
Motherboard:
    BIOSTAR Group B450MX-S (AM4)
Graphics:
    4095MB NVIDIA GeForce GTX 1650 (ZOTAC International)
Storage:
    465GB Seagate ST500DM002-1BD142 (SATA )
    238GB Lexar 256GB SSD (SATA (SSD))
  931GB KINGSTON SNV2S1000G (SATA-2 (SSD))

m3lquixd wrote on 12/5/2023, 8:27 AM

@jetdv I was thinking here, is it possible to fix this bug of running the script more than once, making the script identify if the pan/crop has been changed? if it was changed it doesn't execute the script, something like that. is it possible?

Vegas itself has an indication when the pan/crop has been changed.
​​​​​​​

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:
    32,0GB Dual-Channel DDR4 2666MHz
Motherboard:
    BIOSTAR Group B450MX-S (AM4)
Graphics:
    4095MB NVIDIA GeForce GTX 1650 (ZOTAC International)
Storage:
    465GB Seagate ST500DM002-1BD142 (SATA )
    238GB Lexar 256GB SSD (SATA (SSD))
  931GB KINGSTON SNV2S1000G (SATA-2 (SSD))

jetdv wrote on 12/5/2023, 1:22 PM

@m3lquixd, I'll need to have the time to look at the script. I'll look at it but it may take a little time. It's a really busy season right now...

But, yes, it's not impossible to "ignore" it if Pan/Crop has already been used. For example:

 

m3lquixd wrote on 12/5/2023, 2:01 PM

@jetdvThat's right, we'll see that next year!​​​​​​​

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:
    32,0GB Dual-Channel DDR4 2666MHz
Motherboard:
    BIOSTAR Group B450MX-S (AM4)
Graphics:
    4095MB NVIDIA GeForce GTX 1650 (ZOTAC International)
Storage:
    465GB Seagate ST500DM002-1BD142 (SATA )
    238GB Lexar 256GB SSD (SATA (SSD))
  931GB KINGSTON SNV2S1000G (SATA-2 (SSD))

jetdv wrote on 12/6/2023, 12:39 PM

@m3lquixd I need a way to duplicate this. All the footage/images I've tried adjusted on the first run and did not change on the second run.

jetdv wrote on 12/6/2023, 2:07 PM

@m3lquixd, @Former user Ok, the issue is if it's "wider" than the screen. We added in this code to "compensate" and return the left and right edges of the Pan/Crop back to the left and right edges of the media which returns the black bars on the top and bottom:
 

                            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;
                                    MessageBox.Show("1 " + pwid);
                                }
                                else
                                {
                                    pwid = dHeight / dFullHeight * 100;
                                    smaller = true;
                                    MessageBox.Show("2 " + pwid);
                                }

                                if (dFullWidth > scrWidth)
                                {
                                    smaller = false;
                                    wpwid = dFullWidth / dWidth * 100;
                                    MessageBox.Show("3 " + wpwid);
                                }
                                else
                                {
                                    wpwid = dWidth / dFullWidth * 100;
                                    MessageBox.Show("4 " + wpwid);
                                }

                                if (wpwid > pwid && !smaller)
                                {
                                    pwid = wpwid;
                                    MessageBox.Show("5 " + pwid);
                                }
                                if (wpwid < pwid && smaller)
                                {
                                    pwid = wpwid;
                                    MessageBox.Show("6 " + pwid);
                                }
                                MessageBox.Show("PWID = " + pwid);
                                ScaleKeyframe(thisKeyframe, pwid, 0);
                            }

When this is run the second time, it's still "compensating" to restore to the original size in relation to the black bars on the top and bottom.

Technically, we can remove all of the above code and it will work like VEGAS does. Right-click the Pan/Crop window and choose Match Output Aspect and the left/right edges will be pulled in. So, the solution seems to be to check if either "Pan/Crop" width/height is less than the media width/height and, if yes, readjust. So we do the above section IF:

if (dFullWidth > dWidth || dFullHeight > dHeight)

Try this version:
 

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

                                if (dFullWidth > dWidth || dFullHeight > dHeight)
                                {
                                    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 12/6/2023, 2:46 PM

Tested and approved! 😀

This problem happens with this script too
https://www.vegascreativesoftware.info/us/forum/request-match-output-aspect-without-rescaling--139164/?page=3#ca869579

It would be good if you fixed it too

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:
    32,0GB Dual-Channel DDR4 2666MHz
Motherboard:
    BIOSTAR Group B450MX-S (AM4)
Graphics:
    4095MB NVIDIA GeForce GTX 1650 (ZOTAC International)
Storage:
    465GB Seagate ST500DM002-1BD142 (SATA )
    238GB Lexar 256GB SSD (SATA (SSD))
  931GB KINGSTON SNV2S1000G (SATA-2 (SSD))

jetdv wrote on 12/6/2023, 2:55 PM

@m3lquixd This one *IS* the update for that script. It's the same script!

m3lquixd wrote on 12/6/2023, 3:09 PM

No, you updated the match output aspect without resizing. And remember that you made 2 scripts in this post. I sent you the other one now, which reduces the size of the image to its original size compared to the project.

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

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:
    32,0GB Dual-Channel DDR4 2666MHz
Motherboard:
    BIOSTAR Group B450MX-S (AM4)
Graphics:
    4095MB NVIDIA GeForce GTX 1650 (ZOTAC International)
Storage:
    465GB Seagate ST500DM002-1BD142 (SATA )
    238GB Lexar 256GB SSD (SATA (SSD))
  931GB KINGSTON SNV2S1000G (SATA-2 (SSD))