Forum Discussion

Fusioni-Dev's avatar
Fusioni-Dev
Reel Rookie
3 years ago

how can create dynamic gradient?

We want to use dynamic gradient in our roku app. Is there any way to create it?

Please help.

14 Replies

  • 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)

     

    • Fusioni-Dev's avatar
      Fusioni-Dev
      Reel Rookie

       

      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.

      • TwitchBronBron's avatar
        TwitchBronBron
        Streaming Star

        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.