We want to use dynamic gradient in our roku app. Is there any way to create it?
Please help.
Not nicely, no. There's no css-style gradient support.
You would need to create a roBitmap, and then write rectangles to represent the gradient.
Then write it to tmp:
Then pass the uri out to the poster node (or wherever needs to read it)
w = 1920
h = 1080
bm = CreateObject("roBitmap", {width: w, height: h, AlphaEnable: false})
bm.DrawRect(10, 10, w-20, h-20, &H8080)
bm.Finish()
ba = bm.GetPng(0, 0, w, h)
ba.WriteFile("tmp:/test.png")
Use this but it doesn't look like gradient.
Here's a function you can use to generate vertical and horizontal linear gradients. Keep in mind, this function takes over 1000ms on my streaming stick 4k for a 1920x1080 image, so use it sparingly.
function GenerateGradient(width as integer, height as integer, startRgba as longinteger, endRgba as longinteger, lineDirection = "vertical")
bitmap = CreateObject("roBitmap", { width: width, height: height, alphaEnable: true })
'draw vertical lines from left to right
if lineDirection = "vertical" then
numSteps# = width
'draw horizontal lines from top to bottom
else
numSteps# = height
end if
' separate rgba values to compute the step between each gradient band
red# = (startRgba and &hFF000000&) >> 24
redEnd# = (endRgba and &hFF000000&) >> 24
redStep# = (redEnd# - red#) / numSteps#
blue# = (startRgba and &h00FF0000&) >> 16
blueEnd# = (endRgba and &h00FF0000&) >> 16
blueStep# = (blueEnd# - blue#) / numSteps#
green# = (startRgba and &h0000FF00&) >> 8
greenEnd# = (endRgba and &h0000FF00&) >> 8
greenStep# = (greenEnd# - green#) / numSteps#
alpha# = startRgba and &h000000FF&
alphaEnd# = endRgba and &h000000FF&
alphaStep# = (alphaEnd# - alpha#) / numSteps#
for i = 0 to numSteps#
red# += redStep#
blue# += blueStep#
green# += greenStep#
alpha# += alphaStep#
'merge rgb into single int
color& = (Int(red#) << 24) + (Int(blue#) << 16) + (Int(green#) << + (Int(alpha#))
if lineDirection = "vertical" then
'draw a line at (i, 0) for the full height of the image
bitmap.DrawRect(i, 0, 1, height, color&)
else
'draw a line at (0, i) for the full width of the image
bitmap.DrawRect(0, i, width, 1, color&)
end if
end for
bitmap.Finish()
png = bitmap.GetPng(0, 0, width, height)
uri = "tmp:/linear-gradient-" + str(width) + "x" + str(height) + "-0x" + stri(startRgba, 16) + "-0x" + stri(endRgba, 16) + "-" + lineDirection + ".png"
png.WriteFile(uri)
return uri
end function
And you can call it like this:
verticalGradientUrl = GenerateGradient(1920, 1080, &h00000000, &hFF0000FF, "vertical")
horizontalGradientUrl = GenerateGradient(1920, 1080, &h00000000, &hFF0000FF, "horizontal")
The function has not been optimized, meaning it will draw a line for every pixel in the gradient, even if several lines would have the exact same color. It could be optimized to draw a rectangle that is as big as the height/width of the color band.
If you're in control of the poster size, then you should consider generating a gradient that's 1 pixel in the opposing direction. (i.e. 1920x1 or 1x1080), then you can stretch the poster to the size you need in that opposing direction.