Announcement

Collapse
No announcement yet.

Anti-Aliasing, Again

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

  • Anti-Aliasing, Again

    I'm interested in improving the images shown by gbZoom, where I create a large image from a smaller area. Anti-aliasing seems to be the general concept that fits the need.

    In looking around, there seems to be three anti-aliasing solutions generally discussed:

    1. Create large and then shrink to desired size
    2. Enlarge existing and then shrink to original size
    3. Draw the original with anti-aliasing algorithms

    For improving gbZoom output, a variation of the #2 solution can be applied, as Kurt suggested. But the low contrast results and time to complete the sequence for very large images are of concern.

    At first glance, #3 doesn't apply to improving the output of gbZoom because I'm working with existing graphics (the desktop). But I wonder if the algorithm of the anti-aliasing line-drawing code I published a while back can be applied to an entire existing image. Anti-aliasing without losing the contrast between FG and BG would be the goal. My first guess is that processing time will go up but if the background can be ignored, perhaps that's not so true?

    One problem with that thought is that backgrounds are rarely a single color, so ignoring a "background" won't be a particularly easy task.

    I wonder, also, if there's a different approach to take. For example, I've read that most video cards offer anti-aliasing capabilities that are typically not used, in favor of allowing the application to manage anti-aliasing. "Full screen sampling" is a phrase I've run across in articles about how the graphics card can improve anti-aliasing, plus here's an article here that gives a short overview of SuperSampling and MultiSampling, as it relates to graphics card processing.

    My search on "high contrast anti-aliasing" hasn't turned up much of interest.

  • #2
    I wouldn't actually call it Anti_Aliasing. That usually refers to anti-aliasing drawn objects (ie. lines, circles, etc.). In your case, you naturally get pixilation because of enlarging the image, so you require a more complex cleanup algorithm. I have a software tool I purchased which specifically does this, but the algorithm is quite complex (which is why the software tool was created and sold to users). Rather than simply anti-alias pixels next to a drawn image, you are trying to make a pixelated image cleaner looking, which would require some kind of complex routine which likely would modify the image in blocks (ie. 3 x 3, 4, x 4, 5, x 5, etc.).

    What we are talking about is the common problem of working with Raster (bitmap) images versus Vector images. Vector images define objects which are scalable, which means they can easily be enlarged. Raster images have the problem of not being scalable, which causes pixilation.

    If an image is scaled just slightly, pixilation is easier to fix. The larger the scaling the more complex the routine required to cleanup the image.

    Now one adds to this the situation where one wants to do this on the fly, which requires a very fast routine, or over time (ie. image editor) where time does not matter, but quality does. You can have only one or the other.

    Chris Boss
    Computer Workshop
    Developer of "EZGUI"
    http://cwsof.com
    http://twitter.com/EZGUIProGuy

    Comment


    • #3
      To better appreciate what I mean above, take a look at the software noted below:

      https://www.ashampoo.com/en/usd/pin/...re/photozoom-6

      It is called Photo Zoom. Such software is designed for reversing the pixilation problem when enlarging raster images. The techniques used by such software is what you are trying to accomplish. Likely the algorithms used are quite complex. If they weren't then anybody could do this easily and such software would be meaningless.

      So called "Sharpen" routines in image editors likely is similar, but again they do not usually do well when the image is enlarged significantly. The complex algorithms used in an app like Photo Zoom are most likely very complex.

      This is why in the photography world, high resolution raw images are critical. One can not as easily print a large image of say a 2 megapixel photo as one could a 20 megapixel photo. This is why cameras for pro use are such high megapixel images.

      Pixelation has been the biggest weakness of raster images from day one. Enlarging them has always been a problem.

      Chris Boss
      Computer Workshop
      Developer of "EZGUI"
      http://cwsof.com
      http://twitter.com/EZGUIProGuy

      Comment


      • #4
        While you may find some source code online for a Sharpening routine, it may be harder to find open source code for more complex routines like found in the Photo Zoom software. This where it might require some creativity on your part. I would try your hand at writing your own routine. It is a good learning experience. The key is to break down the problem into simple steps.

        I would start by using a half dozen different images you would like to enlarge. Do a screen copy to get them or if photos use some which are uniquely different. Use some with just a few solid colors and others with a large variety of colors.

        Then enlarge them so you see how they pixelate and then start asking yourself some questions. If I were to manually (pixel by pixel) modify the image myself, how would I do it ? Which pixels would I leave alone and which would I change ? Would I average the ones I change using all the pixels around it or just a few ? Then write down your observations on paper for each scenario.

        Then the hard part. Try to convert your manual observations into code to do the same thing.

        Such tasks are very worthwhile experience for learning.

        I had a similar experience, but with actual anti-aliasing, not a sharpen routine. When I wrote my sprite engine for EZGUI, I wanted to find a way to anti-aliasing pixels around a non-rectangular object stored in a bitmap (one color considered transparent). The problem was that calculation anti-aliased pixels on the fly is very slow, if the sprite needs to be animated quickly. Any complex routines, especially using floating point were out. My solution ?

        My sprites were stored in a 32 bit DIB section bitmap. One byte for alphablending was unused. I wrote a routine which did a "precalculation" of where pixels would be anti-aliased one time when the sprite was loaded and then I stored an alphablend value in the alpha byte. Now when the sprite is actually drawn, I would get the alpha byte out and I would use that to modify the pixel (which would always be a transparent pixel in the sprite) on the background using that precalculated value. This allowed me to anti-alias on the fly very fast. The quality was not nearly as good as say an image editor would do, but it was good enough for animation.

        The point is, the one has to choose a method which fits either performace (speed) or quality, but not both. By being creative in ones solution, one may find some interesting solutions.

        Chris Boss
        Computer Workshop
        Developer of "EZGUI"
        http://cwsof.com
        http://twitter.com/EZGUIProGuy

        Comment


        • #5
          Howdy, Chris,
          and thanks for the comments.

          The images on Photo Zoom looked very impressive. They were, as one would expect, silent about the way they get the results. Plus, their examples are for images rather than text. I would expect images to yield better results than a blow up of text content.

          If all I had to worry about was text, then screen scraping might be a good choice, but desktops rarely consist of all text.

          On this ....
          You can have only one or the other.
          ... one approach might be to use something of low quality /high speed as the mouse is moving, but then apply the best quality once movement has stopped.

          Having to start with someone else's output (whatever is on the screen) does limit my options, eliminating any pre-calculation such as you mention.

          As you suggest, I'll have to think more on the type of solution that makes sense.

          Comment


          • #6
            Looking at Win10 built-in Magnifier, I see that it handles zoom instantly and does not seem to introduce any significant loss in contrast. At very low magnification the anti-aliasing of text-based content is not bad, but even at moderate magnification it degrades significantly. It seemed that zoom over a text based control was better, but nothing close to what would be achieved from screen scraping.

            Here a comparison of gbZoom and Windows Magnifier at 4X. The Magnifier result is much better than gbZoom. Neither has high readability, but certainly the pixelation is better with Magnifier. This image is from an Explorer screen shot.

            Click image for larger version

Name:	pb_2092.jpg
Views:	1
Size:	13.2 KB
ID:	777675
            But, when I take a look at a desktop icon (Magnifier on right), the performance of Magnifier is still better, but not by as large a margin.

            Click image for larger version

Name:	pb_2093.jpg
Views:	1
Size:	31.0 KB
ID:	777676

            The lesson learned from the comparison is that there is certainly some improvement that gbZoom can achieve, although I've no idea what approach Magnifier uses.

            Comment


            • #7
              The Windows magnifier appears to be implementing a "BLUR" effect rather than what the Photo Zoom app would accomplish. By Blurring the image, based on magnification one makes it look less pixelated. That said, the Blur does not produce a true clean zoom. To do that would require a very complex algorithm.

              You will notice that while the Windows magnifier is more sharpened and anti-aliased (lines look better), it is also changing the colors of areas which are quite solid. The background is darker than the original. This means its blur effect has a darkening effect as well.

              The point is that it is using a less intelligent algorithm, which is effective and likely fast, but it loses some aspects of the image in the process. It likely is using a grid algorithm which reads the pixels in blocks (ie. 3 x 3, 4 x 4, 5 x 5, etc.) and then blurs the pixels in that block. I think a lot of image filters uses the grid technique to walk through the pixels. It is likely faster, but it may not be as smart.
              Chris Boss
              Computer Workshop
              Developer of "EZGUI"
              http://cwsof.com
              http://twitter.com/EZGUIProGuy

              Comment


              • #8
                Hi Chris!
                Whatever blue is applied seems to be good at not modifying the white area, giving rise to a better contrast for dark letters on the white background.

                Comment


                • #9
                  Gary,

                  Here is a modified version of your app:

                  Example of desktop icon at 5X magnification:

                  Click image for larger version

Name:	gary2.png
Views:	2
Size:	107.6 KB
ID:	777711

                  Code:
                  'Compilable Example:
                  #COMPILER PBWIN 10
                  #COMPILE EXE
                  #DIM ALL
                  %Unicode = 1
                  #INCLUDE "Win32API.inc"
                  
                  ENUM Equates SINGULAR
                     IDC_Graphic = 500
                     ID_Timer
                     IDM_ZoomIn
                     IDM_ZoomOut
                  END ENUM
                  
                  %UseBitmapCode = 1
                  GLOBAL BitmapEnlargeBy AS LONG
                  
                  GLOBAL hDlg,hGraphic, hGraphicDC AS DWORD, Zoom AS SINGLE, pt AS POINT, hBigBmp AS DWORD
                  
                  FUNCTION PBMAIN() AS LONG
                  
                     BitmapEnlargeBy = 2
                  
                     DIALOG NEW PIXELS, 0, "gbZoom",,,400,400, %WS_OVERLAPPEDWINDOW TO hDlg
                     CONTROL ADD GRAPHIC, hDlg, %IDC_Graphic,"Push", 0,0,200,200
                     CONTROL HANDLE hDlg, %IDC_Graphic TO hGraphic
                     hBigBmp = 0 ' no Bitmap
                     DIALOG SHOW MODAL hDlg CALL DlgProc
                     IF hBigBmp <> 0 THEN
                          GRAPHIC ATTACH hBigBmp, 0
                          GRAPHIC BITMAP END
                     END IF
                  END FUNCTION
                  
                  CALLBACK FUNCTION DlgProc() AS LONG
                     LOCAL rc AS Rect, w,h AS LONG
                     SELECT CASE CB.MSG
                        CASE %WM_INITDIALOG
                           BuildAcceleratorTable
                           Zoom = 1
                           SetTimer(hDlg, %ID_Timer, 100, BYVAL %NULL)
                           DIALOG SET TEXT hDlg, "gbZoom   " + STR$(Zoom) + "X"
                        CASE %WM_COMMAND
                           SELECT CASE CB.CTL
                              CASE %IDM_ZoomIn  : Zoom = MIN(10,Zoom+1) : DIALOG SET TEXT hDlg, "gbZoom   " + STR$(Zoom) + "X" : CopyScreen
                              CASE %IDM_ZoomOut : Zoom = MAX( 1,Zoom-1) : DIALOG SET TEXT hDlg, "gbZoom   " + STR$(Zoom) + "X" : CopyScreen
                           END SELECT
                        CASE %WM_ContextMenu
                           INCR Zoom : IF Zoom > 10 THEN Zoom = 1
                           DIALOG SET TEXT hDlg, "gbZoom   " + STR$(Zoom) + "X" : CopyScreen
                        CASE %WM_TIMER
                           GetCursorPos pt
                           GetWindowRect hGraphic, rc
                           IF PtInRect(rc,pt) = %False THEN CopyScreen
                        CASE %WM_SIZE
                           DIALOG GET CLIENT hDlg TO w,h
                           CONTROL SET SIZE hDlg, %IDC_Graphic, w,h
                           IF hBigBmp <> 0 THEN
                                GRAPHIC ATTACH hBigBmp, 0
                                GRAPHIC BITMAP END
                           END IF
                           GRAPHIC BITMAP NEW w * BitmapEnlargeBy, h * BitmapEnlargeBy TO hBigBmp
                     END SELECT
                  END FUNCTION
                  
                  
                  
                  
                  SUB CopyScreen
                     LOCAL hDeskTopDC AS DWORD, w,h, Bw, Bh AS LONG, oldMode AS LONG
                     DIALOG GET CLIENT hDlg TO w,h
                     Bw = w * BitmapEnlargeBy
                     Bh = h * BitmapEnlargeBy
                     #IF %UseBitmapCode
                          GRAPHIC ATTACH hBigBmp, 0
                          GRAPHIC GET DC TO hGraphicDC
                          hDeskTopDC = GetDC(%Null)
                          oldMode = SetStretchBltMode(hGraphicDC, %HALFTONE)
                          StretchBlt hGraphicDC, 0, 0, Bw, Bh, hDeskTopDC, pt.x - w/Zoom/2, pt.y - h/Zoom/2, w/Zoom, h/Zoom, %SRCCopy
                          SetStretchBltMode hGraphicDC, oldMode
                          ReleaseDC(%Null,hDeskTopDC)
                  
                          GRAPHIC ATTACH hDlg, %IDC_Graphic, REDRAW
                          GRAPHIC STRETCH PAGE hBigBmp,  0, %MIX_COPYSRC, %COLORONCOLOR
                          GRAPHIC REDRAW
                     #ELSE
                          GRAPHIC ATTACH hDlg, %IDC_Graphic, REDRAW
                          GRAPHIC GET DC TO hGraphicDC
                          hDeskTopDC = GetDC(%Null)
                          StretchBlt hGraphicDC, 0, 0, w, h, hDeskTopDC, pt.x - w/Zoom/2, pt.y - h/Zoom/2, w/Zoom, h/Zoom, %SRCCopy
                          ReleaseDC(%Null,hDeskTopDC)
                          GRAPHIC REDRAW
                     #ENDIF
                     GRAPHIC WIDTH 2
                     GRAPHIC BOX (w/2-10,h/2-10)-(w/2+10,h/2+10),,%RED   'optional square are center of viewing area
                     GRAPHIC WIDTH 5
                     GRAPHIC BOX (0,0)-(w,h),,%BLACK
                     GRAPHIC REDRAW
                  END SUB
                  
                  SUB BuildAcceleratorTable
                     LOCAL c AS LONG, ac() AS ACCELAPI, hAccelerator AS DWORD  ' for keyboard accelator table values
                     DIM ac(1)
                     ac(c).fvirt = %FVIRTKEY OR %FCONTROL : ac(c).key   = %VK_M  : ac(c).cmd  = %IDM_ZoomOut : INCR c
                     ac(c).fvirt = %FVIRTKEY OR %FCONTROL : ac(c).key   = %VK_P  : ac(c).cmd  = %IDM_ZoomIn  : INCR c
                     ACCEL ATTACH hDlg, AC() TO hAccelerator
                  END SUB
                  Attached Files
                  Chris Boss
                  Computer Workshop
                  Developer of "EZGUI"
                  http://cwsof.com
                  http://twitter.com/EZGUIProGuy

                  Comment


                  • #10
                    Hey Chris!
                    Thanks for taking the time to create the modified version of gbZoom, with incorporation of a make-large-then-shrink approach, whereas gbZoom simply did a 1:1 copy. Did I say that right?

                    Here's what I see that you've done ...
                    1. Every time there's a resize, you create a larger memory bitmap (easy to vary the size)
                    2. Each timer cycle, you run CopyScreen
                    3. In copy screen you first copy the target to the big bitmap with StretchBlt
                    4. In copy screen you then copy the big bitmap to the output (visible) graphic control with Graphic Stretch Page
                    Now, I need to run gbZoom against your version and see what visual improvement there is in the result. That's the intent of the make-large-then-shrink approach, yes?

                    In this case, there's no blur being applied to the big bitmap, but it's obvious in CopyScreen where the Blur function would go - just before using Graphic Stretch Page to put the big bigmap into the output (visible) graphic control.

                    Be right back ...

                    Comment


                    • #11
                      Chris,
                      Here are some side by side comparisons, with your mod on the left. I used BigmapEnlargeBy = 4, then I also used a 4X enlargement in the display.

                      For the black text on a white background (first image), the smoothing result of your code is obvious. The contrast has dropped some, but the letters are definitely less pixelated.

                      In the second

                      Click image for larger version  Name:	pb_2094.jpg Views:	1 Size:	15.4 KB ID:	777714

                      In this image, comparing 2 desktop icons, the lettering with your approach takes a bigger contrast hit (white letters on dark background), but still has a smoother letter rendering.

                      Click image for larger version  Name:	pb_2095.jpg Views:	1 Size:	27.4 KB ID:	777715

                      With the 4X / 4X settings, I saw about a half second lag when the mouse was moved. With the original gbZoom code, the lag was barely detectable. With there already being a noticeable lag, I would expect that any blur routine will take the realtime usefulness out of this approach.

                      However, that's with 4x/4x settings. I'll play some more with it to see if there's any kind of "sweet spot" to know about.

                      Thanks again! Your example is very helpful in addressing the improvements to gbZoom that I would like to see.

                      Comment


                      • #12
                        There is also one other trick I used. I stretched the image into the bitmap using the %HALFTONE drawing mode. But when I stretched the bitmap to the Graphic control (made smaller) I used the %COLORONCOLOR mode. There is a reason for this. The different drawing modes produces the blur effect you see.
                        Chris Boss
                        Computer Workshop
                        Developer of "EZGUI"
                        http://cwsof.com
                        http://twitter.com/EZGUIProGuy

                        Comment


                        • #13
                          Hi Chris! I never noticed the use of ColorOnColor.

                          There is some blurring even without ColorOnColor, yes?

                          I'll have to compare using it vs HalfTone.

                          Comment


                          • #14
                            Half Toning and Color on Color work differently. They determine which colors to draw differently, so by the use of both of them I get the effect I got. If you use only one or the other you will not get the blur effect I got. This is the key to my code and how it works. If you try to use only one or the other, you will not get the same effect.
                            Chris Boss
                            Computer Workshop
                            Developer of "EZGUI"
                            http://cwsof.com
                            http://twitter.com/EZGUIProGuy

                            Comment


                            • #15
                              Chris,
                              The blurred effect certainly helps the pixelation but for my users with visual impairments, the lack of contrast is a very important issue.

                              A solution where I restore all pre-processed background colored pixels may be the general solution to keeping the contrast, but that doesn't shout "real time"! Plus, some of the restoration would undo some of the desired smoothing effects.

                              In looking for "high contrast anti-aliasing" or "high contrast burring" I ran across this article which talks about font hinting and subpixel rendering. It doesn't appear to be anything we can do, but was an interesting read on how far font technology goes to improve character visibility.

                              Comment


                              • #16
                                The problem with enlarging a raster image is that the detail simply does not exist when enlarged. There is no way to actually enlarge and make it look exactly like the original. In the real world one can zoom closer and closer and the detail is there. It is hard to beat atoms and molecules for tiny detail. But in raster graphics the original pixels are as small as you can get. Accurate enlargement is pixilation. That is exactly what is there. So to get rid of the pixilation one must "fudge" it somehow. The blur effect downplays pixilation. Sharpening or contract increases pixilation. The only way to compensate would be through a very complex algorithm which "recreates" the image through complex calculations which "fudge" it, but with realistic effects. Such a routine would be slow though for a fast zoom feature.

                                IMO one has to give a little and consider what is the most important aspect of the enlargement, doing it fast as well.

                                The blur effect my code produces is fast since it is accomplished through the fast StretchBlt API's in Windows using a trick of coloroncolor overlayed by halftone. A routine which reads each pixel would allow more complexity but would be much slower.
                                Chris Boss
                                Computer Workshop
                                Developer of "EZGUI"
                                http://cwsof.com
                                http://twitter.com/EZGUIProGuy

                                Comment


                                • #17
                                  Gary,

                                  This is the best I can produce using a slightly different approach at merging pixels with multiple calls to GRAPHIC Stretch. The contrast is possible 25% better in this one:

                                  Code:
                                  'Compilable Example:
                                  #COMPILER PBWIN 10
                                  #COMPILE EXE
                                  #DIM ALL
                                  %Unicode = 1
                                  #INCLUDE "Win32API.inc"
                                  
                                  ENUM Equates SINGULAR
                                     IDC_Graphic = 500
                                     ID_Timer
                                     IDM_ZoomIn
                                     IDM_ZoomOut
                                  END ENUM
                                  
                                  %UseBitmapCode = 1
                                  GLOBAL BitmapEnlargeBy AS LONG
                                  
                                  GLOBAL hDlg,hGraphic, hGraphicDC AS DWORD, Zoom AS SINGLE, pt AS POINT, hBigBmp AS DWORD
                                  
                                  FUNCTION PBMAIN() AS LONG
                                  
                                     BitmapEnlargeBy = 2
                                  
                                     DIALOG NEW PIXELS, 0, "gbZoom",,,400,400, %WS_OVERLAPPEDWINDOW TO hDlg
                                     CONTROL ADD GRAPHIC, hDlg, %IDC_Graphic,"Push", 0,0,200,200
                                     CONTROL HANDLE hDlg, %IDC_Graphic TO hGraphic
                                     hBigBmp = 0 ' no Bitmap
                                     DIALOG SHOW MODAL hDlg CALL DlgProc
                                     IF hBigBmp <> 0 THEN
                                          GRAPHIC ATTACH hBigBmp, 0
                                          GRAPHIC BITMAP END
                                     END IF
                                  END FUNCTION
                                  
                                  CALLBACK FUNCTION DlgProc() AS LONG
                                     LOCAL rc AS Rect, w,h AS LONG
                                     SELECT CASE CB.MSG
                                        CASE %WM_INITDIALOG
                                           BuildAcceleratorTable
                                           Zoom = 1
                                           SetTimer(hDlg, %ID_Timer, 100, BYVAL %NULL)
                                           DIALOG SET TEXT hDlg, "gbZoom   " + STR$(Zoom) + "X"
                                        CASE %WM_COMMAND
                                           SELECT CASE CB.CTL
                                              CASE %IDM_ZoomIn  : Zoom = MIN(10,Zoom+1) : DIALOG SET TEXT hDlg, "gbZoom   " + STR$(Zoom) + "X" : CopyScreen
                                              CASE %IDM_ZoomOut : Zoom = MAX( 1,Zoom-1) : DIALOG SET TEXT hDlg, "gbZoom   " + STR$(Zoom) + "X" : CopyScreen
                                           END SELECT
                                        CASE %WM_ContextMenu
                                           INCR Zoom : IF Zoom > 10 THEN Zoom = 1
                                           DIALOG SET TEXT hDlg, "gbZoom   " + STR$(Zoom) + "X" : CopyScreen
                                        CASE %WM_TIMER
                                           GetCursorPos pt
                                           GetWindowRect hGraphic, rc
                                           IF PtInRect(rc,pt) = %False THEN CopyScreen
                                        CASE %WM_SIZE
                                           DIALOG GET CLIENT hDlg TO w,h
                                           CONTROL SET SIZE hDlg, %IDC_Graphic, w,h
                                           IF hBigBmp <> 0 THEN
                                                GRAPHIC ATTACH hBigBmp, 0
                                                GRAPHIC BITMAP END
                                           END IF
                                           GRAPHIC BITMAP NEW w * BitmapEnlargeBy, h * BitmapEnlargeBy TO hBigBmp
                                     END SELECT
                                  END FUNCTION
                                  
                                  
                                  
                                  
                                  SUB CopyScreen
                                     LOCAL hDeskTopDC AS DWORD, w,h, Bw, Bh AS LONG, oldMode AS LONG
                                     DIALOG GET CLIENT hDlg TO w,h
                                     Bw = w * BitmapEnlargeBy
                                     Bh = h * BitmapEnlargeBy
                                     #IF %UseBitmapCode
                                          GRAPHIC ATTACH hBigBmp, 0
                                          GRAPHIC GET DC TO hGraphicDC
                                          hDeskTopDC = GetDC(%Null)
                                          oldMode = SetStretchBltMode(hGraphicDC, %HALFTONE)
                                          StretchBlt hGraphicDC, 0, 0, Bw, Bh, hDeskTopDC, pt.x - w/Zoom/2, pt.y - h/Zoom/2, w/Zoom, h/Zoom, %SRCCopy
                                          SetStretchBltMode hGraphicDC, oldMode
                                          ReleaseDC(%Null,hDeskTopDC)
                                  
                                  
                                          GRAPHIC ATTACH hDlg, %IDC_Graphic, REDRAW
                                  
                                          GRAPHIC STRETCH PAGE hBigBmp,  0, %MIX_MERGESRC, %HALFTONE
                                          GRAPHIC STRETCH PAGE hBigBmp,  0, %WHITEONBLACK, %HALFTONE
                                          GRAPHIC STRETCH PAGE hBigBmp,  0, %MIX_MERGESRC, %COLORONCOLOR
                                          GRAPHIC STRETCH PAGE hBigBmp,  0, %MIX_MERGESRC, %HALFTONE
                                  
                                  
                                          GRAPHIC REDRAW
                                     #ELSE
                                          GRAPHIC ATTACH hDlg, %IDC_Graphic, REDRAW
                                          GRAPHIC GET DC TO hGraphicDC
                                          hDeskTopDC = GetDC(%Null)
                                          StretchBlt hGraphicDC, 0, 0, w, h, hDeskTopDC, pt.x - w/Zoom/2, pt.y - h/Zoom/2, w/Zoom, h/Zoom, %SRCCopy
                                          ReleaseDC(%Null,hDeskTopDC)
                                          GRAPHIC REDRAW
                                     #ENDIF
                                     GRAPHIC WIDTH 2
                                     GRAPHIC BOX (w/2-10,h/2-10)-(w/2+10,h/2+10),,%RED   'optional square are center of viewing area
                                     GRAPHIC WIDTH 5
                                     GRAPHIC BOX (0,0)-(w,h),,%BLACK
                                     GRAPHIC REDRAW
                                  END SUB
                                  
                                  SUB BuildAcceleratorTable
                                     LOCAL c AS LONG, ac() AS ACCELAPI, hAccelerator AS DWORD  ' for keyboard accelator table values
                                     DIM ac(1)
                                     ac(c).fvirt = %FVIRTKEY OR %FCONTROL : ac(c).key   = %VK_M  : ac(c).cmd  = %IDM_ZoomOut : INCR c
                                     ac(c).fvirt = %FVIRTKEY OR %FCONTROL : ac(c).key   = %VK_P  : ac(c).cmd  = %IDM_ZoomIn  : INCR c
                                     ACCEL ATTACH hDlg, AC() TO hAccelerator
                                  END SUB
                                  The key change in the code is here:

                                  Code:
                                         GRAPHIC ATTACH hBigBmp, 0
                                          GRAPHIC GET DC TO hGraphicDC
                                          hDeskTopDC = GetDC(%Null)
                                          oldMode = SetStretchBltMode(hGraphicDC, %HALFTONE)
                                          StretchBlt hGraphicDC, 0, 0, Bw, Bh, hDeskTopDC, pt.x - w/Zoom/2, pt.y - h/Zoom/2, w/Zoom, h/Zoom, %SRCCopy
                                          SetStretchBltMode hGraphicDC, oldMode
                                          ReleaseDC(%Null,hDeskTopDC)
                                  
                                  
                                          GRAPHIC ATTACH hDlg, %IDC_Graphic, REDRAW
                                          GRAPHIC STRETCH PAGE hBigBmp,  0, %WHITEONBLACK, %HALFTONE
                                          GRAPHIC STRETCH PAGE hBigBmp,  0, %MIX_MERGESRC, %COLORONCOLOR
                                          GRAPHIC STRETCH PAGE hBigBmp,  0, %MIX_MERGESRC, %HALFTONE
                                  
                                  
                                          GRAPHIC REDRAW
                                  Chris Boss
                                  Computer Workshop
                                  Developer of "EZGUI"
                                  http://cwsof.com
                                  http://twitter.com/EZGUIProGuy

                                  Comment


                                  • #18
                                    Hey Chris!
                                    Thanks for the update. Perhaps I'm doing something wrong, but both approaches in your last post seem to give the same results. It works differently on your end?

                                    Comment


                                    • #19
                                      Originally posted by Gary Beene View Post
                                      Hey Chris!
                                      Thanks for the update. Perhaps I'm doing something wrong, but both approaches in your last post seem to give the same results. It works differently on your end?
                                      I believe that what you are looking for is a smoothing algorithm.
                                      It removes some detail, but maintains the and improves the overall effect.
                                      I believe it ignores high contrast when blending pixels. What you would end up with
                                      is a blurring of low contrast areas, but a sharper definition between higher contrast areas.
                                      Theoretically, anyway...
                                      It doesn't seem very complex when stated that way.
                                      My own efforts at improving contrast are not going well at the moment.
                                      The tiny routine in the magnification thread only makes light things lighter and dark things darker.
                                      It doesn't take relative differences into account at all. It's a bit of a failure, really.
                                      The world is strange and wonderful.*
                                      I reserve the right to be horrifically wrong.
                                      Please maintain a safe following distance.
                                      *wonderful sold separately.

                                      Comment


                                      • #20
                                        Gary,

                                        My latest version may not seem significantly better, but I can see the difference. Whether it is only 15% or 25% better is only my opinion based on how it looks to me, but it is better.

                                        My key point is that I don't think you can get much better than this for clarity, unless you use a very complex algorithm. To make the image look unpixellated on must blur the pixels to smooth out the picture. That always decreases contrast and sharpness. It is one or the other. The only other way to get better would be a very complex routine which calculates what it "thinks" should be there (which actually isn't) and then compensate for the pixilation. It is simply a fact of enlarging raster images. I don't imagine you will get any better than what I got unless you can write your own complex routine.

                                        Like I said above, this is why companies sell quality programs to do just that, enlarge a raster image without pixilation. There would be no market for such software if it was easy to do in Windows normally, which it isn't.

                                        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.

                                        This is why vector graphics is so important today. Unlike raster graphics (aka. bitmap), vector graphics are based on defining points in an image and then drawing the lines and adding fill. This allows for scaling of the graphics significantly better than raster graphics can do. One good example are TrueType fonts. Unless raster fonts (found Windows 3.1), TrueType fonts are vector based so they are perfectly scalable.

                                        Now the trick with raster image scaling is always having a very large image to start with and then one can shrink the image to a small size. The algorithms for stretching "down" (shrink) a raster image do pretty good for keeping clarity. It is the stretching "up" (enlarge) of raster images which is the problem. You don't have any way to fill in the gaps. You get pixilation. One has to "guess" at the best color to fill in the gaps and that requires a complex algorithm. It requires comparing not only ones neighbor pixels, but even pixels some distance away. Otherwise one gets a blur effect, which is basically what we are getting. The algorithm has to be "smart".
                                        Chris Boss
                                        Computer Workshop
                                        Developer of "EZGUI"
                                        http://cwsof.com
                                        http://twitter.com/EZGUIProGuy

                                        Comment

                                        Working...
                                        X