Announcement

Collapse
No announcement yet.

Discussion for PB_Blur example code

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Discussion for PB_Blur example code

    https://forum.powerbasic.com/forum/u...rol#post776659
    I posted a blur program.
    The code that does the blurring is a single SUB.
    It's not fancy, and it doesn't have a variable range of inclusion for the averaging.
    But it does work nicely enough.
    Code:
    SUB PB_blur(dlg AS DWORD, ctl AS LONG, iterations AS LONG)
        ' adjusting number of iterations extends the blur by bleeding into an extended area.
        ' actually increasing the amount of blur requires extending the area averaged.
        ' the processes are similar, but distinct in their results
        LOCAL avg, x, y, xc, yc, hbmp AS LONG, xy AS LONG PTR, bufr, blr AS STRING, pxls(), blur() AS bgra
        GRAPHIC ATTACH dlg, ctl, REDRAW
        GRAPHIC GET BITS TO bufr
        xy = STRPTR(bufr)
        x = @xy[0] - 1
        y = @xy[1] - 1
        REDIM pxls(x, y) AT STRPTR(bufr) + 8
        FOR avg = 1 TO iterations
            ' Using a separate copy of the image, average from the original and store in the edited version.
            ' By updating the reference copy for each iteration, the reiteratioin bleed-thru is made possible.
            ' The amount of blur is also adjustable by weighting of the pixel being altered.
            ' For instance, you can double the r, g, and b for the pixel being altered, and add 1 to the division step.
            ' That would reduce the amount of interaction between pixel states.
            blr = bufr
            REDIM blur(x, y) AT STRPTR(blr) + 8
            pxls(0, 0).r = (blur(0, 0).r + blur(1, 1).r + blur(0, 1).r + blur(1, 0).r) \ 4
            pxls(x, y).r = (blur(x, y).r + blur(x - 1, y - 1).r + blur(x, y - 1).r + blur(x - 1, y).r) \ 4
            pxls(x, 0).r = (blur(x, 0).r + blur(x - 1, 1).r + blur(x, y + 1).r + blur(x - 1, 0).r) \ 4
            pxls(0, y).r = (blur(0, y).r + blur(1, y - 1).r + blur(1, y).r + blur(0, y - 1).r) \ 4
    
            pxls(0, 0).b = (blur(0, 0).b + blur(1, 1).b + blur(0, 1).b + blur(1, 0).b) \ 4
            pxls(x, y).b = (blur(x, y).b + blur(x - 1, y - 1).b + blur(x, y - 1).b + blur(x - 1, y).b) \ 4
            pxls(x, 0).b = (blur(x, 0).b + blur(x - 1, 1).b + blur(x, y + 1).b + blur(x - 1, 0).b) \ 4
            pxls(0, y).b = (blur(0, y).b + blur(1, y - 1).b + blur(1, y).b + blur(0, y - 1).b) \ 4
    
            pxls(0, 0).g = (blur(0, 0).g + blur(1, 1).g + blur(0, 1).g + blur(1, 0).g) \ 4
            pxls(x, y).g = (blur(x, y).g + blur(x - 1, y - 1).g + blur(x, y - 1).g + blur(x - 1, y).g) \ 4
            pxls(x, 0).g = (blur(x, 0).g + blur(x - 1, 1).g + blur(x, y + 1).g + blur(x - 1, 0).g) \ 4
            pxls(0, y).g = (blur(0, y).g + blur(1, y - 1).g + blur(1, y).g + blur(0, y - 1).g) \ 4
            FOR xc = 1 TO x - 1
                pxls(xc, 0).r = (blur(xc - 1, 0).r + blur(xc, 0).r + blur(xc + 1, 0).r + blur(xc - 1, 1).r + blur(xc, 1).r + blur(xc + 1, 1).r) \ 6
                pxls(xc, 0).g = (blur(xc - 1, 0).g + blur(xc, 0).g + blur(xc + 1, 0).g + blur(xc - 1, 1).g + blur(xc, 1).g + blur(xc + 1, 1).g) \ 6
                pxls(xc, 0).b = (blur(xc - 1, 0).b + blur(xc, 0).b + blur(xc + 1, 0).b + blur(xc - 1, 1).b + blur(xc, 1).b + blur(xc + 1, 1).b) \ 6
                pxls(xc, y).r = (blur(xc - 1, y).r + blur(xc, y).r + blur(xc + 1, y).r + blur(xc - 1, y - 1).r + blur(xc, y - 1).r + blur(xc + 1, y - 1).r) \ 6
                pxls(xc, y).g = (blur(xc - 1, y).g + blur(xc, y).g + blur(xc + 1, y).g + blur(xc - 1, y - 1).g + blur(xc, y - 1).g + blur(xc + 1, y - 1).g) \ 6
                pxls(xc, y).b = (blur(xc - 1, y).b + blur(xc, y).b + blur(xc + 1, y).b + blur(xc - 1, y - 1).b + blur(xc, y - 1).b + blur(xc + 1, y - 1).b) \ 6
            NEXT
            FOR yc = 1 TO y - 1
                pxls(x, yc).r = (blur(x - 1, yc - 1).r + blur(x - 1, yc).r + blur(x - 1, yc + 1).r + blur(x, yc - 1).r + blur(x, yc).r + blur(x, yc + 1).r) \ 6
                pxls(x, yc).g = (blur(x - 1, yc - 1).g + blur(x - 1, yc).g + blur(x - 1, yc + 1).g + blur(x, yc - 1).g + blur(x, yc).g + blur(x, yc + 1).g) \ 6
                pxls(x, yc).b = (blur(x - 1, yc - 1).b + blur(x - 1, yc).b + blur(x - 1, yc + 1).b + blur(x, yc - 1).b + blur(x, yc).b + blur(x, yc + 1).b) \ 6
                pxls(0, yc).r = (blur(0, yc - 1).r + blur(0, yc).r + blur(0, yc + 1).r + blur(1, yc - 1).r + blur(1, yc).r + blur(1, yc + 1).r) \ 6
                pxls(0, yc).g = (blur(0, yc - 1).g + blur(0, yc).g + blur(0, yc + 1).g + blur(1, yc - 1).g + blur(1, yc).g + blur(1, yc + 1).g) \ 6
                pxls(0, yc).b = (blur(0, yc - 1).b + blur(0, yc).b + blur(0, yc + 1).b + blur(1, yc - 1).b + blur(1, yc).b + blur(1, yc + 1).b) \ 6
            NEXT
            FOR xc = 1 TO x - 1
                FOR yc = 1 TO y - 1
                    pxls(xc, yc).r = (blur(xc - 1, yc - 1).r + blur(xc - 1, yc).r + blur(xc - 1, yc + 1).r + blur(xc, yc - 1).r + blur(xc, yc).r + blur(xc, yc + 1).r + blur(xc + 1, yc - 1).r + blur(xc + 1, yc).r + blur(xc + 1, yc + 1).r) \ 9
                    pxls(xc, yc).g = (blur(xc - 1, yc - 1).g + blur(xc - 1, yc).g + blur(xc - 1, yc + 1).g + blur(xc, yc - 1).g + blur(xc, yc).g + blur(xc, yc + 1).g + blur(xc + 1, yc - 1).g + blur(xc + 1, yc).g + blur(xc + 1, yc + 1).g) \ 9
                    pxls(xc, yc).b = (blur(xc - 1, yc - 1).b + blur(xc - 1, yc).b + blur(xc - 1, yc + 1).b + blur(xc, yc - 1).b + blur(xc, yc).b + blur(xc, yc + 1).b + blur(xc + 1, yc - 1).b + blur(xc + 1, yc).b + blur(xc + 1, yc + 1).b) \ 9
                NEXT
            NEXT
        NEXT
        GRAPHIC SET BITS bufr
        GRAPHIC REDRAW
    END SUB
    The world is strange and wonderful.*
    I reserve the right to be horrifically wrong.
    Please maintain a safe following distance.
    *wonderful sold separately.

  • #2
    Updated code available, same thread as above.
    Added, weighting of pixels to allow better control of blurring.
    This refinement will allow me to apply the blur code to a dithering process
    in placing text on graphic controls and bitmaps.
    The world is strange and wonderful.*
    I reserve the right to be horrifically wrong.
    Please maintain a safe following distance.
    *wonderful sold separately.

    Comment


    • #3
      I've run your code, and I like it, but I've not examined the code. Have you considered reversing the process to bring something into focus, like images that fade into the background then back to foreground on some trigger?
      Rod
      "To every unsung hero in the universe
      To those who roam the skies and those who roam the earth
      To all good men of reason may they never thirst " - from "Heaven Help the Devil" by G. Lightfoot

      Comment


      • #4
        Kurt,
        Nice work!. I just spent 30 minutes look at your code, then wandering the web looking for other code. I am so easily distracted with new toys!

        Are there significantly simpler algorithms? Is there a defining benefit of the algorithm that you chose? Does it have an official name, such as a "Gaussian Blur". Anything you can say to put in context with other approaches would be of interest.

        Comment


        • #5
          Originally posted by Gary Beene View Post
          Kurt,
          Nice work!. I just spent 30 minutes look at your code, then wandering the web looking for other code. I am so easily distracted with new toys!

          Are there significantly simpler algorithms? Is there a defining benefit of the algorithm that you chose? Does it have an official name, such as a "Gaussian Blur". Anything you can say to put in context with other approaches would be of interest.
          I'm not sure. It is likely an average blur.
          There is a flaw in the corners, too, which left them improperly processed.
          This is about as simple as they get, really.
          It takes the adjoining pixels and adds them all up and uses the average of all.
          The weighting allows the pixel to retain more of its original value.
          If you just use the average of the pixel being manipulated and its near surroundings,
          it doesn't allow for much variability.
          This algorithm doesn't do much, really. Most of the code is just unwound from the
          loops needed too access each pixel, and removes the need for logic branching for
          the edges and corners. The final FOR/NEXT loop handles the body of the graphic object.
          As you can see, it is really only three lines of code, one for each color for each pixel.
          All the rest is just to keep that last part from having complex branching to handle the
          corners and edges.
          The corrected code is this:
          Code:
          SUB PB_gradblur(dlg AS DWORD, ctl AS LONG, iterations AS LONG, strength AS LONG)
              ' adjusting number of iterations extends the blur by bleeding into an extended area.
              ' adjusting strengt of blur reduces bleedover.
              LOCAL avg, x, y, xc, yc, hbmp, weight AS LONG, xy AS LONG PTR, bufr, blr AS STRING, pxls(), blur() AS bgra
              weight = 32 - (strength AND 31)
              GRAPHIC ATTACH dlg, ctl, REDRAW
              GRAPHIC GET BITS TO bufr
              xy = STRPTR(bufr)
              x = @xy[0] - 1
              y = @xy[1] - 1
              REDIM pxls(x, y) AT STRPTR(bufr) + 8
              FOR avg = 0 TO iterations
                  ' Using a separate copy of the image, average from the original and store in the edited version.
                  ' By updating the reference copy for each iteration, the reiteratioin bleed-thru is made possible.
                  blr = bufr
                  REDIM blur(x, y) AT STRPTR(blr) + 8
                  pxls(0, 0).r = (weight * blur(0, 0).r + blur(1, 1).r + blur(0, 1).r + blur(1, 0).r) \ (weight + 3)
                  pxls(0, 0).b = (weight * blur(0, 0).b + blur(1, 1).b + blur(0, 1).b + blur(1, 0).b) \ (weight + 3)
                  pxls(0, 0).g = (weight * blur(0, 0).g + blur(1, 1).g + blur(0, 1).g + blur(1, 0).g) \ (weight + 3)
          
                  pxls(x, y).r = (weight * blur(x, y).r + blur(x - 1, y - 1).r + blur(x, y - 1).r + blur(x - 1, y).r) \ (weight + 3)
                  pxls(x, y).b = (weight * blur(x, y).b + blur(x - 1, y - 1).b + blur(x, y - 1).b + blur(x - 1, y).b) \ (weight + 3)
                  pxls(x, y).g = (weight * blur(x, y).g + blur(x - 1, y - 1).g + blur(x, y - 1).g + blur(x - 1, y).g) \ (weight + 3)
          
                  pxls(x, 0).r = (weight * blur(x, 0).r + blur(x - 1, 1).r + blur(x, y + 1).r + blur(x - 1, 0).r) \ (weight + 3)
                  pxls(x, 0).b = (weight * blur(x, 0).b + blur(x - 1, 1).b + blur(x, y + 1).b + blur(x - 1, 0).b) \ (weight + 3)
                  pxls(x, 0).g = (weight * blur(x, 0).g + blur(x - 1, 1).g + blur(x, y + 1).g + blur(x - 1, 0).g) \ (weight + 3)
          
                  pxls(0, y).r = (weight * blur(0, y).r + blur(1, y - 1).r + blur(1, y).r + blur(0, y - 1).r) \ (weight + 3)
                  pxls(0, y).b = (weight * blur(0, y).b + blur(1, y - 1).b + blur(1, y).b + blur(0, y - 1).b) \ (weight + 3)
                  pxls(0, y).g = (weight * blur(0, y).g + blur(1, y - 1).g + blur(1, y).g + blur(0, y - 1).g) \ (weight + 3)
          
                  FOR xc = 1 TO x - 1
                      pxls(xc, 0).r = (blur(xc - 1, 0).r + weight * blur(xc, 0).r + blur(xc + 1, 0).r + blur(xc - 1, 1).r + blur(xc, 1).r + blur(xc + 1, 1).r) \ (weight + 5)
                      pxls(xc, 0).g = (blur(xc - 1, 0).g + weight * blur(xc, 0).g + blur(xc + 1, 0).g + blur(xc - 1, 1).g + blur(xc, 1).g + blur(xc + 1, 1).g) \ (weight + 5)
                      pxls(xc, 0).b = (blur(xc - 1, 0).b + weight * blur(xc, 0).b + blur(xc + 1, 0).b + blur(xc - 1, 1).b + blur(xc, 1).b + blur(xc + 1, 1).b) \ (weight + 5)
                      pxls(xc, y).r = (blur(xc - 1, y).r + weight * blur(xc, y).r + blur(xc + 1, y).r + blur(xc - 1, y - 1).r + blur(xc, y - 1).r + blur(xc + 1, y - 1).r) \ (weight + 5)
                      pxls(xc, y).g = (blur(xc - 1, y).g + weight * blur(xc, y).g + blur(xc + 1, y).g + blur(xc - 1, y - 1).g + blur(xc, y - 1).g + blur(xc + 1, y - 1).g) \ (weight + 5)
                      pxls(xc, y).b = (blur(xc - 1, y).b + weight * blur(xc, y).b + blur(xc + 1, y).b + blur(xc - 1, y - 1).b + blur(xc, y - 1).b + blur(xc + 1, y - 1).b) \ (weight + 5)
                  NEXT
                  FOR yc = 1 TO y - 1
                      pxls(x, yc).r = (blur(x - 1, yc - 1).r + blur(x - 1, yc).r + blur(x - 1, yc + 1).r + blur(x, yc - 1).r + weight * blur(x, yc).r + blur(x, yc + 1).r) \ (weight + 5)
                      pxls(x, yc).g = (blur(x - 1, yc - 1).g + blur(x - 1, yc).g + blur(x - 1, yc + 1).g + blur(x, yc - 1).g + weight * blur(x, yc).g + blur(x, yc + 1).g) \ (weight + 5)
                      pxls(x, yc).b = (blur(x - 1, yc - 1).b + blur(x - 1, yc).b + blur(x - 1, yc + 1).b + blur(x, yc - 1).b + weight * blur(x, yc).b + blur(x, yc + 1).b) \ (weight + 5)
                      pxls(0, yc).r = (blur(0, yc - 1).r + weight * blur(0, yc).r + blur(0, yc + 1).r + blur(1, yc - 1).r + blur(1, yc).r + blur(1, yc + 1).r) \ (weight + 5)
                      pxls(0, yc).g = (blur(0, yc - 1).g + weight * blur(0, yc).g + blur(0, yc + 1).g + blur(1, yc - 1).g + blur(1, yc).g + blur(1, yc + 1).g) \ (weight + 5)
                      pxls(0, yc).b = (blur(0, yc - 1).b + weight * blur(0, yc).b + blur(0, yc + 1).b + blur(1, yc - 1).b + blur(1, yc).b + blur(1, yc + 1).b) \ (weight + 5)
                  NEXT
                  FOR xc = 1 TO x - 1
                      FOR yc = 1 TO y - 1
                          pxls(xc, yc).r = (blur(xc-1, yc-1).r + blur(xc-1, yc).r + blur(xc-1, yc+1).r + blur(xc, yc-1).r + weight * blur(xc, yc).r + blur(xc, yc+1).r + blur(xc+1, yc-1).r + blur(xc+1, yc).r + blur(xc+1, yc+1).r) \ (weight+8)
                          pxls(xc, yc).g = (blur(xc-1, yc-1).g + blur(xc-1, yc).g + blur(xc-1, yc+1).g + blur(xc, yc-1).g + weight * blur(xc, yc).g + blur(xc, yc+1).g + blur(xc+1, yc-1).g + blur(xc+1, yc).g + blur(xc+1, yc+1).g) \ (weight+8)
                          pxls(xc, yc).b = (blur(xc-1, yc-1).b + blur(xc-1, yc).b + blur(xc-1, yc+1).b + blur(xc, yc-1).b + weight * blur(xc, yc).b + blur(xc, yc+1).b + blur(xc+1, yc-1).b + blur(xc+1, yc).b + blur(xc+1, yc+1).b) \ (weight+8)
                      NEXT
                  NEXT
              NEXT
              GRAPHIC SET BITS bufr
              GRAPHIC REDRAW
          END SUB
          The world is strange and wonderful.*
          I reserve the right to be horrifically wrong.
          Please maintain a safe following distance.
          *wonderful sold separately.

          Comment


          • #6
            If you're working with just graphic windows, you might find this useful, "Another way to blur a picture":

            https://forum.powerbasic.com/forum/u...icture?t=54031
            Politically incorrect signatures about immigration patriots are forbidden. Googling “immigration patriots” is forbidden. Thinking about Googling ... well, don’t even think about it.

            Comment


            • #7
              Originally posted by Kurt Kuzba View Post
              Code:
              REDIM pxls(x, y) AT STRPTR(bufr) + 8
              FOR avg = 0 TO iterations
                  ' Using a separate copy of the image, average from the original and store in the edited version.
                  ' By updating the reference copy for each iteration, the reiteratioin bleed-thru is made possible.
                  blr = bufr
                  REDIM blur(x, y) AT STRPTR(blr) + 8
              
              ...
              Maybe I'm just being a little dense today, but I don't see where you're creating a separate copy of your image. It looks like just a second pixel array DIMmed AT the same memory address as the first?
              Dan

              Comment


              • #8
                Originally posted by Dan Soper View Post
                Maybe I'm just being a little dense today, but I don't see where you're creating a separate copy of your image. It looks like just a second pixel array DIMmed AT the same memory address as the first?
                I didn't! I created a copy of the string in which the image resides as bits.
                I didn't need another GRAPHIC object just to create a new identical string.
                The world is strange and wonderful.*
                I reserve the right to be horrifically wrong.
                Please maintain a safe following distance.
                *wonderful sold separately.

                Comment


                • #9
                  Originally posted by Kurt Kuzba View Post

                  I didn't! I created a copy of the string in which the image resides as bits.
                  I didn't need another GRAPHIC object just to create a new identical string.
                  Oh yes, so you did. For some reason I thought the line
                  Code:
                  blr = bufr
                  was copying a pointer and not the data.

                  I did say I was being dense!
                  Dan

                  Comment


                  • #10
                    Originally posted by Dan Soper View Post

                    Oh yes, so you did. For some reason I thought the line
                    Code:
                    blr = bufr
                    was copying a pointer and not the data.

                    I did say I was being dense!
                    It was one of those things where I literally hacked my through using brute force.
                    No elegant and insightful soaring algorithms here, just menial, mind-numbing drudgery.
                    But it works, and that was what I wanted.
                    I could have avoided any confusion by naming conventions that better documented the variables.
                    The code to print transparently onto an image background will be similarly utilitarian
                    and has already taken a few sharp turns from the original vision.
                    The world is strange and wonderful.*
                    I reserve the right to be horrifically wrong.
                    Please maintain a safe following distance.
                    *wonderful sold separately.

                    Comment

                    Working...
                    X