Had to make something like this, but i can't find way how to move video which is at middle a bit upper...
melt in.mp4
-filter watermark:"title.jpg" composite.progressive=1 producer.align=centre composite.valign=top composite.halign=c
-filter watermark:"bottom.jpg" composite.progressive=1 producer.align=centre composite.valign=bottom composite.halign=c
-filter crop left=128 right=128
-profile square_profile.txt -consumer avformat:"out.mp4" vcodec=libx264 vb=3500k ab=128k
So how to move centered video upper? Can't find such filter...
The "affine" filter can be used to change the size and position of the video frame:
https://mltframework.org/plugins/FilterAffine/
The affine filter is really just a convenience wrapper that combines a black producer (for the background) and an affine transition:
https://mltframework.org/plugins/TransitionAffine/
You can modify the affine transition properties by setting "transition.*" properties on the affine filter. For example, to set the size and position of the frame, use "transition.geometry".
melt in.mp4 -filter affine transition.geometry="-40/40:700x500" transition.distort=0 transition.fill=0 \
-filter watermark:"bottom.jpg" composite.progressive=1 producer.align=centre composite.valign=bottom composite.halign=c \
-filter watermark:"bottom.jpg" composite.progressive=1 producer.align=centre composite.valign=bottom composite.halign=c \
-profile square_profile.txt -consumer avformat:"out.mp4" vcodec=libx264 vb=3500k ab=128k
The geometry specification is: "X/Y:WxH". So set those according to your needs. The X and Y values can be negative in order to crop off parts that you don't want to display.
Related
trying to array slice the get-psreadlineoption command. I want to select all strings containing the word 'Color' and then input those to 'set-psreadline' to set all colors. I do not understand how this all works in powershell. It's an array, right? I can just loop over it like this:
foreach($a in $i) { $i; if ($i -contains 'MemberColor') {$i;} }
But that gives no output. I also cannot access it as an array:
get-psreadlineoption[21..36]
get-psreadlineoption['EditMode']
Does not work. Basically what I want to do is:
foreach (get-psreadlines[21..36]) { $array = append(<string that contains 'Color'>) } foreach ($a in $array) { set-psreadline($a, ...)}
How would I go about doing this?
(P.S. I just want to set all those colors to the same color in a concise manner as possible)
The solution depends on what version of the PSReadLine module you're using:
PSReadline v2.x, which ships with PowerShell (Core) 7+.
PSReadline v1.x, which Windows PowerShell versions ship with in Windows 10+ / Windows Sever 2016+, although it is possible to install 2.x on demand in Windows PowerShell 5.0 and 5.1 (Install-Module PSReadLine)
Use (Get-Module PSReadLine).Version.ToString() to see which version you're using.
PSReadline v2.x solution:
To get the names of all color properties, via filtering the names by those ending in color (case-insensitively), use reflection, which PowerShell facilitates via the intrinsic .psobject property:
(Get-PSReadLineOption).psobject.Properties.Name -like '*color'
Note:
A quick way to print all property names of interest, including their values, is to use
Get-PSReadLineOption | Select-Object *color. However, the result is a [pscustomobject], not a hashtable, and in order to convert the former to the latter you'd again need the same technique shown below.
However, as an alternative to setting colors via Set-PSReadLineOption (as shown below), you may also use the approach described for PSReadLine v1.x in the bottom section (e.g., (Get-PSReadlineOption).CommentColor = 'DarkGray'), in which case you can use the property names shown in the output from Get-PSReadLineOption | Select-Object *color as-is. Note that the property names differ between v2.x and v1.x; also, as with Set-PSReadLineOption -Colors below, setting background colors requires the use of VT escape sequences.
Caveat: These property names require a transformation in order to be usable as the keys of the hashtable you can pass to Set-PSReadLineOption -Colors (as of PSReadLine 2.1.0):
The suffix Color must be removed, and in the case of DefaultTokenColor, the suffix TokenColor, which the following -replace operation does:
(Get-PSReadLineOption).psobject.Properties.Name -like '*color' `
-replace '(Token)?Color$'
This yields the following color key names (as of PSReadLine 2.1.0):
ContinuationPrompt
Default
Comment
Keyword
String
Operator
Variable
Command
Parameter
Type
Number
Member
Emphasis
Error
Selection
InlinePrediction
You can now pass a hashtable that selectively updates colors; e.g. the following sets the Comment (CommentColor) color to dark gray (while leaving all other colors untouched):
Set-PSReadLineOption -Color #{ Comment = 'DarkGray' }
A color value can either be:
One of the values of the [ConsoleColor] enumeration type; e.g. [ConsoleColor]::DarkGray, which you may pass as string 'DarkGray', as shown above.
A VT (Virtual Terminal) / ANSI escape sequence. Note that use of such sequences is a must if you want to set the background color for a given setting; e.g., the following sets the comment color to dark gray (90) on a white background (47)
Set-PSReadLineOption -Color #{ Comment = "`e[90;47m" }
To create a hashtable comprising all color keys, using the current property values as a starting point, use the following:
$allColors = #{}
(Get-PSReadLineOption).psobject.Properties.
Where({ $_.Name -like '*color' }).
ForEach({ $allColors[$_.Name -replace '(Token)?Color$'] = $_.Value })
Note: When you print $allColors, the Value column may appear to be empty, but the values are there, in the form of - themselves invisible - Virtual Terminal (VT) control sequences.
PSReadline v1.x solution (older versions of Windows PowerShell):
Unlike the v2.x version:
Set-PSReadlineOption in v1.x uses the combination of the -TokenKind and -ForegroundColor / -BackgroundColor parameters for the various colors and also, for general color settings, individual parameters (e.g. -ErrorForegroundColor) (rather than the single v2.x -Colors parameter that accepts a hashtable); also, all color settings are split into foreground and background values.
The color values are limited to the values of the [ConsoleColor] enumeration type, such as 'DarkGray' ([ConsoleColor]::DarkGray)
For a unified approach to setting colors, you may forgo Set-PSReadLineOption and directly set the properties of the Microsoft.PowerShell.PSConsoleReadLineOptions instance that Get-PSReadLineOption returns.
For instance, the following sets the foreground color of comments to dark gray:
(Get-PSReadlineOption).CommentForegroundColor = 'DarkGray'
This is the equivalent of the following v1.x Set-PSReadLineOption call:
Set-PSReadLineOption -TokenKind Comment -ForegroundColor DarkGray
To get the names of all color-relevant properties, use the same approach as for v2.x:
(Get-PSReadLineOption).psobject.Properties.Name -like '*color'
This yields the following color property names:
ContinuationPromptForegroundColor
ContinuationPromptBackgroundColor
DefaultTokenForegroundColor
CommentForegroundColor
KeywordForegroundColor
StringForegroundColor
OperatorForegroundColor
VariableForegroundColor
CommandForegroundColor
ParameterForegroundColor
TypeForegroundColor
NumberForegroundColor
MemberForegroundColor
DefaultTokenBackgroundColor
CommentBackgroundColor
KeywordBackgroundColor
StringBackgroundColor
OperatorBackgroundColor
VariableBackgroundColor
CommandBackgroundColor
ParameterBackgroundColor
TypeBackgroundColor
NumberBackgroundColor
MemberBackgroundColor
EmphasisForegroundColor
EmphasisBackgroundColor
ErrorForegroundColor
ErrorBackgroundColor
This is sort of a common question, how to loop through properties Iterate over PSObject properties in PowerShell. You can also use get-member to get the property list. You can also pipe to "select *color".
Get-PSReadLineOption | get-member *color | % name
CommandColor
CommentColor
ContinuationPromptColor
DefaultTokenColor
EmphasisColor
ErrorColor
KeywordColor
MemberColor
NumberColor
OperatorColor
ParameterColor
PredictionColor
SelectionColor
StringColor
TypeColor
VariableColor
For example, I have a variable, which returns the line with several arrays:
#{sourceDSAcn=B; LastSyncResult=0} #{sourceDSAcn=A; LastSyncResult=9} #{sourceDSAcn=C; LastSyncResult=0} #{sourceDSAcn=M; Last SyncResult=10}
I want to sort this line alphabetically by one of parameters. In this case - by sourceDSAcn, so result must be like that:
#{sourceDSAcn=A; LastSyncResult=9} #{sourceDSAcn=B; LastSyncResult=0} #{sourceDSAcn=C; LastSyncResult=0} #{sourceDSAcn=M; Last SyncResult=10}
How can I do that?
Your output format suggests two things:
The objects aren't arrays, but custom objects ([pscustomobject] instances).
You've used the Write-Host cmdet to print these objects to the host (display), which results in the hashtable-literal-like representation shown in your question (see this answer).
If, instead, you want the usual rich display formatting you get by default - while still sending the output to the host only rather than to the success output stream - you can use the Out-Host cmdlet.
Conversely, to produce data output to the pipeline, use either the Write-Output cmdlet or, preferably, PowerShell's implicit output feature, as shown below; for more information, see this answer.
In order to sort (custom) objects by a given property, simply pass the name of that property to
Sort-Object's (positionally implied) -Property parameter, as Mathias R. Jessen helpfully suggests:
# Using $variable by itself implicitly sends its value through the pipeline.
# It is equivalent to: Write-Output $variable | ...
$variable | Sort-Object sourceDSAcn # same as: ... | Sort-Object -Property sourceDSAcn
I'm trying to create a DPI aware app which responds to user requested DPI change events by resizing the window.
The program in question is created in C and uses SDL2, however to retrieve system DPI information I use xlib directly, as the SDL DPI support in X11 is lacking.
I found two ways to get the correct DPI information on program startup, both involving getting Xft.dpi information from Xresource: one is to use XGetDefault(display, "Xft", "dpi"), while the other is to use XResourceManagerString, XrmGetStringDatabase and XrmGetResource. Both of them return the correct DPI value when the program is created.
The problem is, if the user changes the system scale while the program is running, both XGetDefault abd XrmGetResource still return the old DPI value even though when I run "xrdb -query | grep Xft.dpi" the value has indeed changed.
Does anyone know a way to get the updated Xft.dpi value?
I found out a way to do exactly what I wanted, even though it's rather hackish.
The solution (using XLib) is to create a new, temporary connection to the X server using XOpenDisplay and XCloseDisplay, and poll the resource information from that new connection.
The reason this is needed is because X fetches the resource information only once per new connection, and never updates it. Therefore, by opening a new connection, X will get the updated xresource data, which can then be used for the old main connection.
Be mindful that constantly opening and closing new X connections may not be great for performance, so only do it when you absolutely need to. In my case, since the window has borders, I only check for DPI changes when the title height has changed, as a DPI change will change the size of your title border due to font size differences.
First off it must be noted that the value of the Xft.dpi resource isn't necessarily accurate -- it depends on whether the system and or user login scripts have correctly set it or not.
Also it is important to remember that the Xft.dpi resource is intended to be used by the Xft library, not by arbitrary programs looking for the screen resolution.
The Xft.dpi resource can be set as follows. This example effectively only deals with a display with a single screen, and note that it uses xdpyinfo. This also shows how it might not be exact, but could be rounded. Finally this example shows calculation of both the horizontal and vertical resolution, but Xft really only wants the horizontal resolution:
SCREENDPI=$(xdpyinfo | sed -n 's/^[ ]*resolution:[ ]*\([^ ][^ ]*\) .*$/\1/p;//q')
SCREENDPI_X=$(expr "$SCREENDPI" : '\([0-9]*\)x')
SCREENDPI_Y=$(expr "$SCREENDPI" : '[0-9]*x\([0-9]*\)')
# N.B.: If true screen resolution is within 10% of 100DPI it makes the most
# sense to claim 100DPI to avoid font-scaling artifacts for bitmap fonts.
if expr \( $SCREENDPI_X / 100 = 1 \) \& \( $SCREENDPI_X % 100 \<= 10 \) >/dev/null; then
FontXDPI=100
fi
if expr \( $SCREENDPI_Y / 100 = 1 \) \& \( $SCREENDPI_Y % 100 \<= 10 \) >/dev/null; then
FontYDPI=100
fi
echo "Xft.dpi: ${FontYDPI}" | xrdb -merge
I really wish I knew why Xft didn't at least try to find out the screen's resolution itself instead of relying all of the time on its "dpi" resource being set, but I've found that the current implementation only uses the resource setting, so something like the above is actually always necessary to set the resource properly (and further one must also make sure the X Server itself has been properly configured with the correct physical screen dimensions).
From a C program you want to do just what xdpyinfo itself does and skip all the nonsense about Xft's resources. Here's the xdpyinfo code paraphrased:
Display *dpy;
dpy = XOpenDisplay(displayname);
for (scr = 0; scr < ScreenCount(dpy); scr++) {
int xres, yres;
/*
* there are 2.54 centimeters to an inch; so there are 25.4 millimeters.
*
* dpi = N pixels / (M millimeters / (25.4 millimeters / 1 inch))
* = N pixels / (M inch / 25.4)
* = N * 25.4 pixels / M inch
*/
xres = ((((double) DisplayWidth(dpy, scr)) * 25.4) /
((double) DisplayWidthMM(dpy, scr))) + 0.5;
yres = ((((double) DisplayHeight(dpy, scr)) * 25.4) /
((double) DisplayHeightMM(dpy, scr))) + 0.5;
}
XCloseDisplay(dpy);
Note also that if you are for some odd reason scaling your whole display (e.g. with xrandr), then you should want the fonts to scale equally with everything else. It's just a horrible bad hack to use whole-screen scaling to scale just the fonts, especially when for most things it's simpler to just tell the application to use properly scaled fonts that will display at a constant on-screen point size (which is exactly what Xft uses the "dpi" resource to do). I'm guessing Ubuntu does something stupid to change the screen resolution, e.g. using xrandr to scale up the apparent size of icons and other on-screen widgets without applications having to know about screen size and resolution, then it has to lie to Xft by rewriting the Xft.dpi resource.
Note that if you avoid whole-screen scaling then applications that don't use Xft can still get proper font scaling by correctly requesting a properly scaled font, i.e. even with bitmap fonts you can get them scaled to the proper physical on-screen size by using the screen's actual resolution in the font-spec. E.g. continuing from the above shell fragment:
# For pre-Xft applications we can specify physical font text sizes IFF we also tell
# it the screen's actual resolution when requesting a font. Note the use of the
# rounded values here.
#
DecentDeciPt="80"
DecentPt="8"
export DecentDeciPt DecentPt
#
# Best is to arrange one's font-path to get the desired one first, but....
# If you know the name of a font family that you like and you can be sure
# it is installed and in the font-path somewhere....
#
DefaultFontSpec='-*-liberation mono-medium-r-*-*-*-${DecentDeciPt}-${FontXDPI}-${FontYDPI}-m-*-iso10646-1'
export DefaultFontSpec
#
# For Xft we have set the Xft.dpi resource so this allows the physical font size to
# be specified (e.g. with Xterm's "-fs" option) and for a decent scalable font
# to be chosen:
#
DefaultFTFontSpec="-*-*-medium-r-*-*-*-*-0-0-m-*-iso10646-1"
DefaultFTFontSpecL1="-*-*-medium-r-*-*-*-*-0-0-m-*-iso8859-1"
export DefaultFTFontSpec DefaultFTFontSpecL1
# Set a default font that should work for everything
#
eval echo "*font: ${DefaultFontSpec}" | xrdb -merge
Finally here's an example of starting an xterm (that's been compiled to use Xft) with the above settings (i.e. the Xft.dpi resource and the shell variables above) to show text at physical size of 10.0 Points on the screen:
xterm -fs 10 -fa $DefaultFTFontSpec
You could try to use xdpyinfo(1); on my system it outputs, among a lot of other things:
dimensions: 1280x1024 pixels (332x250 millimeters)
resolution: 98x104 dots per inch
depths (7): 24, 1, 4, 8, 15, 16, 32
I don't know whether it can help you because I don't know how do you change the DPI of your screen, but chances are it works. Good luck!
--- UPDATE after comment ---
In a comment below from the OP, it is said that "there is a setting to change the DPI"... still I don't know which. Anyway, I tried Ctrl+Alt+Plus and Ctrl+Alt+Minus to change the resolution of the X server on the fly. After having changed the resolution, and seeing everything bigger than before, I ran xdpyinfo again. IT DIDN'T WORK: still the same output. But may be the method you use (which?) instead works...
I have a list of objects of unknown length, I want to create 2 lists of checkboxes, in each list a checkbox for each line of the list. I also need to be able to get to the checkboxes and check their value.
Since I didn't find a way to get the value of a checkbox from its path, I wanted to create a global array that will hold the variables for the check boxes, and tried the fallowing:
global cb
set i 0
foreach port $ports {
set to_cb [checkbutton $to.cb_to_$i -variable [list $cb(to$i)] -text $port -command [list __sp_from_to_changed $from $to]]
set from_cb [checkbutton $from.cb_from_$i -variable [list $cb(from$i)] -text $port -command [list __sp_from_to_changed $from $to]]
grid $to_cb -row [expr $i + 2] -sticky nsew
grid $from_cb -row [expr $i + 2] -sticky nsew
incr i
When I source it get the error can't read "cb(to0)": no such variable, how can I assign a variable inside an array for a check box, or better yet, is there a way to get the current value directly from the checkbox without using intermediate variables?
Checkbuttons always need to be bound to a variable (there is a default, but you don't want to use that). What you need to do is to generate the name of a variable that is unique for each checkbutton; an array element is an excellent choice here.
So what's the problem in your code? It's simply that you're trying to dereference the variables by putting a $ in front of them; unlike some other languages, Tcl always uses the $ to mean “read this variable” (except in regular expressions). You also don't need to wrap the variable name in list; that would only be useful if you putting it into a generated script. Instead, you need lines like this:
set to_cb [checkbutton $to.cb_to_$i -variable cb(to$i) -text $port \
-command [list __sp_from_to_changed to $i]]
set from_cb [checkbutton $from.cb_from_$i -variable cb(from$i) -text $port \
-command [list __sp_from_to_changed from $i]]
The changes here are:
Removed the extra generated complexity from the -variable option's value; a bare array element name is good enough.
Updated the arguments to __sp_from_to_changed so that they say what has actually been modified (the first argument is now to or from, and the second is the index; from that, you should be able to construct all the element names you need quite trivially).
Added a backslash to those long lines so I could break them up for readability. :-)
I have searched online and wasn't able to find an answer to this so I figured I could ask the experts here. Is there anyway to get the current window resolution in OpenCV? I've tried the cvGetWindowProperty passing in the named instance of the window, but I can't find a flag to use.
Any help would be greatly appreciated.
You can get the width and height of the contents of the window by using shape[1] and shape[0] respectively.
I think when you use Open CV, the image from the camera is stored as a Numpy array, with the shape being [rows, cols, bgr_channels] like [480,640,3]
code e.g.
import cv2 as cv2
cv2.namedWindow("myWindow")
cap = cv2.VideoCapture(0) #open camera
ret,frame = cap.read() #start streaming
windowWidth=frame.shape[1]
windowHeight=frame.shape[0]
print(windowWidth)
print(windowHeight)
cv2.waitKey(0) #wait for a key
cap.release() # Destroys the capture object
cv2.destroyAllWindows() # Destroys all the windows
console output:
640
480
You could also call getWindowImageRect() which gets a whole rectangle: x,y,w,h
e.g.
import cv2 as cv2
cv2.namedWindow("myWindow")
cap = cv2.VideoCapture(0) #open camera
ret,frame = cap.read() #start streaming
windowWidth=cv2.getWindowImageRect("myWindow")[2]
windowHeight=cv2.getWindowImageRect("myWindow")[3]
print(windowWidth)
print(windowHeight)
cv2.waitKey(0) #wait for a key
cap.release() # Destroys the capture object
cv2.destroyAllWindows() # Destroys all the windows
-which very curiously printed 800 500 (the actual widescreen format from the camera)
Hmm... it's not really a great answer (pretty hack!), but you could always call cvGetWindowHandle. With that native window handle, I'm sure you could figure out some native calls to get the contained image sizes. Ugly, hackish, and not-very-portable, but that's the best I could suggest given my limited OpenCV exposure.