Announcement

Collapse
No announcement yet.

Graphic Get PPI function

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

  • Graphic Get PPI function

    I stumbled upon some strange behaviour of the Graphic Get PPI function in PBCC 4.04 :

    The 1024 x 768 screen of my notebook measures exactly 12 x 9 inches.
    Dividing both sets of figures gives me a graphical resolution of 85.3 ppi in both directions.

    Using the Graphic Get PPI function, i can ask PBCC 4.04 to report the screen resolution,
    which is reported as 96 x 96 ppi, about 12.5% too high. But it becomes worse.
    I can change the screen mode to 800 x 600 or 640 x 480 pixels, and in all cases the graphic
    resolution is reported to be 96 x 96 ppi, which is of course wrong.
    I checked the various system settings, and could find nothing unusual.
    I tried next the printer counterpart of this function, XPrint Get PPI, which appeared to work properly.

    Specially in the case of a notebook, where all parts belong together and form one unit,
    i cannot easily imagine what might have gone wrong. On the other hand i do not immediately
    want to assume that there is something wrong with the compiler.

    Does anyone have experience with this function ?

    Arie Verheul




    Code:
     
    ' Testcode for Graphic Get PPI
     
    #Compile Exe
    #Dim All
     
    Function PBMain () As Long
     
        Local hWnd As Dword
     
        Local ClientWidth, ClientHeight, Hres, Vres As Long
     
        ' Set up a graphic window
     
        Desktop Get Client To ClientWidth, ClientHeight
        Graphic Window "",0 ,0 ,ClientWidth, ClientHeight To hWnd
        Graphic Attach hWnd, 0
        Graphic Color %Black, %White
        Graphic Font "Verdana", 12, 0
        Graphic Clear
     
        ' Get window size
     
        Graphic Get Client To ClientWidth, ClientHeight
        Graphic Print "Window  "+ Str$(ClientWidth) +"  x " + Str$(ClientHeight)
     
        ' Get graphic resolution
     
        Graphic Get PPI To Hres, Vres
        Graphic Print "Resolution  " + Str$(Hres) + "  x " + Str$(Vres)
     
        Do:Sleep 1000:Loop
     
    End Function

  • #2
    It's possible that the resolution is being reported for the entire screen, including the part under the bezel.
    KS

    Comment


    • #3
      Nothing wrong, it's reading your Windows 'DPI' setting. Control Panel -> Display -> Settings Tab -> Advanced.

      There are 2 typical values here - 96 and 120. I can't say for sure, but I would imagine that GRAPHIC GET PPI is a "wrapper" around the following Windows API code:

      MSDN: GetDeviceCaps

      Code:
      #COMPILE EXE
      #DIM ALL
      
      #INCLUDE "WIN32API.INC"
      
      FUNCTION PBMAIN () AS LONG
      
          LOCAL hDC   AS DWORD
          LOCAL PPI_x AS LONG
          LOCAL PPI_y AS LONG
          
          hDC = GetDC(%HWND_DESKTOP)
          
          PPI_x = GetDeviceCaps(hDC, %LOGPIXELSX)
          PPI_y = GetDeviceCaps(hDC, %LOGPIXELSY)
          
          ReleaseDC %HWND_DESKTOP, hDC
          
          PRINT "Pixels per logical inch (X): " + FORMAT$(PPI_x)
          PRINT "Pixels per logical inch (Y): " + FORMAT$(PPI_y)
          
          WAITKEY$
      
      END FUNCTION
      Adam Drake
      PowerBASIC

      Comment


      • #4
        Help file"
        "Representative physical size" means that the actual image may be close to a particular physical size, but is subject to factors including* Windows default PPI setting, the driver's DPI to PPI ratio and even how the monitor has been adjusted.
        Unless I am mistaken, printers use "real" inches rather than the "logical" inches used by displays.
        Michael Mattias
        Tal Systems (retired)
        Port Washington WI USA
        [email protected]
        http://www.talsystems.com

        Comment


        • #5
          Graphic Get PPI function

          Adam,

          Thank you for your help,

          I am afraid you are right that the Graphic Get PPI function simply returns the
          Windows DPI setting. But according to the manual (see quote below), that is not
          what it is supposed to do.

          I noticed that the Windows GetDeviceCaps function may also return the physical
          screen dimensions, which would provide a simple way to calculate the screen
          resolution. I slightly extended your code to do this (see below).
          But for my 12 x 9" screen, dimensions of 320 x 240 mm are returned, what might
          only be correct if the part of the screen under the bezel were included, as
          Keith suggested. Probably we are talking here about manufacturers who like to
          present their screens as larger than they actually are. The calculated screen
          resolution is 81.3 ppi, compared to the observed 85.3 ppi about 4.5% low.

          I suppose that as even the basic data are unreliable, it will be difficult to
          obtain accurate information about screen resolution.

          Arie Verheul



          GRAPHIC GET PPI statement (PBCC help file)


          Purpose Retrieve the resolution of the display device, in points per inch.

          Syntax GRAPHIC GET PPI TO ncWidth&, ncHeight&

          The graphic window must first be selected with GRAPHIC ATTACH.
          The resolution is always specified in pixels, regardless of any GRAPHIC SCALE option.
          This statement is particularly useful in drawing items such as rulers and graphs to a
          "representative physical size". There are 25.4 millimeters per inch, so just divide
          by 25.4 to convert from pixels per inch to pixels per millimeter.

          "Representative physical size" means that the actual image may be close to a
          particular physical size, but is subject to factors including Windows default PPI
          setting, the driver's DPI to PPI ratio and even how the monitor has been adjusted.
          By using the GRAPHIC GET PPI, results, you can construct a representative graphic
          image that can be saved and later output at the intended scale by more precise means,
          for example a higher resolution Windows printer.


          Adam's code, extended to calculate actual screen resolution.

          Code:
           
           
          #Compile Exe
          #Dim All
          #Include "Win32api.inc"
           
          Function PBMain () As Long
           
              Local hDC        As Dword
              Local PPI_x      As Long
              Local PPI_y      As Long
              Local PhysSize_x As Long
              Local PhysSize_y As Long
              Local LogSize_x  As Long
              Local LogSize_y  As Long
           
              hDC = GetDC(%HWND_DESKTOP)
           
              PPI_x       = GetDeviceCaps(hDC, %LOGPIXELSX)
              PPI_y       = GetDeviceCaps(hDC, %LOGPIXELSY)
              PhysSize_x  = GetDeviceCaps(hDC, %HORZSIZE)
              PhysSize_y  = GetDeviceCaps(hDC, %VERTSIZE)
              LogSize_x   = GetDeviceCaps(hDC, %HORZRES)
              LogSize_y   = GetDeviceCaps(hDC, %VERTRES)
           
              ReleaseDC %HWND_DESKTOP, hDC
           
              Print "Horizontal logical  size (pixels)  : " ; LogSize_x
              Print "Vertical   logical  size (Pixels)  : " ; LogSize_y
              Print
              Print "Horizontal physical size (mm)      : " ; PhysSize_x
              Print "Vertical   physical size (mm)      : " ; PhysSize_y
              Print
              Print "Calculated resolution x (ppi)      : " ; Round(25.4*LogSize_x/PhysSize_x,1)
              Print "Calculated resolution y (ppi)      : " ; Round(25.4*LogSize_y/PhysSize_y,1)
              Print
              Print "Pixels per logical inch (X)        : " ; PPI_x
              Print "Pixels per logical inch (Y)        : " ; PPI_y
           
           
              WaitKey$
           
          End Function

          Comment


          • #6
            I suppose that as even the basic data are unreliable, it will be difficult to
            obtain accurate information about screen resolution.
            Not unreliable, as it is returning number of pixels per logical, not physical, inch.

            I think that the help file if not somewhat vaguely covers this (note use of the word representative) :

            "Representative physical size" means that the actual image may be close to a
            particular physical size, but is subject to factors including Windows default PPI
            setting, the driver's DPI to PPI ratio and even how the monitor has been adjusted.
            By using the GRAPHIC GET PPI, results, you can construct a representative graphic
            image that can be saved and later output at the intended scale by more precise means,
            for example a higher resolution Windows printer.
            As Michael stated, printers actually use physical size, see help file under 'XPRINT GET PPI'.

            What you see on the monitor is not exactly what's actually going to be on a piece of paper on the printer, but it will be close.

            Is there a real need to get the actual physical size for the display monitor?
            Adam Drake
            PowerBASIC

            Comment


            • #7
              It's a confusing subject

              Adam,

              To start with your last question, the purpose of this is indeed to draw to an
              accurate size. My background is in engineering, and there it is good practise
              to draw accurately to scale.
              Normally this is achieved by calibrating the screen: display a rectangle on the
              screen, and ask to measure this rectangle with a ruler, and to return the measured
              values to the application. I actually still could do this, but i erroneously
              understood that the Graphics Get PPI function could take care of it.

              If i get you right, if there is made reference to inches or millimeters with respect
              to screen graphics, it is always about logical inches or millimeters, that have no
              direct relation to the size they have in the real world. And even the physical screen
              size, as returned by the GetDeviceCaps function is measured in logical millimeters,
              although this is not stated :

              GetDeviceCaps

              HORZSIZE Width, in millimeters, of the physical screen.
              VERTSIZE Height, in millimeters, of the physical screen.
              In my trade such a practice would not have been accepted.
              If logical units are needed, that's fine, put please give them a different name.
              Also, if the Graphic Get PPI function just returns the Windows DPI setting,
              it would have helped a lot if the manual simply said that.

              It's indeed a very confusing subject, thank you very much for clearing this up.
              Thank you for your help.

              Arie Verheul

              Comment

              Working...
              X