Detect when 'Sony Titles & Text' OFXEffect text is Off-Screen?

ClockBox wrote on 1/22/2023, 9:26 AM

Hi there, been relying on the API and FAQ provided on this forum and VS watching certain values up until now for VEGAS Pro Plugin scripting, but this one I don't think I'm gonna get very far on alone.

I have a script that generates one-line text of a certain font size, the script does not know what text it will put on-screen beforehand, and so sometimes that text goes off-screen to the left and to the right due to how long it is. Is there a way I could retrieve values from the effect to work-around this with a 'while' loop that shrink the text size until the text is small enough to not be going off-screen? The text, of course, has that grey box around it when selected in VEGAS Pro, so clearly VEGAS knows the bounds of the text, it's just a matter of me obtaining that information.

Working in C# btw, but I assume at this point with the other options on offer for plugin development that this is standard in the VEGAS Pro scripting community.

Many thanks for reading!

Comments

jetdv wrote on 1/22/2023, 1:36 PM

VEGAS does not return the actual width used. Plus, there are other factors that could sway the number such as tracking being something other than "0" and scale being set to something other than 1.

However, you can use windows to calculate the "size" of a string graphically. You would use something like:
 

System.Drawing.Bitmap b = new System.Drawing.Bitmap(500, 100, System.Drawing.Imaging.PixelFormat.Format16bppRgb555);
System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(b);

System.Drawing.SizeF sSize = g.MeasureString("my string", QLFont);

sSize would return the width/height needed for a string using the specified font information. I do not know how the size would relate to what you actually see in Titles and Text but it might be a way to get the width.

ClockBox wrote on 1/22/2023, 1:47 PM

VEGAS does not return the actual width used. Plus, there are other factors that could sway the number such as tracking being something other than "0" and scale being set to something other than 1.

However, you can use windows to calculate the "size" of a string graphically. You would use something like:
 

System.Drawing.Bitmap b = new System.Drawing.Bitmap(500, 100, System.Drawing.Imaging.PixelFormat.Format16bppRgb555);
System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(b);

System.Drawing.SizeF sSize = g.MeasureString("my string", QLFont);

sSize would return the width/height needed for a string using the specified font information. I do not know how the size would relate to what you actually see in Titles and Text but it might be a way to get the width.

Yeah, I came across the 'ol 'MeasureString' function during my breakpoint exercises, it's just I've only used C# for Unity outside of VEGAS Pro scripting, and so I didn't know you could create a new bitmap in the way you demonstrated that I could set the dimensions of in code. I think I can make something work out of this, but I'll update regardless. TYVM!

jetdv wrote on 1/22/2023, 2:37 PM

Here's my experimental code. Didn't get me very far. It seems the larger the number of letters, the larger the "offset multiplier" really needs to be. These were done by starting a new project in Vegas, add one video track, and add one Titles and Text to that track. It will pull the text from the box but you have to define the font information separately as that, apparently, is also not pulled FROM VEGAS (but it does send it!).
 

            TrackEvent evnt = myVegas.Project.Tracks[0].Events[0];

            VideoEvent vevnt = (VideoEvent)evnt;
            Effect gEffect = vevnt.ActiveTake.Media.Generator;

            if (gEffect.PlugIn.UniqueID == "{Svfx:com.vegascreativesoftware:titlesandtext}")
            {
                OFXEffect ofx = gEffect.OFXEffect;

                Font myFont = new Font("Verdana", 48, FontStyle.Regular);

                RichTextBox rtfText = new RichTextBox();
                OFXStringParameter tparm = (OFXStringParameter)ofx.FindParameterByName("Text");
                rtfText.Rtf = tparm.Value;


                string s = "Text: " + rtfText.Text;
                s += "\r\nmyFont: " + myFont;
                s += "\r\nFont: " + rtfText.Font;
                s += "\r\nTextLength: " + rtfText.TextLength;

                Graphics g = Graphics.FromHwnd(rtfText.Handle);

                SizeF f = g.MeasureString(rtfText.Text, myFont);
                s += "\r\n\r\nGraphic Size: " + f;

                s += "\r\nCalculated Width: " + (f.Width * 3.8);

                MessageBox.Show(s);
            }

 

ClockBox wrote on 1/22/2023, 2:48 PM

Here's my experimental code. Didn't get me very far. It seems the larger the number of letters, the larger the "offset multiplier" really needs to be. These were done by starting a new project in Vegas, add one video track, and add one Titles and Text to that track. It will pull the text from the box but you have to define the font information separately as that, apparently, is also not pulled FROM VEGAS (but it does send it!).
 

            TrackEvent evnt = myVegas.Project.Tracks[0].Events[0];

            VideoEvent vevnt = (VideoEvent)evnt;
            Effect gEffect = vevnt.ActiveTake.Media.Generator;

            if (gEffect.PlugIn.UniqueID == "{Svfx:com.vegascreativesoftware:titlesandtext}")
            {
                OFXEffect ofx = gEffect.OFXEffect;

                Font myFont = new Font("Verdana", 48, FontStyle.Regular);

                RichTextBox rtfText = new RichTextBox();
                OFXStringParameter tparm = (OFXStringParameter)ofx.FindParameterByName("Text");
                rtfText.Rtf = tparm.Value;


                string s = "Text: " + rtfText.Text;
                s += "\r\nmyFont: " + myFont;
                s += "\r\nFont: " + rtfText.Font;
                s += "\r\nTextLength: " + rtfText.TextLength;

                Graphics g = Graphics.FromHwnd(rtfText.Handle);

                SizeF f = g.MeasureString(rtfText.Text, myFont);
                s += "\r\n\r\nGraphic Size: " + f;

                s += "\r\nCalculated Width: " + (f.Width * 3.8);

                MessageBox.Show(s);
            }

 

You've gone above and beyond to help, I really appreciate it! I didn't get quite as far as you, as I went with your code earlier with creating the dummy Bitmap the same size as my preview window in Sony VEGAS and I simply did a rough 'lets see if this matches up' test by getting the values in the sSize created and then comparing those values to the actual pixel width and height of the text on my screen within that preview window. Unfortunately, I found that whilst I was expecting the width of the pixels in my actual preview window to be within a few pixel units of the with in the sSize width variable, they were pretty massively off, so at that point I was stumped as to how the sSize correlates to the actual pixel size of the text when put on-screen considering the size of the Bitmap was the same as the preview window and should have given round-about the same results for sSize as me making a selection box around the text in a screenshot of the preview window did. A primitive way to test it, I know, but in a practical sense without much else to go on it made sense to me.

Anyway, the script you've provided here is incredibly useful, I suppose all I'd need to do is figure out the multiplier or exponent correlating the offset multiplier to the number of letters in the input string by plotting out some results on a graph. TYSM!

ClockBox wrote on 1/22/2023, 5:43 PM

Here's my experimental code. Didn't get me very far. It seems the larger the number of letters, the larger the "offset multiplier" really needs to be. These were done by starting a new project in Vegas, add one video track, and add one Titles and Text to that track. It will pull the text from the box but you have to define the font information separately as that, apparently, is also not pulled FROM VEGAS (but it does send it!).
 

            TrackEvent evnt = myVegas.Project.Tracks[0].Events[0];

            VideoEvent vevnt = (VideoEvent)evnt;
            Effect gEffect = vevnt.ActiveTake.Media.Generator;

            if (gEffect.PlugIn.UniqueID == "{Svfx:com.vegascreativesoftware:titlesandtext}")
            {
                OFXEffect ofx = gEffect.OFXEffect;

                Font myFont = new Font("Verdana", 48, FontStyle.Regular);

                RichTextBox rtfText = new RichTextBox();
                OFXStringParameter tparm = (OFXStringParameter)ofx.FindParameterByName("Text");
                rtfText.Rtf = tparm.Value;


                string s = "Text: " + rtfText.Text;
                s += "\r\nmyFont: " + myFont;
                s += "\r\nFont: " + rtfText.Font;
                s += "\r\nTextLength: " + rtfText.TextLength;

                Graphics g = Graphics.FromHwnd(rtfText.Handle);

                SizeF f = g.MeasureString(rtfText.Text, myFont);
                s += "\r\n\r\nGraphic Size: " + f;

                s += "\r\nCalculated Width: " + (f.Width * 3.8);

                MessageBox.Show(s);
            }

 

You've gone above and beyond to help, I really appreciate it! I didn't get quite as far as you, as I went with your code earlier with creating the dummy Bitmap the same size as my preview window in Sony VEGAS and I simply did a rough 'lets see if this matches up' test by getting the values in the sSize created and then comparing those values to the actual pixel width and height of the text on my screen within that preview window. Unfortunately, I found that whilst I was expecting the width of the pixels in my actual preview window to be within a few pixel units of the with in the sSize width variable, they were pretty massively off, so at that point I was stumped as to how the sSize correlates to the actual pixel size of the text when put on-screen considering the size of the Bitmap was the same as the preview window and should have given round-about the same results for sSize as me making a selection box around the text in a screenshot of the preview window did. A primitive way to test it, I know, but in a practical sense without much else to go on it made sense to me.

Anyway, the script you've provided here is incredibly useful, I suppose all I'd need to do is figure out the multiplier or exponent correlating the offset multiplier to the number of letters in the input string by plotting out some results on a graph. TYSM!

UPDATE: I took a break then ran some tests. Below you should be able to see a screenshot of an Excel table I set up to determine the correlation between font size and multiplier and what my findings were.

Most columns are self explanatory, but here's the explanation anyhow:
FONT SIZE: Self-Explanatory, set by-hand in code

CHARACTER COUNT: Self-Explanatory, set by-hand in code

WIDTH (VISIBLE_TAKEN): When I set a text generation to have FONT SIZE and CHARACTER COUNT, how many pixels does it take up along the width of a 1080p video? (1920 pixels total width ofc), set by-hand in Excel

WIDTH (GRAPHICS): What is the MeasureString result for FONT SIZE and CHARACTER COUNT?, set by-hand in Excel

MULTIPLIER: What multiplier does it take to get from WIDTH (GRAPHICS) to WIDTH (VISIBLE_TAKEN)?, set automatically with functions in Excel

AVERAGE MULTIPLIER: The average of all multiplier cells, set automatically with functions in Excel

 

I wasn't planning on doing an 'AVERAGE MULTIPLIER' cell because I had assumed that some exponent would be required to figure out the multiplier needed for a combination of CHARACTER COUNT and FONT SIZE and I was going to find this exponent by plotting my results on a line graph and using some old high school maths to figure out the rest, but as it turns out, it seems a decent variety of CHARACTER COUNT and FONT SIZE combinations come out to just about 3.8 as is, as demonstrated by AVERAGE MULTIPLIER.

 

I think for the purposes of my project, just leaving the value as 3.8 should be fine in 9/10 scenarios, so I think I'm satisfied in saying my problem is solved.

jetdv wrote on 1/22/2023, 8:29 PM

Glad I could, at least, get you "close".