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. Domains: forum.doom9.org / forum.doom9.net / forum.doom9.se |
|
|
#1 | Link |
|
Registered User
Join Date: Jan 2006
Posts: 1,869
|
New Script: Drawrect 0.6
Another one of my utility functions.
Code:
#Drawrect 0.6 by jmac698
#a script to draw rectangles on top of existing video or create masks
#requires masktools v2a45+ (mode in lutspa) and yv12 video
#0.6: Added even faster option, bool "chroma", simplified code
#0.5: Speedup and simplification (thanks Gavino, yet again), new function createrect, improved code
#0.4: Added calculated named colors, removed old system
#0.3: Added fully opaque with opacity=256, now default. Fixed bugs. Added colors. Refactored. Outline option.
# Bugs: When opacity=256, the color edges are not merged,
#todo: finish deepcolor support, more shapes
#Usage:
#createrect(clip c, int x1, int y1, int x2, int y2, int "foreclr" (255), int "backclr" (0), bool "filled" (true), bool "chroma" (false)) This is meant to create a simple rect mask
#drawrect(clip c, int x1, int y1, int x2, int y2, int foreclr, int "opacity" (256), bool "filled" (true), bool "chroma" (false)) This is meant to draw on existing video
#opacity=256 for fully opaque
colorbars(pixel_type="YV12")
createrect(400,400,419,419)#Great for making masks, a square with luma=255 and 0 elsewhere. Note that chroma is untouched by default!
#Now use drawrect to add more shapes onto the first mask
drawrect(1,1,150,200,named_color("cyn"), filled=false)#a cyan square
drawrect(1,40,300,40,named_color("red"))#a red horizontal line (notice at y=41 the color overwrites the background)
drawrect(280,300,319,340,$FF8080,opacity=127)#transparent white rectangle
drawrect(-10,-10,5,5,$B08080)#test behavior with offscreen coordinates
function drawrect(clip c, int x1, int y1, int x2, int y2, int foreclr, int "opacity", bool "filled", bool "chroma"){
#A function to draw a filled rectangle into a YV12 clip, can also draw lines as (1,1,1,200,$7E8080): a vertical line 1 pixel wide from 1,1 to 1,200
#Note that chroma will be merged with the input clip; draw on mod 2 boundaries if you need to ensure the given pixel chroma
#The opacity formula is (opacity*foreground+(255-opacity)*background+128)/256
#You can't draw 255 on black unless you use opacity=256, because opacity=255 gives output=254
#If create=true, it just draws a single rectangle
#chroma=true (default) to process chroma. This function is meant to draw colored rect's on video, so defaults to true.
#(It can also build masks with more than one rect)
filled=default(filled, true)
opacity=default(opacity,256)
chroma=default(chroma, true)
y=getword(foreclr, 2)#byte=2 (n*65536), wordsize=1
u=getword(foreclr, 1)
v=getword(foreclr, 0)
#"x>=xl & x<=xh & y>=yl & y<= yh ? Y : 16" y is the coordinate y, Y is a variable which is substituted as a number in the expression
#"x x1 >= & x xh <= y yl >= & y yh <= & & Y 16 ?"
xl=min(x1, x2)#sort the coordinates
xh=max(x1, x2)
yl=min(y1, y2)
yh=max(y1, y2)
xl2=ceil(xl/2)#chroma coordinates in YV12 are half, ensure they are just larger than luma size
xh2=ceil(xh/2)
yl2=ceil(yl/2)
yh2=ceil(yh/2)
m=opacity==256?255:256
chromamode=chroma?3:1
drawstry2=drawstr(y, m)
drawstru2=drawstr(u, m)
drawstrv2=drawstr(v, m)
drawstrm=buildrectexp(xl, yl, xh, yh, opacity, 0, filled)
drawstrmuv=buildrectexp(xl2, yl2, xh2, yh2, opacity, 0, filled)
mask=mt_lutspa(c, mode="absolute", yexpr=drawstrm, uexpr=drawstrmuv, vexpr=drawstrmuv, u=chromamode, v=chromamode)
mt_lutxy(c, mask, yexpr=drawstry2, uexpr=drawstru2, vexpr=drawstrv2, u=chromamode, v=chromamode)
}
function createrect(clip c, int x1, int y1, int x2, int y2, int "foreclr", int "backclr", bool "filled", bool "chroma"){
#chroma=true (default) to process chroma. This function is meant to draw white rect's for masks, so defaults to false.
foreclr=default(foreclr, $FF8080)
backclr=default(backclr, $008080)
filled=default(filled, true)
chroma=default(chroma, false)
yf=getword(foreclr, 2)#byte=2 (n*65536), wordsize=1
uf=getword(foreclr, 1)
vf=getword(foreclr, 0)
yb=getword(backclr, 2)
ub=getword(backclr, 1)
vb=getword(backclr, 0)
xl=min(x1, x2)#sort the coordinates
xh=max(x1, x2)
yl=min(y1, y2)
yh=max(y1, y2)
xl2=ceil(xl/2)#chroma coordinates in YV12 are half, ensure they are just larger than luma size
xh2=ceil(xh/2)
yl2=ceil(yl/2)
yh2=ceil(yh/2)
chromamode=chroma?3:1
drawstry=buildrectexp(xl, yl, xh, yh, yf, yb, filled)
drawstru=buildrectexp(xl2, yl2, xh2, yh2, uf, ub, filled)
drawstrv=buildrectexp(xl2, yl2, xh2, yh2, vf, vb, filled)
mt_lutspa(c, mode="absolute", yexpr=drawstry, uexpr=drawstru, vexpr=drawstrv, u=chromamode, v=chromamode)
}
function drawstr(int clr, int m) {
return string(clr)+ " y * "+string(m)+" y - x * + "+string(m)+" /"
}
function buildrectexp(int xl, int yl, int xh, int yh, int clrfore, int clrback, bool filled){
#if x=x1 or x=x2 and y>=y1 and y<=y2 or y=y1 or y=y2 and x>=x1 and x<=x2
#x x1 = x x2 = or y y1 >= y y2 <= and and y y1 = y y2 = or x x1 >= x x2 <= and and or
filled?"x "+string(xl)+" >= x "+string(xh)+" <= & y "+string(yl)+" >= y "+string(yh)+" <= & & "+string(clrfore)+" "+string(clrback)+" ?" \
:"x "+string(xl)+" = x "+string(xh)+" = | y "+string(yl)+" >= y "+string(yh)+" <= & & y "+ \
string(yl)+" = y "+string(yh)+" = | x "+string(xl)+" >= x "+string(xh)+" <= & & | "+string(clrfore)+" "+string(clrback)+" ?"
}
function named_color(string color, string "colorspace", float "luma", float "sat", bool "deepcolor") {
#calculate the named color in yuv with specificed saturation and luminance
color=lcase(color)
colorspace=default(colorspace, "rec601")
luma=default(luma, .75)
sat=default(sat, .75)
deepcolor=default(deepcolor, false)
#Define in rgb, it's easiest
colorrgb="111"
colorrgb=color=="yel"||color=="yellow"?"110":colorrgb
colorrgb=color=="cyn"||color=="cyan"?"011":colorrgb
colorrgb=color=="grn"||color=="green"?"010":colorrgb
colorrgb=color=="mag"||color=="magenta"?"101":colorrgb
colorrgb=color=="red"?"100":colorrgb
colorrgb=color=="blu"||color=="blue"?"001":colorrgb
colorrgb=color=="blk"||color=="black"?"000":colorrgb
r=midstr(colorrgb, 1, 1)=="1"?1:0
g=midstr(colorrgb, 2, 1)=="1"?1:0
b=midstr(colorrgb, 3, 1)=="1"?1:0
#Need to be more flexible. -I=(-.956295,.272558,1.104744)
kr601=.299
kg601=.587
kb601=.114
kr709=.2125
kg709=.7154
kb709=.0721
y=colorspace=="rec601"?kr601*r+kg601*g+kb601*b:kr709*r+kg709*g+kb709*b
pb=colorspace=="rec601"?(b-y)/(1-kb601):(b-y)/(1-kb709)
pr=colorspace=="rec601"?(r-y)/(1-kr601):(r-y)/(1-kr709)
scale=deepcolor?65536:256
yscale=deepcolor?219*219:219*luma
cscale=deepcolor?112*112:112*sat
round(y*yscale+scale/16)*scale*scale+round(pb*cscale+scale/2)*scale+round(pr*cscale+scale/2)
}
function hexbyte(int n) {
#This function returns the lower byte of n as a 2 digit hex string.
#For example, hex(257)="01".
n=n%256
h=floor(n/16)
l=n%16
s1=h>9?h+65-10:h+48
s2=l>9?l+65-10:l+48
chr(s1)+chr(s2)
}
function hex(int n){
#returns 3 byte hex string
d2=floor(n/65536)
n=n-d2*65536
d1=floor(n/256)
n=n-d1*256
hexbyte(d2)+hexbyte(d1)+hexbyte(n)
}
function getword(int n, int p, int "size"){
#Get word p of size size from n, limited to p=(0,2)
#Warning: due to a bug in avisynth 2.6a3, p=2 and size=2 gives wrong answrs
size=default(size, 1)
f=pow(2,8*size*2)
p2=floor(n/f)
n=n-p2*f
f=pow(2,8*size*1)
p1=floor(n/f)
n=n-p1*f
p0=n
int(p==0?p0:p==1?p1:p2)
}
Last edited by jmac698; 9th November 2011 at 19:26. Reason: Updated |
|
|
|
| Thread Tools | Search this Thread |
| Display Modes | |
|
|