Announcement

Collapse
No announcement yet.

Anti-Aliasing, Again

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

  • #21
    Originally posted by Chris Boss View Post
    When you consider the typical Image/Graphic editing software image filters one usually has filters such as improve contrast, sharpen and smooth. Improving contrast (or sharpen) decreases smoothness. Smoothing an image decreases contrast. They are opposed to each other. What you want is both ! Smooth the image to decrease pixilation but also sharpen the image for better readability.
    It's going to take at least two filters. One to smooth, and then one to sharpen.
    They do opposite things, but a sharpened image that is smoothed is way
    different from a smoothed image that is sharpened.
    The world of image filters is deep and wide.
    The world is strange and wonderful.*
    I reserve the right to be horrifically wrong.
    Please maintain a safe following distance.
    *wonderful sold separately.

    Comment


    • #22
      Chris/Kurt!
      It's a good thing I have some folks who can act as my life preserver, else I would drown in the ocean of options! sea of solutions! flood of filters! ... feeling poetic this morning ...

      Comment


      • #23
        Originally posted by Gary Beene View Post
        It's a good thing I have some folks who can act as my life preserver, else I would drown in the ocean of options! sea of solutions! flood of filters! ... feeling poetic this morning ...
        Gaussian filter with contrast enhancement.
        I think it still needs a smoothing routine, but the results are better than
        the direct magnification image when you run the magnified image through
        the gnorm() function.
        The contrast enhancement will work with positive or negative values.
        The steps are rather close, so a value of 100 works well in this example.
        I'm going to see if I can work out a simple smoothing routine that will
        blur the image while preserving edges.
        I'm thinking of checking the absolute difference between pixels and using
        the target pixel value instead of the neighbor pixel value if the difference is
        beyond a threshold value to where it is a clearly different color.
        The contrast enhancement is very simple. It expands the range of 0-255
        to one that is greater, then clips the results to fit a byte, maxing the range.
        I included a branch, (if x mod 4), to avoid handling the alpha byte.
        But I haven't run tests to see if it saves CPU cycles.
        Code:
        FUNCTION gnorm(STR_src AS STRING) AS STRING
            LOCAL STR_nrm, STR_buf AS STRING, xL, yL, x, y, c, cxy, prcnt AS LONG
            LOCAL BPTR_nrm AS BYTE POINTER, LPTR_buf AS LONG POINTER, PXs(), PXd() AS bgra
            STR_buf = EnhanceContrast(STR_src, 100)
            STR_nrm = STR_src
            LPTR_buf = STRPTR(STR_buf)
            xL = @LPTR_buf
            yL = @LPTR_buf[1]
            REDIM PXs(xL - 1, yL - 1) AT STRPTR(STR_buf) + 8
            REDIM PXd(xL - 1, yL - 1) AT STRPTR(STR_nrm) + 8
            FOR x = 2 TO xL - 3
                FOR y = 0 TO yL - 1
                    PXd(x,y).b = (PXs(x-2,y).b+PXs(x-1,y).b*6+PXs(x,y).b*21+PXs(x+1,y).b*6+PXs(x+2,y).b)\35
                    PXd(x,y).g = (PXs(x-2,y).g+PXs(x-1,y).g*6+PXs(x,y).g*21+PXs(x+1,y).g*6+PXs(x+2,y).g)\35
                    PXd(x,y).r = (PXs(x-2,y).r+PXs(x-1,y).r*6+PXs(x,y).r*21+PXs(x+1,y).r*6+PXs(x+2,y).r)\35
                NEXT
            NEXT
            STR_buf = STR_nrm
            FOR y = 2 TO yL - 3
                FOR x = 0 TO xL - 1
                    PXd(x,y).b = (PXs(x,y-2).b+PXs(x,y-1).b*6+PXs(x,y).b*21+PXs(x,y+1).b*6+PXs(x,y+2).b)\35
                    PXd(x,y).g = (PXs(x,y-2).g+PXs(x,y-1).g*6+PXs(x,y).g*21+PXs(x,y+1).g*6+PXs(x,y+2).g)\35
                    PXd(x,y).r = (PXs(x,y-2).r+PXs(x,y-1).r*6+PXs(x,y).r*21+PXs(x,y+1).r*6+PXs(x,y+2).r)\35
                NEXT
            NEXT
            FUNCTION = STR_nrm
        END FUNCTION
        FUNCTION EnhanceContrast(STR_src AS STRING, boost AS LONG) AS STRING
            LOCAL c, x, dv, median AS LONG, BPTR_buf AS BYTE POINTER, STR_buf AS STRING
            dv = 255 + boost
            median = boost \ 2
            STR_buf = STR_src
            BPTR_buf = STRPTR(STR_buf)
            FOR x = 8 TO LEN(STR_buf) - 1
                IF (x MOD 4) THEN
                    c = ((@BPTR_buf[x] * dv) \ 255) - median
                    SELECT CASE c
                        CASE > 255 : @BPTR_buf[x] = 255
                        CASE < 0   : @BPTR_buf[x] =   0
                        CASE ELSE  : @BPTR_buf[x] =   c
                    END SELECT
                END IF
            NEXT
            FUNCTION = STR_buf
        END FUNCTION
        The world is strange and wonderful.*
        I reserve the right to be horrifically wrong.
        Please maintain a safe following distance.
        *wonderful sold separately.

        Comment


        • #24
          The function to enhance contrast is slowed significantly by the test for alpha channel.
          This is better. What it does is expand the range of pixels from 255 to a larger spread.
          Then it centers the range and truncates at both ends, using 0 Min. and 255 Max..
          Used in conjunction with the gaussian normalization, it makes the magnified image
          clearer. While a smoothing routine might be useful, it may be too CPU cycle intensive
          to be useful for an on-the-fly magnification process.
          One could replace the gaussian normalization with a smoothing routine that would
          preserve edges where a greater difference in pixel value levels was observed, but
          that would also eliminate the desirable edge smoothing of the normalization blur.
          Code:
          FUNCTION EnhanceContrast(STR_src AS STRING, boost AS LONG) AS STRING
              LOCAL c, x, dv, median AS LONG, BPTR_buf AS BYTE POINTER, STR_buf AS STRING
              dv = 255 + boost
              median = boost \ 2
              STR_buf = STR_src
              BPTR_buf = STRPTR(STR_buf)
              FOR x = 8 TO LEN(STR_buf) - 1
                  c = ((@BPTR_buf[x] * dv) \ 255) - median
                  SELECT CASE c
                      CASE > 255 : @BPTR_buf[x] = 255
                      CASE < 0   : @BPTR_buf[x] =   0
                      CASE ELSE  : @BPTR_buf[x] =   c
                  END SELECT
              NEXT
              FUNCTION = STR_buf
          END FUNCTION
          The world is strange and wonderful.*
          I reserve the right to be horrifically wrong.
          Please maintain a safe following distance.
          *wonderful sold separately.

          Comment


          • #25
            Kurt, thanks for the latest posts. I'm a bit stretched right now and may not get to testing until later today.

            Comment


            • #26
              Originally posted by Gary Beene View Post
              Kurt, thanks for the latest posts. I'm a bit stretched right now and may not get to testing until later today.
              Speaking of "stretched".
              I think it's working pretty well in this present form.
              I put a thumbnail of the screen in the lower left hand corner.
              Clicking on it selects the screen area to be viewed.
              The contrast enhancement works pretty well.
              Code:
              #COMPILE EXE
              #DIM ALL
              #DEBUG DISPLAY
              #INCLUDE "win32api.inc"
              ENUM ctrls SINGULAR
                  grfx = 500
                  grfxmag
                  grfxmagblur
                  viewport
                  bgimage
                  lbl01
                  lbl02
              END ENUM
              
              TYPE bgra
                  b AS BYTE
                  g AS BYTE
                  r AS BYTE
                  a AS BYTE
              END TYPE
              
              FUNCTION PBMAIN () AS LONG
                  LOCAL hWin, xitcode, hfont AS LONG
                  FONT NEW "", 14 TO hfont
                  RANDOMIZE
                  DIALOG NEW PIXELS, 0, "Magnify Test", , , 732, 530, %WS_BORDER OR %WS_CAPTION OR %WS_SYSMENU TO hWin
                  DIALOG SET COLOR hWin, %WHITE, %BLACK
                  CONTROL ADD BUTTON, hWin, %bgimage, "Refresh Background",  3, 1, 240, 24
                  CONTROL ADD LABEL, hWin, %lbl01, "Plain Magnified View", 246, 1, 240, 25, %SS_CENTER
                  CONTROL ADD LABEL, hWin, %lbl02, "Enhanced Magnified View", 489, 1, 240, 25, %SS_CENTER
                  CONTROL SET COLOR hWin, %lbl01, %GREEN, %BLACK
                  CONTROL SET FONT hWin, %lbl01, hfont
                  CONTROL SET COLOR hWin, %lbl02, %GREEN, %BLACK
                  CONTROL SET FONT hWin, %lbl02, hfont
                  CONTROL ADD GRAPHIC, hWin, %grfx, "", 3, 26, 240, 360
                  GRAPHIC ATTACH hWin, %grfx
                  GRAPHIC CLEAR %BLACK
                  CONTROL ADD GRAPHIC, hWin, %viewport, "", 3, 389, 240, 135, %SS_NOTIFY
                  GRAPHIC ATTACH hWin, %viewport
                  GRAPHIC CLEAR %BLACK
                  CONTROL ADD GRAPHIC, hWin, %grfxmag, "", 246, 26, 240, 500
                  GRAPHIC ATTACH hWin, %grfxmag
                  GRAPHIC CLEAR %BLACK
                  CONTROL ADD GRAPHIC, hWin, %grfxmagblur, "", 489, 26, 240, 500
                  GRAPHIC ATTACH hWin, %grfxmagblur
                  GRAPHIC CLEAR %BLACK
                  DIALOG SHOW MODAL hWin, CALL dlgproc() TO xitcode
                  FONT END hfont
                  FUNCTION = xitcode
              END FUNCTION
              
              CALLBACK FUNCTION dlgproc()
                  LOCAL getvalue AS STRING, xy AS POINT, hwnd AS DWORD
                  SELECT CASE CB.MSG
                      CASE %WM_INITDIALOG
                          DIALOG POST CB.HNDL, %WM_COMMAND, %bgimage, %BN_CLICKED
                      CASE %WM_COMMAND
                          SELECT CASE CB.CTL
                              CASE %bgimage
                                  IF CB.CTLMSG = %BN_CLICKED THEN
                                      get_background CB.HNDL, %grfx, %viewport
                                      GRAPHIC ATTACH CB.HNDL, %grfxmag, REDRAW
                                      GRAPHIC STRETCH CB.HNDL, %grfx, (0, 0)-(59, 124) TO (0, 0)-(239,499), 0, %HALFTONE
                                      GRAPHIC REDRAW
                                      GRAPHIC GET BITS TO getvalue
                                      GRAPHIC ATTACH CB.HNDL, %grfxmagblur, REDRAW
                                      GRAPHIC STRETCH CB.HNDL, %grfx, (0, 0)-(59, 124) TO (0, 0)-(239, 499), 0, %HALFTONE
                                      GRAPHIC GET BITS TO getvalue
                                      getvalue = gnorm(getvalue)
                                      GRAPHIC SET BITS getvalue
                                      GRAPHIC REDRAW
                                  END IF
                              CASE %viewport
                                  IF CB.CTLMSG = %stn_clicked THEN
                                      getcursorpos(xy)
                                      CONTROL HANDLE CB.HNDL, CB.CTL TO hwnd
                                      screentoclient(hwnd, xy)
                                      CONTROL SET USER CB.HNDL, CB.CTL, 1, xy.x
                                      CONTROL SET USER CB.HNDL, CB.CTL, 2, xy.y
                                  END IF
                                  DIALOG POST CB.HNDL, %WM_COMMAND, %bgimage, %BN_CLICKED
                          END SELECT
                  END SELECT
              END FUNCTION
              
              SUB get_background(dlg AS DWORD, ctl AS LONG, v AS LONG)
                  LOCAL DC_desktop, DC_ctl, hbmp AS DWORD, x, y, xx, yy, scx, scy, vx, vy AS LONG
                  scx = METRICS(MAXIMIZED.X)
                  scy = METRICS(MAXIMIZED.Y)
                  CONTROL GET SIZE dlg, ctl TO x, y
                  CONTROL GET USER dlg, v, 1 TO xx
                  CONTROL GET USER dlg, v, 2 TO yy
                  CONTROL GET SIZE dlg, v TO vx, vy
                  xx = xx * scx \ vx
                  yy = yy * scy \ vy
                  DC_desktop = getdc(0)
                  GRAPHIC ATTACH dlg, ctl, REDRAW
                  GRAPHIC CLEAR %BLACK
                  GRAPHIC GET DC TO DC_ctl
                  bitblt(DC_ctl, 0, 0, x, y, DC_desktop, xx, yy, %srccopy)
                  GRAPHIC REDRAW
                  GRAPHIC ATTACH dlg, v, REDRAW
                  GRAPHIC GET DC TO DC_ctl
                  stretchblt(DC_ctl, 0, 0, vx, vy, DC_desktop, 0, 0, scx, scy, %srccopy)
                  GRAPHIC REDRAW
                  releasedc(0, DC_desktop)
              END SUB
              
              FUNCTION gnorm(STR_src AS STRING) AS STRING
                  LOCAL STR_nrm, STR_buf AS STRING, xL, yL, x, y, c, cxy, prcnt AS LONG
                  LOCAL BPTR_nrm AS BYTE POINTER, LPTR_buf AS LONG POINTER, PXs(), PXd() AS bgra
                  STR_buf = EnhanceContrast(STR_src, 100)
                  STR_nrm = STR_src
                  LPTR_buf = STRPTR(STR_buf)
                  xL = @LPTR_buf
                  yL = @LPTR_buf[1]
                  REDIM PXs(xL - 1, yL - 1) AT STRPTR(STR_buf) + 8
                  REDIM PXd(xL - 1, yL - 1) AT STRPTR(STR_nrm) + 8
                  FOR x = 2 TO xL - 3
                      FOR y = 0 TO yL - 1
                          PXd(x,y).b = (PXs(x-2,y).b+PXs(x-1,y).b*6+PXs(x,y).b*21+PXs(x+1,y).b*6+PXs(x+2,y).b)\35
                          PXd(x,y).g = (PXs(x-2,y).g+PXs(x-1,y).g*6+PXs(x,y).g*21+PXs(x+1,y).g*6+PXs(x+2,y).g)\35
                          PXd(x,y).r = (PXs(x-2,y).r+PXs(x-1,y).r*6+PXs(x,y).r*21+PXs(x+1,y).r*6+PXs(x+2,y).r)\35
                      NEXT
                  NEXT
                  STR_buf = STR_nrm
                  FOR y = 2 TO yL - 3
                      FOR x = 0 TO xL - 1
                          PXd(x,y).b = (PXs(x,y-2).b+PXs(x,y-1).b*6+PXs(x,y).b*21+PXs(x,y+1).b*6+PXs(x,y+2).b)\35
                          PXd(x,y).g = (PXs(x,y-2).g+PXs(x,y-1).g*6+PXs(x,y).g*21+PXs(x,y+1).g*6+PXs(x,y+2).g)\35
                          PXd(x,y).r = (PXs(x,y-2).r+PXs(x,y-1).r*6+PXs(x,y).r*21+PXs(x,y+1).r*6+PXs(x,y+2).r)\35
                      NEXT
                  NEXT
                  FUNCTION = STR_nrm
              END FUNCTION
              
              FUNCTION EnhanceContrast(STR_src AS STRING, boost AS LONG) AS STRING
                  LOCAL c, x, dv, median AS LONG, BPTR_buf AS BYTE POINTER, STR_buf AS STRING
                  dv = 255 + boost
                  median = boost \ 2
                  STR_buf = STR_src
                  BPTR_buf = STRPTR(STR_buf)
                  FOR x = 8 TO LEN(STR_buf) - 1
                      c = ((@BPTR_buf[x] * dv) \ 255) - median
                      SELECT CASE c
                          CASE > 255 : @BPTR_buf[x] = 255
                          CASE < 0   : @BPTR_buf[x] =   0
                          CASE ELSE  : @BPTR_buf[x] =   c
                      END SELECT
                  NEXT
                  FUNCTION = STR_buf
              END FUNCTION
              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