Welcome to Doom9's Forum, THE in-place to be for everyone interested in DVD conversion.

Before you start posting please read the forum rules. By posting to this forum you agree to abide by the rules.

 

Go Back   Doom9's Forum > Capturing and Editing Video > VapourSynth

Reply
 
Thread Tools Search this Thread Display Modes
Old 11th August 2023, 05:31   #1  |  Link
hello_hello
Registered User
 
Join Date: Mar 2011
Posts: 5,017
Specifying color (for borders or a blank clip)

For anyone who might want it, here's the latest version of the function discussed in this thread (for specifying color in an Avisynth-like manner).
I've removed all the old links from the thread (as some pointed to an incomplete version) and changed the function name to RGBColor.


Even though the default color is "black" for VapourSynth's AddBorders & BlankClip functions, the added borders are always full range (for 8 bit video the black level is 0 rather than 16 as it should be for limited range video). The RGBColor function will ensure the black level is correct. YUV and RGB are both supported at any bitdepth (except for half float).

Changes for RGBColor version 2024-10-02:

- I hadn't realised the VapourSynth _ColorRange frame property uses 0 for full range and 1 for limited, while the resizers use 0 for limited and 1 for full, so the color range is now specified correctly when RGBColor creates the blank clip it uses for determining the color.
- The previous versions required the user to specify a color. This version defaults to "black".
- "lightgray" wasn't included as a color, only "lightgrey". Both are now included (as the same color).

RGBColor 2025-03-25.zip

There's a help file included.

import vapoursynth as vs
core = vs.core
import RGBColor as rgb

Specifying a border color for the AddBorders function

Adding black borders

clip = core.ffms2.Source("Video.mkv")
clip = core.std.AddBorders(clip, 20,20,0,0, color=rgb.RGBColor(clip))

Adding dark blue borders

clip = core.ffms2.Source("Video.mkv")
clip = core.std.AddBorders(clip, 20,20,0,0, color=rgb.RGBColor(clip, color="darkblue"))

Specifying the color of a blank clip with the same properties as a previous clip

A blank clip with black frames

clip = core.ffms2.Source("Video.mkv")
BClip = core.std.BlankClip(clip, color=rgb.RGBColor(clip))

A blank clip with red frames

clip = core.ffms2.Source("Video.mkv")
BClip = core.std.BlankClip(clip, color=rgb.RGBColor(clip, color="red"))

Specifying the color of a blank clip when no previous clip exists

A blank clip with black frames

BClip = core.std.BlankClip(format=vs.YUV420P8)
BClip = core.std.BlankClip(BClip, color=rgb.RGBColor(BClip))

A blank clip with red frames

BClip = core.std.BlankClip(format=vs.YUV420P8)
BClip = core.std.BlankClip(BClip, color=rgb.RGBColor(BClip, color="red"))

Last edited by hello_hello; 27th March 2025 at 13:39.
hello_hello is offline   Reply With Quote
Old 11th August 2023, 07:32   #2  |  Link
_Al_
Registered User
 
Join Date: May 2011
Posts: 372
something similar to colors_rgb.avsi not sure, but for data like that python can use dictionaries, enums or dataclasses to give values to named objects, so you just create one of those.

To change these data from that colors_rgb.avsi to python's dictionary is in a code below.
Then getting a color from a string:
yellow = colors["yellow"]
So yellow is color for RGB24 (8bit).

To automatize that and get color based on your used clip's format, bitdepth and matrix you can use custom made function that changes color based on clips properties:
Code:
import vapoursynth as vs
from vapoursynth import core

clip = core.ffms2.Source(r'video.mp4') 
colors = {
           "color_aliceblue"    :  (240, 248, 255),
           "color_antiquewhite" :  (250, 235, 215),
           "color_aqua"         :  (0, 255, 255),
            #etc.
           "yellow"             :  (255, 255, 0),
          }

def get_clip_color(clip, rgb_color: tuple=None, string_color: str=None):
    """
    pass rgb_color (8bit tuple) or string_color 
    """
    if rgb_color is None:
        color = colors[string_color]
    else:
        color = rgb_color
    blank_rgb = core.std.BlankClip(color=color)    

    matrix_prop = clip.get_frame(0).props.get("_Matrix", None)
    if matrix_prop in [0,2,3]:   matrix_prop = None
    matrix_size = None
    if not clip.format.color_family==vs.RGB:
        if clip.height <= 576:   matrix_size = 5 #470bg or 170m
        elif clip.height < 1090: matrix_size = 1 #709
        else:                    matrix_size = 9 #2020ncl
    my_color_clip = blank_rgb.resize.Point(format=clip.format.id, matrix=matrix_prop or matrix_size)
    #getting color values from 0,0 pixel
    p0, p1, p2 = (None, None, None)
    f = my_color_clip.get_frame(0)
    planes =[f[i] for i in range(f.format.num_planes)]
    p0 = planes[0][0,0]
    try:    p1 = planes[1][0,0]
    except IndexError: pass
    try:    p2 = planes[2][0,0]
    except IndexError: pass
    return (p0,p1,p2) if p1 is not None else p0

color = get_clip_color(clip, string_color="yellow")
#color = get_clip_color(clip, rgb_color=(255, 255, 0))
print(color)

Last edited by _Al_; 11th August 2023 at 08:08.
_Al_ is offline   Reply With Quote
Old 11th August 2023, 08:03   #3  |  Link
_Al_
Registered User
 
Join Date: May 2011
Posts: 372
or those dictionaries could be left with those hex strings and let code to change it to rgb tuple:
Code:
def hex_to_rgb(hex):
  return tuple(int(hex[i:i+2], 16) for i in (0, 2, 4))

hexstring = "FFFF00"
rgb_color = hex_to_rgb(hexstring)) # (255, 255, 0)
_Al_ is offline   Reply With Quote
Old 11th August 2023, 08:47   #4  |  Link
hello_hello
Registered User
 
Join Date: Mar 2011
Posts: 5,017
I couldn't get RGB values to work correctly for YUV, which is why my example contains YUV values too, but maybe I was doing something silly.

Thanks for the info. I've been on the computer all day and my brain has just about shut down, so I'll return tomorrow when I can take it in.

Cheers.
hello_hello is offline   Reply With Quote
Old 24th August 2023, 16:26   #5  |  Link
hello_hello
Registered User
 
Join Date: Mar 2011
Posts: 5,017
I'm on my way to a colors_rgb type function for Vapoursynth. It's working perfectly if the video is RGB, but not so much for YUV.

Any suggestions welcome. I'm still very new to Python-speak.
<link removed>

To specify a border color for AddBorders (RGB clip) (should be okay for any bitdepth).

Code:
import vapoursynth as vs
vc = vs.core
import colors

clip = <SomethingRGB>
BorderColor = colors.RGBColor(clip, color='aqua')
clip = clip.std.AddBorders(32,32,32,32, color=BorderColor)
To specify the color of a new BlankClip (RGB).

Code:
import vapoursynth as vs
vc = vs.core
import colors

clip = vc.std.BlankClip(format=vs.RGBS)
ClipColor = colors.RGBColor(clip, color='aqua')
clip = vc.std.BlankClip(clip, color=ClipColor)
So now I have to work out how to convert the RGB values to YUV, using the correct matrix I suppose, and I'll need someone to explain how to scale YUV values for float. When I used YUV values for a YUV clip they scaled as I expected for integer bit depths, but not for float.

Last edited by hello_hello; 2nd October 2023 at 19:22.
hello_hello is offline   Reply With Quote
Old 24th August 2023, 16:29   #6  |  Link
hello_hello
Registered User
 
Join Date: Mar 2011
Posts: 5,017
Quote:
Originally Posted by _Al_ View Post
or those dictionaries could be left with those hex strings and let code to change it to rgb tuple:
Code:
def hex_to_rgb(hex):
  return tuple(int(hex[i:i+2], 16) for i in (0, 2, 4))

hexstring = "FFFF00"
rgb_color = hex_to_rgb(hexstring)) # (255, 255, 0)
If I'd seen your post I would have done it that way, but unfortunately I didn't see it until just now, so I guess I converted the hex values to RGB the hard way. I'm still very new to dealing with tuples (although is the way I did it considered a tuple?).

PS. Is the matrix a factor when adding borders to an RGB clip or just YUV? I'm still trying to get my head around your original function.

Thanks.

Last edited by hello_hello; 24th August 2023 at 17:06.
hello_hello is offline   Reply With Quote
Old 24th August 2023, 18:32   #7  |  Link
hello_hello
Registered User
 
Join Date: Mar 2011
Posts: 5,017
_Al_ ,

I used your method above instead of the way I was originally doing it, so now the color can be specified either way, similar to Avisynth.

Still only works for RGB.
<link removed>

BColor = colors.RGBColor(clip, 'FFFF00')
or
BColor = colors.RGBColor(clip, 'yellow')

clip = clip.std.AddBorders(32,32,32,32, color=BColor)

Last edited by hello_hello; 26th August 2023 at 19:05.
hello_hello is offline   Reply With Quote
Old 24th August 2023, 21:51   #8  |  Link
_Al_
Registered User
 
Join Date: May 2011
Posts: 372
Quote:
Is the matrix a factor when adding borders to an RGB clip or just YUV?
no, only for yuv clips, in that example I posted in that get_clip_color() , matrix would end up being None if clip was rgb, which resize function would accept, that's a default value, if not specified anyway.

That get_clip_color function can accept rgb or yuv clip and returns rgb or yuv tuple, or just a single value if t is a gray clip
the principle of that function is making blankclip of desired rgb color, then using resize function to change it into clips format and color, in rgb or yuv format,
then simply getting color for 0,0 pixel values, (could be any pixel, but with 0,0 pixel we do not need to deal with subsampling shifted positions for chroma), gives you desired color in particular bitdepth either for rgb or yuv, that code could be improved a bit so it is more readable to something like this:
Code:
#getting color tuple from 0,0 pixel from yuv, rgb or gray clip:
f = clip.get_frame(0)                   #getting a first frame for a clip that gives us an access to clips planes -  one plane (gray clip) or three planes (rgb or yuv clip)
#f[0] is first plane, first slice of frame f, it is a two dimensional  array of values, same as numpy array would be, values are accesed like this: value=f[0][y,x] for x,y pixel coordinates
p0 = f[0][0,0]                          #this is R value for rgb clip or Y value for yuv clip, for 0,0 pixel of the first plane
if f.format.name.startswith('Gray'):
    return p0                           #only Y value if clip is gray (there is one plane only for gray clip)
return p0, f[1][0,0], f[2][0,0]         #R, G, B values for rgb clip or Y, U, V  values for yuv clip
that function returns any bitdepth even float tuple if a clip is 32bit (float values), no need to scale it to a bitdepth as you did in colors.py,
no calculations are needed or to get yuv values from rgb etc., let vapoursynth resize function to come up with proper values

Last edited by _Al_; 24th August 2023 at 22:43.
_Al_ is offline   Reply With Quote
Old 24th August 2023, 22:49   #9  |  Link
_Al_
Registered User
 
Join Date: May 2011
Posts: 372
I include it here as well, just if someone wants to get a pixel value of yuv clip, where subsampling is important, if wanting any pixel values, not just 0,0 pixel, chroma planes could be smaller than first luma plane (YUV420, YUV422, YUV411), so in that case getting a pixel value for x, y coordinates for frame 0, would be:
Code:
f = clip.get_frame(0)
p0 = f[0][y,x]
if f.format.name.startswith('Gray'):
    return p0
ys = y >> f.format.subsampling_h
xs = x >> f.format.subsampling_w
return p0, f[1][ys,xs], f[2][ys,xs]
which would work even in above function, even for any rgb besides any yuv, because subsampling_h and subsampling_w are 0 for rgb as well, same as for YUV444, so there would not be any binary shift (1 or 2 which equals decimal division by 2 or 4)

Last edited by _Al_; 24th August 2023 at 23:35.
_Al_ is offline   Reply With Quote
Old 25th August 2023, 00:05   #10  |  Link
_Al_
Registered User
 
Join Date: May 2011
Posts: 372
Also, as using python now, you can use thousands of its modules that come with python as well, like color picker, so you can implement to select color from a GUI interface:
Code:
import tkinter
from tkinter import colorchooser
root = tkinter.Tk()
root.withdraw()
color = colorchooser.askcolor(title ="Choose color")
if not color:
    root.mainloop()
else:
    rgb_color, hex_color = color
    root.destroy() 
print(rgb_color)

Last edited by _Al_; 25th August 2023 at 05:14.
_Al_ is offline   Reply With Quote
Old 25th August 2023, 00:50   #11  |  Link
hello_hello
Registered User
 
Join Date: Mar 2011
Posts: 5,017
_Al_,
I've only skimmed over your last posts as I've got to spend some time in the real world, but I've been playing around with the colors function and it now converts the RGB values to YUV.
I'm not sure if the formula is always the same, and obviously the primaries differ for rec.601, 709, and 2020. The difference between the first two probably isn't enough to matter, but I assume the sRGB primaries should be converted to rec.2020 primaries when adding YUV borders, but if that's correct I'm not sure how to do it yet. The function scales YUV correctly for integer bit depths, but it's obviously wrong for float.

Anyway, I'll be back at some stage to re-read your posts and try to take them in, but in the mean time I've replaced the version of colors.py I uploaded earlier with the new version, which works for YUV of integer bitdepths now.

Cheers.
hello_hello is offline   Reply With Quote
Old 25th August 2023, 01:34   #12  |  Link
_Al_
Registered User
 
Join Date: May 2011
Posts: 372
I got correct results for float formats as well.
Using "yellow" color for YUV444PS clip I got: (0.9277999997138977, -0.5, 0.045847088098526)
Using "yellow" color for RGBS clip I got : (1.0, 1.0, 0)
previewer shows the same yellow rgb 255,255,0 for borders if I use those colors for particular clip in AddBorders(), as for any integer "yelow" argument

As for get_clip_color() from above, if matrix is in clip's props, than correct matrix is used for resize conversion and we get correct colors, if not it defaults depending on size(that can be changed).

You can include the same code for primaries and transfer, because if you have a in value and out value is not specified, you might get resize error. I do the same thing when automatizing these things.
Checking props if _Matrix, _Primaries, _Transfer is set and then get out arguments for resize, even updating props afterwords, like in that example but that could get complicated, I use even mediainfo in that example, where I should use rather vapoursynth props only. For your purpose, you might just copy your clip and delete those particular props and just be dealing with matrix maybe. It is just a color picker, it might not be that important.
_Al_ is offline   Reply With Quote
Old 25th August 2023, 12:04   #13  |  Link
hello_hello
Registered User
 
Join Date: Mar 2011
Posts: 5,017
I haven't looked back over your earlier posts yet (short on time), but after reading your last post and looking at your numbers I thought maybe after scaling I needed to subtract 0.5 from the UV values for float, so zero becomes the equivalent of 128 in 8 bit. It's still not quite right though, and my calculation for 8 bit YUV yellow isn't quite RGB yellow. I'm wondering if it's the matrix being used to convert the video to RGB for display. How exactly did you calculate your numbers?

What I'm currently getting using the formula in the script (the output of a blank clip).

For yellow:









Your numbers:



PS I found an online RGB to YUV converter and the numbers it calculates for 8 bit yellow are not quite, but very close to the numbers I'm getting.
https://www.calculatormix.com/conver...oogle_vignette
I don't know why there's a small difference.

It turns out that using the same numbers for 8 bit I get pure yellow after a conversion from 601 to 709 (excluding the primaries), so the difference is probably there somewhere, at least for integer.


Last edited by hello_hello; 25th August 2023 at 12:43.
hello_hello is offline   Reply With Quote
Old 25th August 2023, 14:46   #14  |  Link
_Al_
Registered User
 
Join Date: May 2011
Posts: 372
I do not calculate anything, I use zimg resizer (default in vapoursynth) to do the math. Making sure matrix is correct (and possibly primaries or transfer if they are set in clip as well). Having simple one color yellow (255,255,0) RGB blank clip and resizing that clip to clips format. Then reading its color values from its planes. That is what get_clip_color() does. All possible format values loading into previewer then give 255,255,0 yellow rgb.
_Al_ is offline   Reply With Quote
Old 25th August 2023, 18:48   #15  |  Link
hello_hello
Registered User
 
Join Date: Mar 2011
Posts: 5,017
Well I think I have the formulas worked out now. I assume YUV float is always supposed to be full-scale, because I'm getting values very similar to yours now, with matrix="709".
I added a matrix argument for specifying "601", "709" or "2020". If no matrix is specified it uses the matrix from frame properties if it exists, otherwise the default is "601".

I'll try your method sometime soon anyway, to check I've got the three matrices correct, but I think it's okay. I wish that someone who knows for sure would come along.
Obviously the matrix argument only applies to YUV.

<link removed>

"None" in the subtitle was the check for a matrix in frame properties I forgot to remove.

Color = colors.RGBColor(clip, color='yellow', matrix='601')





Color = colors.RGBColor(clip, color='yellow', matrix='709')




Last edited by hello_hello; 26th August 2023 at 19:06.
hello_hello is offline   Reply With Quote
Old 25th August 2023, 22:34   #16  |  Link
_Al_
Registered User
 
Join Date: May 2011
Posts: 372
Those values do not look correct. Values like 0.99 float looks wrong (too close to 1) but more visibly -0.49 (no blue in yellow, should be U=-0.5?), similar like would be in red, 255,0,0 there would be positive 0.5 for V (full red). And matrix should not matter because color is not there (blue in yellow) or full amount (red in red only), would that be correct?

For real video footage, not our color case, for float limited range, all illegal Y values should be above 1.0. Previewer should show those values.
But for our task, getting color, it should never be above 1.0, no illegal colors, because we start with full rgb 255 value, it cannot be illegal from that point., unless using faulty equations.

I checked that colors.py. You you are not using values from a zimg conversion but values are calculated using equations, :-)

but how about ye different matrixes alone? Not mentioning color ranges, etc. You just need more and more equations. Simply using vapoursynth conversions and then pulling out pixel values seams like way to go. Someone already worked his a** off :-) , to get proper conversions for all scenarios, why not to use it.
I might post that function again considering it all, range , primaries, transfer....
_Al_ is offline   Reply With Quote
Old 26th August 2023, 13:03   #17  |  Link
hello_hello
Registered User
 
Join Date: Mar 2011
Posts: 5,017
Quote:
Originally Posted by _Al_ View Post
I checked that colors.py. You you are not using values from a zimg conversion but values are calculated using equations, :-)
Yeah, I wanted to see if I could get the equations correct, once I start doing it that way. I'll use your method to get the values from a zimg conversion too and compare the results.

I think I read that according to the specs the results are supposed to be rounded for integer (I didn't bother as Vapoursynth accepts float) and the float result could simply be due to floating point math inaccuracies. Your luma value for yellow was 0.9277999997138977 rather than 1.0 too, but that's probably correct because I assume adding blue must increase the luma so only pure white would have a value of 1.0. If I use a color picker on those images though, I get (255, 255, 7) for the 8 bit yellow image and (255, 254, 6) for the 32 bit one, so maybe they're not 100% correct. Then again, they were converted back to 8 bit RGB for display by VS edit and I've no idea what it's doing.

I might start another thread, or ask over at video help, to see if I can find someone who knows what the equations should be, given I've come this far.

Thinking about it, I'm not sure any difference in primaries would be a factor, given the hex values used are for specifying RGB primaries, so RGB's green would be the same green for each colorspace (well maybe a tad off for SD). If 2020's green was specified instead, it'd have to be converted to RGB's green for rec.709 as the RGB color space doesn't include rec.2020's green, but the rec.2020 color space includes RGB green. Does that make sense or is it faulty logic?
https://en.wikipedia.org/wiki/File:C...31_Rec_601.svg
https://en.wikipedia.org/wiki/File:C...31_Rec_709.svg
https://en.wikipedia.org/wiki/File:C...1_Rec_2020.svg
hello_hello is offline   Reply With Quote
Old 26th August 2023, 18:29   #18  |  Link
hello_hello
Registered User
 
Join Date: Mar 2011
Posts: 5,017
Well it looks like you talked me into using your method.
If a matrix is specified it's used (YUV only).
If it's not specified any matrix in frame properties is used.
If there's no frame property it's based on resolution, similar to your example.
(Edit: Re-uploaded to fix an error with choosing the matrix).
<link removed>

The new script works the same way as the original one.

Code:
import vapoursynth as vs
vc = vs.core
import colors

clip = <SomeVideo>
BorderColor = colors.RGBColor(clip, color='aqua', matrix='709')  #  or  (color='00FFFF', matrix=1)
clip = clip.std.AddBorders(32,32,32,32, color=BorderColor)
To specify the color of a new BlankClip.

Code:
import vapoursynth as vs
vc = vs.core
import colors

clip = vc.std.BlankClip(format=vs.RGBS)  #  or  format=vs.GRAY8  or  format=vs.YUV420P10  etc.
ClipColor = colors.RGBColor(clip, color='aqua')
clip = vc.std.BlankClip(clip, color=ClipColor)

Last edited by hello_hello; 27th August 2023 at 23:40.
hello_hello is offline   Reply With Quote
Old 27th August 2023, 07:02   #19  |  Link
_Al_
Registered User
 
Join Date: May 2011
Posts: 372
ad colors.py,
I would not pass matrix, because matrix could be different than clip's matrix, and all weirdness breaks. But if you prefer to pass matrix, like you did, and to have two types for one argument, then you could deal with kwargs instead of values (because key argument changes depending on type value). Also vapoursynth would just raise error if matrix would be wrong. Exactly the same what you do, so not trying to troubleshoot matrix validity. I included range check as well. It would be like this:
Code:
import vapoursynth as vs
from vapoursynth import core
from typing import Union

colors = {'aliceblue'            : 'F0F8FF',
          'antiquewhite'         : 'FAEBD7',
              #etc. dictionary is not complete}

def input_rgb24_color(color:str):
    ''' returns rgb color as a tuple'''
    if color in colors.keys():
        color = colors[color]
    #color is hex string only now
    try:
        rgb_color =  tuple(int(color[i:i+2], 16) for i in (0, 2, 4))
        core.std.BlankClip(color=rgb_color)
    except (ValueError, vs.Error):
        print('RGBColor: color must be a proper hex string that represents 8bit rgb color, example: "00008B"')
        raise
    return rgb_color

def RGBColor(clip, color:str, matrix:Union[int,str]=None):
    if not isinstance(clip, vs.VideoNode):
       raise ValueError('RGBColor: clip must be a video')

    if not isinstance(color, str):
       raise ValueError('RGBColor: color must be a string, for example "darkblue" or "00008B"')
    else:
        rgb_color = input_rgb24_color(color)

    if clip.format.color_family==vs.RGB:
        matrix_kwarg_out = {}

    else:
        #yuv, gray
        if matrix is None:            MatrixPassed_kwarg = {}
        elif isinstance(matrix, str): MatrixPassed_kwarg = {'matrix_s':matrix}
        elif isinstance(matrix, int): MatrixPassed_kwarg = {'matrix':matrix}
        else:
            raise ValueError('RGBColor: matrix must be an integer or string')

        MatrixProp = clip.get_frame(0).props.get("_Matrix", None)
        MatrixProp_kwarg = {} if MatrixProp in [None,0,2,3] else {'matrix':MatrixProp}

        if   clip.width <= 1024 and clip.height <= 576: MatrixSize_kwarg = {'matrix':5}
        elif clip.width < 3840 and clip.height < 2160:  MatrixSize_kwarg = {'matrix':1}
        else: MatrixSize_kwarg = {'matrix':9}

        matrix_kwarg_out = MatrixPassed_kwarg or MatrixProp_kwarg or MatrixSize_kwarg

    RangeProp = clip.get_frame(0).props.get('_ColorRange', None)
    range = None if RangeProp is None else {0:1,1:0}[RangeProp] #values needs to be swapped for zimg

    BlankRGBClip = core.std.BlankClip(color=rgb_color)
    ColorClip = BlankRGBClip.resize.Point(format=clip.format.id, **matrix_kwarg_out, range=range)
    f = ColorClip.get_frame(0)
    p0 = f[0][0,0]
    if clip.format.color_family==vs.GRAY:
        return p0
    return p0, f[1][0,0], f[2][0,0]
all colors are ok in previewer as well, for yellow (255,255,0) , or one of those values could +-1 with rounding error (like for some 8bit integer source) , more than +-1 would be too much

Last edited by _Al_; 27th August 2023 at 07:39.
_Al_ is offline   Reply With Quote
Old 27th August 2023, 20:02   #20  |  Link
hello_hello
Registered User
 
Join Date: Mar 2011
Posts: 5,017
I was experiencing this problem yesterday and in the end I put it down to user error when it went away, but as it was happening today I managed to track down the cause.... eventually.

Code:
clip = YUV420_Video      # here clip.get_frame(0).props.get("_Matrix", None) returns 1
clip = vc.std.BlankClip(clip)      # here it returns None
clip = clip.resize.Spline36(1280,720)      # here it returns 2
RGBClip = vc.std.BlankClip(color=(255, 255, 0))
MatrixProp = clip.get_frame(0).props.get("_Matrix", None)
clip = RGBClip.resize.Point(format=clip.format.id, matrix=MatrixProp)      # here the error is "no path between colorspaces"
Code:
clip = YUV420_Video      # here clip.get_frame(0).props.get("_Matrix", None) returns 1
clip = vc.std.BlankClip(clip)      # here it returns None
RGBClip = vc.std.BlankClip(color=(255, 255, 0))
MatrixProp = clip.get_frame(0).props.get("_Matrix", None)
clip = RGBClip.resize.Point(format=clip.format.id, matrix=MatrixProp)      # here the error is "a matrix must be specified"
Two different error message depending on whether the _Matrix property doesn't exist, or exists but has an "unspecified" value.
Why would the Vapoursynth resizers add the frame property and give it an unspecified value instead of just not adding it?

My bad, I guess, for not considering the possibility that _Matrix might have a value of 2, but because a value of 2 and no value at all produce different error messages, when they're effectively the same thing, I banged my head on the desk way too many times before I tracked that one down.

Last edited by hello_hello; 27th August 2023 at 22:49.
hello_hello is offline   Reply With Quote
Reply

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 18:28.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2025, vBulletin Solutions Inc.