Announcement

Collapse
No announcement yet.

Discussion for PB_Blur example code

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

  • Kurt Kuzba
    started a topic Discussion for PB_Blur example code

    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

  • Kurt Kuzba
    replied
    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.

    Leave a comment:


  • Dan Soper
    replied
    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!

    Leave a comment:


  • Kurt Kuzba
    replied
    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.

    Leave a comment:


  • Dan Soper
    replied
    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?

    Leave a comment:


  • Mark Hunter
    replied
    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

    Leave a comment:


  • Kurt Kuzba
    replied
    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

    Leave a comment:


  • Gary Beene
    replied
    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.

    Leave a comment:


  • Rodney Hicks
    replied
    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?

    Leave a comment:


  • Kurt Kuzba
    replied
    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.

    Leave a comment:

Working...
X