Announcement

Collapse
No announcement yet.

Adding text to a JPEG

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

  • Adding text to a JPEG

    Anyone know how to add text to a JPEG?

    Lets say I want to add a watermark to a jpeg to protect an image (Or in this case a piece of software until the software is registered)...
    Scott Turchin
    MCSE, MCP+I
    http://www.tngbbs.com
    ----------------------
    True Karate-do is this: that in daily life, one's mind and body be trained and developed in a spirit of humility; and that in critical times, one be devoted utterly to the cause of justice. -Gichin Funakoshi

  • #2
    Normally text or, better, any kind of meta data is added via Exif tags.
    But if you want something a little bit more subtle (but not, by any mean, really effective as a watermark) you can also simply add some bytes at the end of the file, after the last 0xFF 0xD9 bytes.
    The bitmap will continue to be read correctly by almost any software, and you have some bytes moderately hidden, at least to the casual viewer.

    Bye!
    Last edited by Marco Pontello; 18 Oct 2008, 08:52 PM.
    -- The universe tends toward maximum irony. Don't push it.

    File Extension Seeker - Metasearch engine for file extensions / file types
    Online TrID file identifier | TrIDLib - Identify thousands of file formats

    Comment


    • #3
      Originally posted by Scott Turchin View Post
      Anyone know how to add text to a JPEG?
      have a look at the GDI+ functions. Jose Roca's site is the best place to look, http://com.it-berater.org/gdiplus/no..._functions.htm.

      There are examples in the PB forums on loading and saving JPGs using GDI+.

      Comment


      • #4
        Oh I don't want the text hidden, I want it to say "UNREGISTERED SHAREWARE VERSION" All over it

        I'd like to mix it
        Scott Turchin
        MCSE, MCP+I
        http://www.tngbbs.com
        ----------------------
        True Karate-do is this: that in daily life, one's mind and body be trained and developed in a spirit of humility; and that in critical times, one be devoted utterly to the cause of justice. -Gichin Funakoshi

        Comment


        • #5
          Originally posted by Scott Turchin View Post
          Oh I don't want the text hidden, I want it to say "UNREGISTERED SHAREWARE VERSION" All over it
          So you have just one image and in the shareware it gets a watermark but not in the full version?

          Comment


          • #6
            Scott,
            open the .jpg file in Paint (under All Programs/Accessories) add the text and save it again.

            It won't quite give you a watermark apearance but it'll probably be Ok for what you need.

            Paul.

            Comment


            • #7
              Not sure, but I think Scott means kinda like National Instruments "Labview" that puts a silhouette of their insignia in the bottom right of their apps in Forms/Dialogs/Windows that are made with shareware or trial programs

              Kind of like "If you like it...buy it.....If you don't...then do not use it"

              It helps somewhat with sales, and is somewhat not annoying as other techniques. And a DEFINITE tip-off when supporting a call or email or other that turns out is a user that wants something for nothing.

              I could be off...but I think the generic premise is true
              Engineer's Motto: If it aint broke take it apart and fix it

              "If at 1st you don't succeed... call it version 1.0"

              "Half of Programming is coding"....."The other 90% is DEBUGGING"

              "Document my code????" .... "WHYYY??? do you think they call it CODE? "

              Comment


              • #8
                Taking my own medicine, I tried to draw some text on a picture using GDIP. So far I have failed. The basic code to display the picture works fine, but the text drawing bit does not. I'm going to turn in now (it's late here), I will leave some copileable code just in case there is a GDIP wizard out there who can spot the obvious mistake ( all changes are in the in the WM_ERASEBKGND handler)

                Code:
                '   A very simple application which displays a picture file chosen by the user.
                '   Uses GDIPLUS and includes error reporting using GDIplus status codes
                '   PB Win 8.04, no dependencies except standard INCLUDES.
                '
                '   Chris Holbrook 1 August 2008
                '
                '   5-AUG-2008 revised WM_ERASEBKGND handler
                '  21-OCT-2008 trying out adding text to the picture see WM_ERASEBKGND handler!
                '
                #COMPILE EXE
                #DIM ALL
                
                #INCLUDE "WIN32API.INC"
                #INCLUDE "comdlg32.inc"
                
                %IDD_DIALOG1      =  101
                %IDC_getpic_bn    = 1004
                '------------------------------------------------------------------------------
                ' GDI+ status (error) codes
                %StatusOk = 0
                %StatusGenericError = 1
                %StatusInvalidParameter = 2
                %StatusOutOfMemory = 3
                %StatusObjectBusy = 4
                %StatusInsufficientBuffer = 5
                %StatusNotImplemented = 6
                %StatusWin32Error = 7
                %StatusWrongState = 8
                %StatusAborted = 9
                %StatusFileNotFound = 10
                %StatusValueOverflow = 11
                %StatusAccessDenied = 12
                %StatusUnknownImageFormat = 13
                %StatusFontFamilyNotFound = 14
                %StatusFontStyleNotFound = 15
                %StatusNotTrueTypeFont = 16
                %StatusUnsupportedGdiplusVersion = 17
                %StatusGdiplusNotInitialized = 18
                %StatusPropertyNotFound = 19
                %StatusPropertyNotSupported = 20
                '---------------------------------------------------------------------
                TYPE GdiplusStartupInput
                   GdiplusVersion AS DWORD             '// Must be 1
                   DebugEventCallback AS DWORD         '// Ignored on free builds
                   SuppressBackgroundThread AS LONG    '// FALSE unless you're prepared to call
                                                       '// the hook/unhook functions properly
                   SuppressExternalCodecs AS LONG      '// FALSE unless you want GDI+ only to use
                                                       '// its internal image codecs.
                END TYPE
                '---------------------------------------------------------------------
                '
                TYPE GdiplusStartupOutput
                '  // The following 2 fields are NULL if SuppressBackgroundThread is FALSE.
                '  // Otherwise, they are functions which must be called appropriately to
                '  // replace the background thread.
                '  //
                '  // These should be called on the application's main message loop - i.e.
                '  // a message loop which is active for the lifetime of GDI+.
                '  // "NotificationHook" should be called before starting the loop,
                '  // and "NotificationUnhook" should be called after the loop ends.
                   NotificationHook AS DWORD
                   NotificationUnhook AS DWORD
                END TYPE
                '
                DECLARE FUNCTION GdipDrawImageRectI LIB "gdiplus.dll" ALIAS "GdipDrawImageRectI" (BYVAL graphics AS LONG, BYVAL nImage AS LONG, BYVAL x AS LONG, BYVAL y AS LONG, BYVAL nWidth AS LONG, BYVAL Height AS LONG) AS LONG
                DECLARE FUNCTION GdipDeleteGraphics LIB "gdiplus.dll" ALIAS "GdipDeleteGraphics" (BYVAL graphics AS LONG) AS LONG
                DECLARE FUNCTION GdipCreateFromHDC LIB "gdiplus.dll" ALIAS "GdipCreateFromHDC" (BYVAL hdc AS LONG, graphics AS LONG) AS LONG
                DECLARE FUNCTION GdipGetImagePixelFormat LIB "gdiplus.dll" ALIAS "GdipGetImagePixelFormat" _
                            (BYVAL nImage AS LONG, PixelFormat AS LONG) AS LONG
                DECLARE FUNCTION GdipGetImageDimension LIB "gdiplus.dll" ALIAS "GdipGetImageDimension" _
                            (BYVAL nImage AS LONG, nWidth AS SINGLE, Height AS SINGLE) AS LONG
                DECLARE FUNCTION GdiplusStartup LIB "GDIPLUS.DLL" ALIAS "GdiplusStartup" _
                            (token AS DWORD, inputbuf AS GdiplusStartupInput, outputbuf AS GdiplusStartupOutput) AS LONG
                DECLARE SUB GdiplusShutdown LIB "GDIPLUS.DLL" ALIAS "GdiplusShutdown" _
                            (BYVAL token AS DWORD)
                DECLARE FUNCTION GdipLoadImageFromFile LIB "GDIPLUS.DLL" ALIAS "GdipLoadImageFromFile" _
                            (BYVAL flname AS STRING, lpImage AS DWORD) AS LONG
                DECLARE FUNCTION GdipDisposeImage LIB "GDIPLUS.DLL" ALIAS "GdipDisposeImage" _
                            (BYVAL lpImage AS DWORD) AS LONG
                DECLARE FUNCTION GdipDrawString LIB "GDIPLUS.DLL" ALIAS "GdipDrawString" _
                            (BYVAL graphics AS DWORD, BYVAL pString AS STRING, BYVAL length AS LONG, BYVAL pFont AS DWORD, _
                             BYREF layoutRect AS Rect, BYVAL stringFormat AS DWORD, BYVAL brush AS DWORD ) AS LONG
                DECLARE FUNCTION GdipCreateStringFormat LIB "GDIPLUS.DLL" ALIAS "GdipCreateStringFormat" _
                            ( BYVAL formatAttributes AS LONG, BYVAL language AS WORD, BYREF pFormat AS DWORD ) AS LONG
                
                
                
                DECLARE SUB skIconise (BYVAL xPic AS LONG, BYVAL yPic AS LONG,            _ picture dimensions
                               BYVAL xCell AS LONG, BYVAL yCell AS LONG,          _ FRAME dimensions
                               BYREF xOfs AS LONG, BYREF yOfs AS LONG,            _ calc'd offset in frame
                               BYREF xSize AS LONG, BYREF ySize AS LONG)   ' thumbnail dimensions
                '-------------------------------------------------------------------------------------------------------
                ' Computes location and size to stretch a bitmap preserving its aspect.
                '
                SUB skIconise (BYVAL xPic AS LONG, BYVAL yPic AS LONG,            _ picture dimensions
                               BYVAL xCell AS LONG, BYVAL yCell AS LONG,          _ FRAME dimensions
                               BYREF xOfs AS LONG, BYREF yOfs AS LONG,            _ calc'd offset in frame
                               BYREF xSize AS LONG, BYREF ySize AS LONG) EXPORT   ' thumbnail dimensions
                  LOCAL SCALE AS SINGLE
                
                    IF xPIC& THEN scale! = xCell& / xPic&
                    IF scale! > 1 THEN scale! = 1
                    xSize& = xPic& * scale!: ySize& = yPic& * scale!
                  ' In case Height > 150 compute new scale factor
                    IF ySize& > yCell& THEN
                       IF yPic& THEN scale! = yCell& / yPic&
                       xSize& = xPic& * scale!: ySize& = yPic& * scale!
                    END IF
                    xOfs& = (xCell& - xSize&) \ 2
                    yOfs& = (yCell& - ySize&) \ 2
                END SUB
                '---------------------------------------------------------------------
                ' get image filename
                FUNCTION getpic (hD AS LONG) AS STRING
                    LOCAL buf, spath, sfile AS STRING
                    LOCAL dwstyle AS DWORD
                    LOCAL hFile AS LONG
                    dwStyle = %OFN_EXPLORER OR %OFN_FILEMUSTEXIST OR %OFN_HIDEREADONLY
                    Buf   = "Picture files (*.JPG,*.PNG,*.TIF,*.ICO,*.GIF,*.BMP)|*.JPG|*.PNG|*.TIF|*.ICO|*.PNG|*.BMP|"
                    sfile = "*.JPG;*.PNG;*.TIF;*.ICO;*.GIF;*.BMP"
                    IF OpenFileDialog (hD, "Locate image file ", sfile, spath, buf, "JPG", dwstyle) = 0 THEN
                       EXIT FUNCTION
                    END IF
                    FUNCTION = sfile
                END FUNCTION
                '----------------------------------------------------------------------
                FUNCTION MakeFont(BYVAL fName AS STRING, BYVAL ptSize AS LONG, _
                                  OPT BYVAL attr AS STRING) AS DWORD
                   '--------------------------------------------------------------------
                   ' Create a desired font and return its handle.
                   ' attr = "biu" for bold, italic, and underlined (any order)
                   '--------------------------------------------------------------------
                   LOCAL hDC AS DWORD, CharSet AS LONG, CyPixels AS LONG
                   LOCAL BOLD, italic, uLine AS LONG
                   IF LEN(attr) THEN
                      IF INSTR(LCASE$(attr), "b") THEN BOLD = %FW_BOLD
                      IF INSTR(LCASE$(attr), "i") THEN italic = 1
                      IF INSTR(LCASE$(attr), "u") THEN uLine = 1
                   END IF
                   hDC = GetDC(%HWND_DESKTOP)
                   CyPixels  = GetDeviceCaps(hDC, %LOGPIXELSY)
                   ReleaseDC %HWND_DESKTOP, hDC
                   PtSize = 0 - (ptSize * CyPixels) \ 72
                   FUNCTION = CreateFont(ptSize, 0, 0, 0, BOLD, italic, uLine, _
                             %FALSE, CharSet, %OUT_TT_PRECIS, _
                             %CLIP_DEFAULT_PRECIS, %DEFAULT_QUALITY, _
                             %FF_DONTCARE , BYCOPY fName)
                END FUNCTION
                '------------------------------------------------------------------------
                ' callback function for dialog on which the image is displayed
                '
                CALLBACK FUNCTION PicDlgCB()
                    STATIC   sPicPath                AS STRING
                    STATIC   himage                  AS DWORD
                    LOCAL    pGraphics               AS DWORD
                    LOCAL    hdc, hfont, hbrush, strformat      AS DWORD
                    LOCAL    r                       AS rect
                    LOCAL    lPixelFormat            AS LONG
                    LOCAL    l, framex, framey AS LONG
                    STATIC   ofsx, ofsy, tX, tY      AS LONG
                    LOCAL    maxwidth, maxheight     AS LONG
                    LOCAL    origwidth, origheight   AS SINGLE
                    STATIC   sGDIPStatusCodes()      AS STRING ' table of error codes referenced by GDIP status codes
                    LOCAL    sGDIPfn                 AS STRING ' GDIP function name for error reporting
                    LOCAL    sz                      AS ASCIZ * 16
                
                    SELECT CASE AS LONG CBMSG
                        CASE %WM_INITDIALOG
                            ' initialise static variables
                            himage = 0: ofsx = 0: ofsy = 0: tX = 0: tY = 0
                            ' create font
                            hfont = makefont ("Courier New", 10, "")
                            ' load GDIPlus error messages
                            GOSUB LoadGDIPERMS
                        '
                        CASE %WM_ERASEBKGND
                            IF himage = 0 THEN FUNCTION = 0 : EXIT SELECT
                            hdc = getdc(CBHNDL)
                            IF GdipCreatefromHDC ( hDC, pGraphics) =  0 THEN
                                l = GdipDrawImageRectI(pGraphics, himage, ofsX, ofsY, tX, tY)
                                IF l THEN sGDIPfn = "GdipDrawImageRectI": GOSUB gdiperror
                            END IF
                            sz = UCODE$("hello!")
                            setrect BYVAL VARPTR(r), 10, 10, 100, 100
                            hBrush = SelectObject(hDC, GetStockObject(%NULL_BRUSH))
                
                            ' Create the StringFormat object
                            ' We can pass NULL for the flags and language ID if we want
                            CALL GdipCreateStringFormat(0, 0, strFormat)
                            GdipDrawString ( pgraphics, sz, 1, hfont, r, 0, BYVAL 0)
                            l = gdipdeletegraphics(pgraphics)
                            IF l THEN sGDIPfn = "gdipdeletegraphics": GOSUB gdiperror
                            FUNCTION = 1
                        '
                        CASE %WM_USER + 401
                            spicpath = UCODE$(GetPic(CBHNDL))
                            getClientrect(CBHNDL, r)
                            IF himage THEN gdipdisposeimage (himage)
                            l = GDIPLoadImageFromFile (BYVAL spicPath , BYREF hImage)
                            IF l THEN sGDIPfn = "GDIPLoadImageFromFile": GOSUB gdiperror
                            IF hImage = 0 THEN EXIT SELECT
                            ' get image height, width & pixel format
                            l = GdipGetImageDimension (BYVAL hImage, BYREF origwidth, BYREF origheight)
                            IF l THEN sGDIPfn = "GdipGetImageDimension": GOSUB gdiperror
                            maxwidth  =  r.nright - r.nleft : maxheight = r.nbottom - r.ntop
                            l = GdipGetImagePixelFormat (BYVAL hImage, BYREF lPixelFormat)
                            IF l THEN sGDIPfn = "GdipGetImagePixelFormat": GOSUB gdiperror
                            ' derive new image size for display on the dailog, preserving aspect ratio
                            ' the results are declared STATIC so that the %WM_ERASEBKGND handler can use them
                            skIconise ( BYVAL origwidth, BYVAL origheight, BYVAL maxwidth, BYVAL maxheight, _
                                        BYREF ofsX, BYREF ofsY, BYREF tX, BYREF tY)
                            ' force redraw via WM_ERASEBKGND
                            invalidaterect CBHNDL, r, %TRUE
                        '
                        CASE %WM_DESTROY
                            IF himage THEN
                                deleteobject ( hfont)
                                l = gdipdisposeimage(himage)
                                IF l THEN sGDIPfn = "GdipDisposeImage": GOSUB gdiperror
                            END IF
                        '
                    END SELECT
                    EXIT FUNCTION
                ''''''''''''''''''''''
                gdiperror:
                    ? sGDIPfn + ":" + sGDIPStatusCodes(l)
                    EXIT FUNCTION
                    RETURN
                ''''''''''''''''''''''
                LoadGDIPERMS:
                    DIM sGDIPStatusCodes(0 TO 20) AS STATIC STRING
                    sGDIPStatusCodes(%StatusOk                        ) = "Ok
                    sGDIPStatusCodes(%StatusGenericError              ) = "Generic Error
                    sGDIPStatusCodes(%StatusInvalidParameter          ) = "Invalid Parameter
                    sGDIPStatusCodes(%StatusOutOfMemory               ) = "Out Of Memory
                    sGDIPStatusCodes(%StatusObjectBusy                ) = "Object Busy
                    sGDIPStatusCodes(%StatusInsufficientBuffer        ) = "Insufficient Buffer
                    sGDIPStatusCodes(%StatusNotImplemented            ) = "Not Implemented
                    sGDIPStatusCodes(%StatusWin32Error                ) = "Win32 Error
                    sGDIPStatusCodes(%StatusWrongState                ) = "Wrong State
                    sGDIPStatusCodes(%StatusAborted                   ) = "Aborted
                    sGDIPStatusCodes(%StatusFileNotFound              ) = "File Not Found
                    sGDIPStatusCodes(%StatusValueOverflow             ) = "Value Overflow
                    sGDIPStatusCodes(%StatusAccessDenied              ) = "Access Denied
                    sGDIPStatusCodes(%StatusUnknownImageFormat        ) = "Unknown Image Format
                    sGDIPStatusCodes(%StatusFontFamilyNotFound        ) = "Font Family Not Found
                    sGDIPStatusCodes(%StatusFontStyleNotFound         ) = "Font Style Not Found
                    sGDIPStatusCodes(%StatusNotTrueTypeFont           ) = "Not TrueType Font
                    sGDIPStatusCodes(%StatusUnsupportedGdiplusVersion ) = "Unsupported Gdiplus Version
                    sGDIPStatusCodes(%StatusGdiplusNotInitialized     ) = "Gdiplus Not Initialized
                    sGDIPStatusCodes(%StatusPropertyNotFound          ) = "Property Not Found
                    sGDIPStatusCodes(%StatusPropertyNotSupported      ) = "Property Not Supported
                    RETURN
                
                END FUNCTION
                '------------------------------------------------------------------------
                ' main dialog callback function
                '
                CALLBACK FUNCTION MainDlgCB()
                    LOCAL s AS STRING
                    STATIC hPicWnd      AS DWORD
                
                    SELECT CASE AS LONG CBMSG
                        CASE %WM_INITDIALOG
                            ' create another dialog on which the image will be displayed.
                            ' It didn't have to be a dialog, but if a control in the main dialog
                            ' was used then it would have to be sub- or super-classed to receive its
                            ' own WM_ERASEBKGND messages. This is just the easiest (DDT) way to do it.
                            DIALOG NEW CBHNDL, "", 85, 5, 190, 125, %WS_POPUP OR %WS_BORDER OR _
                                %WS_POPUP OR %WS_CHILD OR _
                                %WS_CLIPSIBLINGS OR %WS_VISIBLE OR %DS_3DLOOK OR %DS_NOFAILCREATE OR _
                                %DS_SETFONT, %WS_EX_CONTROLPARENT OR %WS_EX_TOOLWINDOW OR _
                                %WS_EX_TOPMOST OR %WS_EX_LEFT OR %WS_EX_LTRREADING TO hPicWnd
                            DIALOG SHOW MODELESS hPicWnd, CALL PicDlgCB 'TO lRslt
                
                        CASE %WM_COMMAND
                            SELECT CASE AS LONG CBCTL
                                CASE %IDC_getpic_bn
                                    IF HI(WORD,CBWPARAM) = %BN_CLICKED THEN
                                        sendmessage hPicWnd, %WM_USER + 401, 0, 0
                                    END IF
                            END SELECT
                    END SELECT
                END FUNCTION
                '------------------------------------------------------------------
                FUNCTION MainDlg(BYVAL hParent AS DWORD) AS LONG
                    LOCAL lRslt AS LONG
                    LOCAL hDlg  AS DWORD
                
                    DIALOG NEW hParent, "using GDI+ example 1", 139, 129, 279, 135, _
                        %WS_POPUP OR %WS_BORDER OR %WS_DLGFRAME OR %WS_SYSMENU OR _
                        %WS_CLIPSIBLINGS OR %WS_VISIBLE OR %DS_MODALFRAME OR %DS_3DLOOK OR _
                        %DS_NOFAILCREATE OR %DS_SETFONT, _
                        %WS_EX_CONTROLPARENT, TO hDlg
                    CONTROL ADD BUTTON, hDlg, %IDC_getpic_bn, "find a picture", 5, 5, 75, 15
                    DIALOG SHOW MODAL hDlg, CALL MainDlgCB TO lRslt
                    FUNCTION = lRslt
                END FUNCTION
                '=======================================================================
                FUNCTION PBMAIN()
                    STATIC nstatus AS LONG
                    STATIC token AS DWORD
                    STATIC StartupInput AS GdiplusStartupInput
                
                    StartupInput.GdiplusVersion = 1
                    nStatus = GdiplusStartup(token, StartupInput, BYVAL %NULL)
                    IF nStatus THEN
                        MSGBOX  "Error initializing GDI+", %mb_applmodal, "Warning"
                        EXIT FUNCTION
                    END IF
                    MainDlg %HWND_DESKTOP
                    GdiplusShutdown token
                
                END FUNCTION

                Comment


                • #9
                  Originally posted by Cliff Nichols View Post
                  Not sure, but I think Scott means kinda like National Instruments "Labview" that puts a silhouette of their insignia in the bottom right of their apps in Forms/Dialogs/Windows that are made with shareware or trial programs

                  Kind of like "If you like it...buy it.....If you don't...then do not use it"

                  It helps somewhat with sales, and is somewhat not annoying as other techniques. And a DEFINITE tip-off when supporting a call or email or other that turns out is a user that wants something for nothing.

                  I could be off...but I think the generic premise is true
                  This is correct, if a rather large website was to use this (Pipe dream) and was displaying an unregistered version sign or a "BBSDown" sign and had the chance to eliminate that by purchasing, odds are if they like it they will purchase it.

                  But having undertaken this I've had some second thoughts, the nag screen is probably enough - but this STILL looks like it would be fun to do to all of my pictures in my My Pictures (That would equate to about 8000)....
                  Scott Turchin
                  MCSE, MCP+I
                  http://www.tngbbs.com
                  ----------------------
                  True Karate-do is this: that in daily life, one's mind and body be trained and developed in a spirit of humility; and that in critical times, one be devoted utterly to the cause of justice. -Gichin Funakoshi

                  Comment


                  • #10
                    Scott,
                    I'm sorry I misunderstood what you were meaning.

                    For adding text on the bitmap, you can use the free ImageMagick. With that, you can do just about any kind of programmatic modifications to images, including adding text / watermarks.

                    Here are just some samples:
                    ImageMagick: A graphics wizard for the command line

                    Bye!
                    -- The universe tends toward maximum irony. Don't push it.

                    File Extension Seeker - Metasearch engine for file extensions / file types
                    Online TrID file identifier | TrIDLib - Identify thousands of file formats

                    Comment


                    • #11
                      Getting somewhere with this GDIPLUS drawing text on a picture, but it is ignoring the position (bounding rectangle in GDIPdrawstring), and only the last 3 chars are drawn on the image... Once again, I must put it down, this time to work on something else - Any GDIP experts out there?

                      Code:
                      '   A very simple application which displays a picture file chosen by the user.
                      '   Uses GDIPLUS and includes error reporting using GDIplus status codes
                      '   PB Win 8.04, no dependencies except standard INCLUDES.
                      '
                      '   Chris Holbrook 1 August 2008
                      '
                      '   5-AUG-2007 revised WM_ERASEBKGND handler
                      '   21-OCT-2008 added code to write a fixed string to the image.
                      '                      the code is all in the WM_INITDIALOG and WM_ERASEBKGND
                      '                      handlers in the PICDLGCB function
                      '
                      #COMPILE EXE
                      #DIM ALL
                      
                      #INCLUDE "WIN32API.INC"
                      #INCLUDE "comdlg32.inc"
                      #INCLUDE "c:\bepo\sgoti\GDIPLUS.INC"
                      ' GDI+ status (error) codes
                      %StatusOk = 0
                      %StatusGenericError = 1
                      %StatusInvalidParameter = 2
                      %StatusOutOfMemory = 3
                      %StatusObjectBusy = 4
                      %StatusInsufficientBuffer = 5
                      %StatusNotImplemented = 6
                      %StatusWin32Error = 7
                      %StatusWrongState = 8
                      %StatusAborted = 9
                      %StatusFileNotFound = 10
                      %StatusValueOverflow = 11
                      %StatusAccessDenied = 12
                      %StatusUnknownImageFormat = 13
                      %StatusFontFamilyNotFound = 14
                      %StatusFontStyleNotFound = 15
                      %StatusNotTrueTypeFont = 16
                      %StatusUnsupportedGdiplusVersion = 17
                      %StatusGdiplusNotInitialized = 18
                      %StatusPropertyNotFound = 19
                      %StatusPropertyNotSupported = 20
                      
                      %IDD_DIALOG1      =  101
                      %IDC_getpic_bn    = 1004
                      '------------------------------------------------------------------------------
                      
                      DECLARE SUB skIconise (BYVAL xPic AS LONG, BYVAL yPic AS LONG,            _ picture dimensions
                                     BYVAL xCell AS LONG, BYVAL yCell AS LONG,          _ FRAME dimensions
                                     BYREF xOfs AS LONG, BYREF yOfs AS LONG,            _ calc'd offset in frame
                                     BYREF xSize AS LONG, BYREF ySize AS LONG)   ' thumbnail dimensions
                      '-------------------------------------------------------------------------------------------------------
                      ' Computes location and size to stretch a bitmap preserving its aspect.
                      '
                      SUB skIconise (BYVAL xPic AS LONG, BYVAL yPic AS LONG,            _ picture dimensions
                                     BYVAL xCell AS LONG, BYVAL yCell AS LONG,          _ FRAME dimensions
                                     BYREF xOfs AS LONG, BYREF yOfs AS LONG,            _ calc'd offset in frame
                                     BYREF xSize AS LONG, BYREF ySize AS LONG) EXPORT   ' thumbnail dimensions
                        LOCAL SCALE AS SINGLE
                      
                          IF xPIC& THEN scale! = xCell& / xPic&
                          IF scale! > 1 THEN scale! = 1
                          xSize& = xPic& * scale!: ySize& = yPic& * scale!
                        ' In case Height > 150 compute new scale factor
                          IF ySize& > yCell& THEN
                             IF yPic& THEN scale! = yCell& / yPic&
                             xSize& = xPic& * scale!: ySize& = yPic& * scale!
                          END IF
                          xOfs& = (xCell& - xSize&) \ 2
                          yOfs& = (yCell& - ySize&) \ 2
                      END SUB
                      '---------------------------------------------------------------------
                      ' get image filename
                      FUNCTION getpic (hD AS LONG) AS STRING
                          LOCAL buf, spath, sfile AS STRING
                          LOCAL dwstyle AS DWORD
                          LOCAL hFile AS LONG
                          dwStyle = %OFN_EXPLORER OR %OFN_FILEMUSTEXIST OR %OFN_HIDEREADONLY
                          Buf   = "Picture files (*.JPG,*.PNG,*.TIF,*.ICO,*.GIF,*.BMP)|*.JPG|*.PNG|*.TIF|*.ICO|*.PNG|*.BMP|"
                          sfile = "*.JPG;*.PNG;*.TIF;*.ICO;*.GIF;*.BMP"
                          IF OpenFileDialog (hD, "Locate image file ", sfile, spath, buf, "JPG", dwstyle) = 0 THEN
                             EXIT FUNCTION
                          END IF
                          FUNCTION = sfile
                      END FUNCTION
                      '----------------------------------------------------------------------
                      FUNCTION MakeFont(BYVAL fName AS STRING, BYVAL ptSize AS LONG, _
                                        OPT BYVAL attr AS STRING) AS DWORD
                         '--------------------------------------------------------------------
                         ' Create a desired font and return its handle.
                         ' attr = "biu" for bold, italic, and underlined (any order)
                         '--------------------------------------------------------------------
                         LOCAL hDC AS DWORD, CharSet AS LONG, CyPixels AS LONG
                         LOCAL BOLD, italic, uLine AS LONG
                         IF LEN(attr) THEN
                            IF INSTR(LCASE$(attr), "b") THEN BOLD = %FW_BOLD
                            IF INSTR(LCASE$(attr), "i") THEN italic = 1
                            IF INSTR(LCASE$(attr), "u") THEN uLine = 1
                         END IF
                         hDC = GetDC(%HWND_DESKTOP)
                         CyPixels  = GetDeviceCaps(hDC, %LOGPIXELSY)
                         ReleaseDC %HWND_DESKTOP, hDC
                         PtSize = 0 - (ptSize * CyPixels) \ 72
                         FUNCTION = CreateFont(ptSize, 0, 0, 0, BOLD, italic, uLine, _
                                   %FALSE, CharSet, %OUT_TT_PRECIS, _
                                   %CLIP_DEFAULT_PRECIS, %DEFAULT_QUALITY, _
                                   %FF_DONTCARE , BYCOPY fName)
                      END FUNCTION
                      '------------------------------------------------------------------------
                      ' callback function for dialog on which the image is displayed
                      '
                      CALLBACK FUNCTION PicDlgCB()
                          STATIC   sPicPath                AS STRING
                          STATIC   himage                  AS DWORD
                          LOCAL    pGraphics               AS DWORD
                          LOCAL    hdc                     AS DWORD
                          STATIC   pfont, pfontfamily, pbrush, pformat _
                                                           AS DWORD
                          LOCAL    r                       AS rect
                          LOCAL    lPixelFormat            AS LONG
                          LOCAL    l, framex, framey AS LONG
                          STATIC   ofsx, ofsy, tX, tY      AS LONG
                          LOCAL    maxwidth, maxheight     AS LONG
                          LOCAL    origwidth, origheight   AS SINGLE
                          STATIC   sGDIPStatusCodes()      AS STRING ' table of error codes referenced by GDIP status codes
                          LOCAL    sGDIPfn                 AS STRING ' GDIP function name for error reporting
                          LOCAL    sz                      AS ASCIZ * 16
                          LOCAL    sfont                   AS STRING
                      
                          SELECT CASE AS LONG CBMSG
                              CASE %WM_INITDIALOG
                                  ' initialise static variables
                                  himage = 0: ofsx = 0: ofsy = 0: tX = 0: tY = 0
                                  ' create font
                                  'hfont = makefont ("Courier New", 10, "")
                                  'Create Brush and Pen
                                  GdipCreateSolidFill(&HFF000000, pBrush)
                      
                                  'Create FontFamily, Font and Format
                                  sfont = UCODE$("Courier New")
                                  L = GdipCreateFontFamilyFromName(BYVAL sfont, BYVAL %NULL, pFontFamily)
                                  'IF l THEN sGDIPfn = "GdipCreateFontFamilyFromName": GOSUB gdiperror
                                  L = GdipCreateFont(pFontFamily, 20, %FontStyleBold, %UnitPixel, pFont)
                                  L = GdipCreateStringFormat(BYVAL %NULL, BYVAL %LANG_NEUTRAL, BYVAL VARPTR( pFormat))
                                  L = GdipSetStringFormatLineAlign(pFormat, %StringAlignmentCenter)
                                  L = GdipSetStringFormatAlign(pFormat, %StringAlignmentCenter)
                                  L = GdipSetStringFormatFlags(pFormat, %StringFormatFlagsNoClip OR %StringFormatFlagsNoWrap)
                                  L = GdipSetStringFormatTrimming(pFormat, %StringTrimmingNone)
                      
                                  ' load GDIPlus error messages
                                  GOSUB LoadGDIPERMS
                              '
                              CASE %WM_ERASEBKGND
                                  IF himage = 0 THEN FUNCTION = 0 : EXIT SELECT
                                  hdc = getdc(CBHNDL)
                                  IF GdipCreatefromHDC ( hDC, pGraphics) =  0 THEN
                                      l = GdipDrawImageRectI(pGraphics, himage, ofsX, ofsY, tX, tY)
                                      IF l THEN sGDIPfn = "GdipDrawImageRectI": GOSUB gdiperror
                                  END IF
                                  sz = UCODE$("hello!")
                                  getclientrect CBHNDL, BYVAL VARPTR(r)
                                  r.nleft = 10: r.ntop = 10
                                  l = GdipDrawString ( pgraphics, sz, 6, pfont, r, pFormat, pBrush)
                                  l = gdipdeletegraphics(pgraphics)
                                  IF l THEN sGDIPfn = "gdipdeletegraphics": GOSUB gdiperror
                                  FUNCTION = 1
                              '
                              CASE %WM_USER + 401
                                  spicpath = UCODE$(GetPic(CBHNDL))
                                  getClientrect(CBHNDL, r)
                                  IF himage THEN gdipdisposeimage (himage)
                                  l = GDIPLoadImageFromFile (BYVAL spicPath , BYREF hImage)
                                  IF l THEN sGDIPfn = "GDIPLoadImageFromFile": GOSUB gdiperror
                                  IF hImage = 0 THEN EXIT SELECT
                                  ' get image height, width & pixel format
                                  l = GdipGetImageDimension (BYVAL hImage, BYREF origwidth, BYREF origheight)
                                  IF l THEN sGDIPfn = "GdipGetImageDimension": GOSUB gdiperror
                                  maxwidth  =  r.nright - r.nleft : maxheight = r.nbottom - r.ntop
                                  l = GdipGetImagePixelFormat (BYVAL hImage, BYREF lPixelFormat)
                                  IF l THEN sGDIPfn = "GdipGetImagePixelFormat": GOSUB gdiperror
                                  ' derive new image size for display on the dailog, preserving aspect ratio
                                  ' the results are declared STATIC so that the %WM_ERASEBKGND handler can use them
                                  skIconise ( BYVAL origwidth, BYVAL origheight, BYVAL maxwidth, BYVAL maxheight, _
                                              BYREF ofsX, BYREF ofsY, BYREF tX, BYREF tY)
                                  ' force redraw via WM_ERASEBKGND
                                  invalidaterect CBHNDL, r, %TRUE
                              '
                              CASE %WM_DESTROY
                                  IF himage THEN
                                  'Cleanup brush
                                  IF (pBrush) THEN
                                      GdipDeleteBrush(pBrush)
                                      pBrush = %NULL
                                  END IF
                      
                                  'Cleanup font
                                  IF (pFont) THEN
                                      GdipDeleteFont(pFont)
                                      pFont = %NULL
                                  END IF
                      
                                  'Cleanup format
                                  IF (pFormat) THEN
                                      GdipDeleteStringFormat(pFormat)
                                      pFormat = %NULL
                                  END IF
                      
                                  'Cleanup font family
                                  IF (pFontFamily) THEN
                                      GdipDeleteFontFamily(pFontFamily)
                                  END IF
                                      l = gdipdisposeimage(himage)
                                      IF l THEN sGDIPfn = "GdipDisposeImage": GOSUB gdiperror
                                  END IF
                              '
                          END SELECT
                          EXIT FUNCTION
                      ''''''''''''''''''''''
                      gdiperror:
                          ? sGDIPfn + ":" + sGDIPStatusCodes(l)
                          EXIT FUNCTION
                          RETURN
                      ''''''''''''''''''''''
                      LoadGDIPERMS:
                          DIM sGDIPStatusCodes(0 TO 20) AS STATIC STRING
                          sGDIPStatusCodes(%StatusOk                        ) = "Ok
                          sGDIPStatusCodes(%StatusGenericError              ) = "Generic Error
                          sGDIPStatusCodes(%StatusInvalidParameter          ) = "Invalid Parameter
                          sGDIPStatusCodes(%StatusOutOfMemory               ) = "Out Of Memory
                          sGDIPStatusCodes(%StatusObjectBusy                ) = "Object Busy
                          sGDIPStatusCodes(%StatusInsufficientBuffer        ) = "Insufficient Buffer
                          sGDIPStatusCodes(%StatusNotImplemented            ) = "Not Implemented
                          sGDIPStatusCodes(%StatusWin32Error                ) = "Win32 Error
                          sGDIPStatusCodes(%StatusWrongState                ) = "Wrong State
                          sGDIPStatusCodes(%StatusAborted                   ) = "Aborted
                          sGDIPStatusCodes(%StatusFileNotFound              ) = "File Not Found
                          sGDIPStatusCodes(%StatusValueOverflow             ) = "Value Overflow
                          sGDIPStatusCodes(%StatusAccessDenied              ) = "Access Denied
                          sGDIPStatusCodes(%StatusUnknownImageFormat        ) = "Unknown Image Format
                          sGDIPStatusCodes(%StatusFontFamilyNotFound        ) = "Font Family Not Found
                          sGDIPStatusCodes(%StatusFontStyleNotFound         ) = "Font Style Not Found
                          sGDIPStatusCodes(%StatusNotTrueTypeFont           ) = "Not TrueType Font
                          sGDIPStatusCodes(%StatusUnsupportedGdiplusVersion ) = "Unsupported Gdiplus Version
                          sGDIPStatusCodes(%StatusGdiplusNotInitialized     ) = "Gdiplus Not Initialized
                          sGDIPStatusCodes(%StatusPropertyNotFound          ) = "Property Not Found
                          sGDIPStatusCodes(%StatusPropertyNotSupported      ) = "Property Not Supported
                          RETURN
                      
                      END FUNCTION
                      '------------------------------------------------------------------------
                      ' main dialog callback function
                      '
                      CALLBACK FUNCTION MainDlgCB()
                          LOCAL s AS STRING
                          STATIC hPicWnd      AS DWORD
                      
                          SELECT CASE AS LONG CBMSG
                              CASE %WM_INITDIALOG
                                  ' create another dialog on which the image will be displayed.
                                  ' It didn't have to be a dialog, but if a control in the main dialog
                                  ' was used then it would have to be sub- or super-classed to receive its
                                  ' own WM_ERASEBKGND messages. This is just the easiest (DDT) way to do it.
                                  DIALOG NEW CBHNDL, "", 85, 5, 190, 125, %WS_POPUP OR %WS_BORDER OR _
                                      %WS_POPUP OR %WS_CHILD OR _
                                      %WS_CLIPSIBLINGS OR %WS_VISIBLE OR %DS_3DLOOK OR %DS_NOFAILCREATE OR _
                                      %DS_SETFONT, %WS_EX_CONTROLPARENT OR %WS_EX_TOOLWINDOW OR _
                                      %WS_EX_TOPMOST OR %WS_EX_LEFT OR %WS_EX_LTRREADING TO hPicWnd
                                  DIALOG SHOW MODELESS hPicWnd, CALL PicDlgCB 'TO lRslt
                      
                              CASE %WM_COMMAND
                                  SELECT CASE AS LONG CBCTL
                                      CASE %IDC_getpic_bn
                                          IF HI(WORD,CBWPARAM) = %BN_CLICKED THEN
                                              sendmessage hPicWnd, %WM_USER + 401, 0, 0
                                          END IF
                                  END SELECT
                          END SELECT
                      END FUNCTION
                      '------------------------------------------------------------------
                      FUNCTION MainDlg(BYVAL hParent AS DWORD) AS LONG
                          LOCAL lRslt AS LONG
                          LOCAL hDlg  AS DWORD
                      
                          DIALOG NEW hParent, "using GDI+ example 1", 139, 129, 279, 135, _
                              %WS_POPUP OR %WS_BORDER OR %WS_DLGFRAME OR %WS_SYSMENU OR _
                              %WS_CLIPSIBLINGS OR %WS_VISIBLE OR %DS_MODALFRAME OR %DS_3DLOOK OR _
                              %DS_NOFAILCREATE OR %DS_SETFONT, _
                              %WS_EX_CONTROLPARENT, TO hDlg
                          CONTROL ADD BUTTON, hDlg, %IDC_getpic_bn, "find a picture", 5, 5, 75, 15
                          DIALOG SHOW MODAL hDlg, CALL MainDlgCB TO lRslt
                          FUNCTION = lRslt
                      END FUNCTION
                      '=======================================================================
                      FUNCTION PBMAIN()
                          STATIC nstatus AS LONG
                          STATIC token AS DWORD
                          STATIC StartupInput AS GdiplusStartupInput
                      
                          StartupInput.GdiplusVersion = 1
                          nStatus = GdiplusStartup(token, StartupInput, BYVAL %NULL)
                          IF nStatus THEN
                              MSGBOX  "Error initializing GDI+", %MB_APPLMODAL, "Warning"
                              EXIT FUNCTION
                          END IF
                          MainDlg %HWND_DESKTOP
                          GdiplusShutdown token
                      
                      END FUNCTION

                      Comment


                      • #12
                        I tried taking a look, but need GDIPLUS.INC where is that located?
                        Engineer's Motto: If it aint broke take it apart and fix it

                        "If at 1st you don't succeed... call it version 1.0"

                        "Half of Programming is coding"....."The other 90% is DEBUGGING"

                        "Document my code????" .... "WHYYY??? do you think they call it CODE? "

                        Comment


                        • #13
                          Cliff, I got the headers from a post by Patrice Terrier at http://www.powerbasic.com/support/pb...ht=gdiplus.inc

                          There is also a good GDI+ resource at Jose Roca's site, http://www.jose.it-berater.org/gdiplus/iframe/index.htm, I have found this a great help.

                          Comment


                          • #14
                            Just use the powerbasic internal functions. In most cases they really should be all what you need to make something like a simple watermark. (I don't think that it supports something like alpha channels yet?)The only problem is the jpg converting. For this problem I use the freeimage.dll (and somewhere here in the forum are some declarations and includes for it...but don't have time to look for them.)

                            After loading the image with freeimage the most work should be done -> just load the jpg with freeimage, convert it to bitmap, and use the handle to manipulate it with the PowerBasic-GRAPHIC statements.

                            If the passing by handle doesn't work, you possibly can load the jpg, and save it per freeimage.dll as bmp to load it with powerbasic statements directly from harddisk. I am no expert, but this would be my way to try.

                            Regards,
                            Marc Giesmann

                            Comment


                            • #15
                              At the third attempt, here is text drawn on an image with GDI+. I still don't understand how to position the text on the image, it has to do with the stringformat setup.

                              Having drawn text over the image, you could save the resulting graphic to a file if you wanted, so this example could easily be adapted to label an image file, or batch of image files, with text.

                              Code:
                              '   A very simple application which displays a picture file chosen by the user.
                              '   Uses GDIPLUS and includes error reporting using GDIplus status codes
                              '   PB Win 8.04, no dependencies except standard INCLUDES.
                              '
                              '   Chris Holbrook 1 August 2008
                              '
                              '   23-OCT-2007 added code to draw a text string on the image
                              '
                              #COMPILE EXE
                              #DIM ALL
                              
                              #INCLUDE "WIN32API.INC"
                              #INCLUDE "comdlg32.inc"
                              #INCLUDE "GDIPLUS.INC"
                              ' GDI+ status (error) codes
                              %StatusOk = 0
                              %StatusGenericError = 1
                              %StatusInvalidParameter = 2
                              %StatusOutOfMemory = 3
                              %StatusObjectBusy = 4
                              %StatusInsufficientBuffer = 5
                              %StatusNotImplemented = 6
                              %StatusWin32Error = 7
                              %StatusWrongState = 8
                              %StatusAborted = 9
                              %StatusFileNotFound = 10
                              %StatusValueOverflow = 11
                              %StatusAccessDenied = 12
                              %StatusUnknownImageFormat = 13
                              %StatusFontFamilyNotFound = 14
                              %StatusFontStyleNotFound = 15
                              %StatusNotTrueTypeFont = 16
                              %StatusUnsupportedGdiplusVersion = 17
                              %StatusGdiplusNotInitialized = 18
                              %StatusPropertyNotFound = 19
                              %StatusPropertyNotSupported = 20
                              
                              %IDD_DIALOG1      =  101
                              %IDC_getpic_bn    = 1004
                              '------------------------------------------------------------------------------
                              
                              DECLARE SUB skIconise (BYVAL xPic AS LONG, BYVAL yPic AS LONG,            _ picture dimensions
                                             BYVAL xCell AS LONG, BYVAL yCell AS LONG,          _ FRAME dimensions
                                             BYREF xOfs AS LONG, BYREF yOfs AS LONG,            _ calc'd offset in frame
                                             BYREF xSize AS LONG, BYREF ySize AS LONG)   ' thumbnail dimensions
                              '-------------------------------------------------------------------------------------------------------
                              ' Computes location and size to stretch a bitmap preserving its aspect.
                              '
                              SUB skIconise (BYVAL xPic AS LONG, BYVAL yPic AS LONG,            _ picture dimensions
                                             BYVAL xCell AS LONG, BYVAL yCell AS LONG,          _ FRAME dimensions
                                             BYREF xOfs AS LONG, BYREF yOfs AS LONG,            _ calc'd offset in frame
                                             BYREF xSize AS LONG, BYREF ySize AS LONG) EXPORT   ' thumbnail dimensions
                                LOCAL SCALE AS SINGLE
                              
                                  IF xPIC& THEN scale! = xCell& / xPic&
                                  IF scale! > 1 THEN scale! = 1
                                  xSize& = xPic& * scale!: ySize& = yPic& * scale!
                                ' In case Height > 150 compute new scale factor
                                  IF ySize& > yCell& THEN
                                     IF yPic& THEN scale! = yCell& / yPic&
                                     xSize& = xPic& * scale!: ySize& = yPic& * scale!
                                  END IF
                                  xOfs& = (xCell& - xSize&) \ 2
                                  yOfs& = (yCell& - ySize&) \ 2
                              END SUB
                              '---------------------------------------------------------------------
                              ' get image filename
                              FUNCTION getpic (hD AS LONG) AS STRING
                                  LOCAL buf, spath, sfile AS STRING
                                  LOCAL dwstyle AS DWORD
                                  LOCAL hFile AS LONG
                                  dwStyle = %OFN_EXPLORER OR %OFN_FILEMUSTEXIST OR %OFN_HIDEREADONLY
                                  Buf   = "Picture files (*.JPG,*.PNG,*.TIF,*.ICO,*.GIF,*.BMP)|*.JPG|*.PNG|*.TIF|*.ICO|*.PNG|*.BMP|"
                                  sfile = "*.JPG;*.PNG;*.TIF;*.ICO;*.GIF;*.BMP"
                                  IF OpenFileDialog (hD, "Locate image file ", sfile, spath, buf, "JPG", dwstyle) = 0 THEN
                                     EXIT FUNCTION
                                  END IF
                                  FUNCTION = sfile
                              END FUNCTION
                              '----------------------------------------------------------------------
                              FUNCTION MakeFont(BYVAL fName AS STRING, BYVAL ptSize AS LONG, _
                                                OPT BYVAL attr AS STRING) AS DWORD
                                 '--------------------------------------------------------------------
                                 ' Create a desired font and return its handle.
                                 ' attr = "biu" for bold, italic, and underlined (any order)
                                 '--------------------------------------------------------------------
                                 LOCAL hDC AS DWORD, CharSet AS LONG, CyPixels AS LONG
                                 LOCAL BOLD, italic, uLine AS LONG
                                 IF LEN(attr) THEN
                                    IF INSTR(LCASE$(attr), "b") THEN BOLD = %FW_BOLD
                                    IF INSTR(LCASE$(attr), "i") THEN italic = 1
                                    IF INSTR(LCASE$(attr), "u") THEN uLine = 1
                                 END IF
                                 hDC = GetDC(%HWND_DESKTOP)
                                 CyPixels  = GetDeviceCaps(hDC, %LOGPIXELSY)
                                 ReleaseDC %HWND_DESKTOP, hDC
                                 PtSize = 0 - (ptSize * CyPixels) \ 72
                                 FUNCTION = CreateFont(ptSize, 0, 0, 0, BOLD, italic, uLine, _
                                           %FALSE, CharSet, %OUT_TT_PRECIS, _
                                           %CLIP_DEFAULT_PRECIS, %DEFAULT_QUALITY, _
                                           %FF_DONTCARE , BYCOPY fName)
                              END FUNCTION
                              '------------------------------------------------------------------------
                              ' callback function for dialog on which the image is displayed
                              '
                              CALLBACK FUNCTION PicDlgCB()
                                  STATIC   sPicPath                AS STRING
                                  STATIC   himage                  AS DWORD
                                  LOCAL    pGraphics               AS DWORD
                                  LOCAL    hdc                     AS DWORD
                                  STATIC   pfont, pfontfamily, pbrush, pformat _
                                                                   AS DWORD
                                  LOCAL    r                       AS rect
                                  LOCAL    lPixelFormat            AS LONG
                                  LOCAL    l, framex, framey AS LONG
                                  STATIC   ofsx, ofsy, tX, tY      AS LONG
                                  LOCAL    maxwidth, maxheight     AS LONG
                                  LOCAL    origwidth, origheight   AS SINGLE
                                  STATIC   sGDIPStatusCodes()      AS STRING ' table of error codes referenced by GDIP status codes
                                  LOCAL    sGDIPfn                 AS STRING ' GDIP function name for error reporting
                                  LOCAL    sz                      AS ASCIZ * 16
                                  LOCAL    s, sfont                AS STRING
                              
                                  SELECT CASE AS LONG CBMSG
                                      CASE %WM_INITDIALOG
                                          ' initialise static variables
                                          himage = 0: ofsx = 0: ofsy = 0: tX = 0: tY = 0
                                          ' create font
                                          'hfont = makefont ("Courier New", 10, "")
                                          'Create Brush and Pen
                                          GdipCreateSolidFill(&HFF000000, pBrush)
                              
                                          'Create FontFamily, Font and Format
                                          sfont = UCODE$("Courier New")
                                          L = GdipCreateFontFamilyFromName(BYVAL sfont, BYVAL %NULL, pFontFamily)
                                          'IF l THEN sGDIPfn = "GdipCreateFontFamilyFromName": GOSUB gdiperror
                                          L = GdipCreateFont(pFontFamily, 20, %FontStyleBold, %UnitPixel, pFont)
                                          L = GdipCreateStringFormat(BYVAL %NULL, BYVAL %LANG_NEUTRAL, BYVAL VARPTR( pFormat))
                              '            L = GdipSetStringFormatLineAlign(pFormat, %StringAlignmentCenter)
                              '            L = GdipSetStringFormatAlign(pFormat, %StringAlignmentCenter)
                                          L = GdipSetStringFormatFlags(pFormat, %StringFormatFlagsNoClip OR %StringFormatFlagsNoWrap)
                                          L = GdipSetStringFormatTrimming(pFormat, %StringTrimmingNone)
                              
                                          ' load GDIPlus error messages
                                          GOSUB LoadGDIPERMS
                                      '
                                      CASE %WM_ERASEBKGND
                                          IF himage = 0 THEN FUNCTION = 0 : EXIT SELECT
                                          hdc = getdc(CBHNDL)
                                          IF GdipCreatefromHDC ( hDC, pGraphics) =  0 THEN
                                              l = GdipDrawImageRectI(pGraphics, himage, ofsX, ofsY, tX, tY)
                                              IF l THEN sGDIPfn = "GdipDrawImageRectI": GOSUB gdiperror
                                          END IF
                                          s = "UNLICENSED COPY"
                                          l = LEN(s)
                                          s = UCODE$(s)
                                          'getclientrect CBHNDL, BYVAL VARPTR(r)
                                          setrect r, 50, 50, 100, 100
                                          l = GdipDrawString ( pgraphics, s, l, pfont, r, pFormat, pBrush)
                                          l = gdipdeletegraphics(pgraphics)
                                          IF l THEN sGDIPfn = "gdipdeletegraphics": GOSUB gdiperror
                                          FUNCTION = 1
                                      '
                                      CASE %WM_USER + 401
                                          spicpath = UCODE$(GetPic(CBHNDL))
                                          getClientrect(CBHNDL, r)
                                          IF himage THEN gdipdisposeimage (himage)
                                          l = GDIPLoadImageFromFile (BYVAL spicPath , BYREF hImage)
                                          IF l THEN sGDIPfn = "GDIPLoadImageFromFile": GOSUB gdiperror
                                          IF hImage = 0 THEN EXIT SELECT
                                          ' get image height, width & pixel format
                                          l = GdipGetImageDimension (BYVAL hImage, BYREF origwidth, BYREF origheight)
                                          IF l THEN sGDIPfn = "GdipGetImageDimension": GOSUB gdiperror
                                          maxwidth  =  r.nright - r.nleft : maxheight = r.nbottom - r.ntop
                                          l = GdipGetImagePixelFormat (BYVAL hImage, BYREF lPixelFormat)
                                          IF l THEN sGDIPfn = "GdipGetImagePixelFormat": GOSUB gdiperror
                                          ' derive new image size for display on the dailog, preserving aspect ratio
                                          ' the results are declared STATIC so that the %WM_ERASEBKGND handler can use them
                                          skIconise ( BYVAL origwidth, BYVAL origheight, BYVAL maxwidth, BYVAL maxheight, _
                                                      BYREF ofsX, BYREF ofsY, BYREF tX, BYREF tY)
                                          ' force redraw via WM_ERASEBKGND
                                          invalidaterect CBHNDL, r, %TRUE
                                      '
                                      CASE %WM_DESTROY
                                          IF himage THEN
                                          'Cleanup brush
                                          IF (pBrush) THEN
                                              GdipDeleteBrush(pBrush)
                                              pBrush = %NULL
                                          END IF
                              
                                          'Cleanup font
                                          IF (pFont) THEN
                                              GdipDeleteFont(pFont)
                                              pFont = %NULL
                                          END IF
                              
                                          'Cleanup format
                                          IF (pFormat) THEN
                                              GdipDeleteStringFormat(pFormat)
                                              pFormat = %NULL
                                          END IF
                              
                                          'Cleanup font family
                                          IF (pFontFamily) THEN
                                              GdipDeleteFontFamily(pFontFamily)
                                          END IF
                                              l = gdipdisposeimage(himage)
                                              IF l THEN sGDIPfn = "GdipDisposeImage": GOSUB gdiperror
                                          END IF
                                      '
                                  END SELECT
                                  EXIT FUNCTION
                              ''''''''''''''''''''''
                              gdiperror:
                                  ? sGDIPfn + ":" + sGDIPStatusCodes(l)
                                  EXIT FUNCTION
                                  RETURN
                              ''''''''''''''''''''''
                              LoadGDIPERMS:
                                  DIM sGDIPStatusCodes(0 TO 20) AS STATIC STRING
                                  sGDIPStatusCodes(%StatusOk                        ) = "Ok
                                  sGDIPStatusCodes(%StatusGenericError              ) = "Generic Error
                                  sGDIPStatusCodes(%StatusInvalidParameter          ) = "Invalid Parameter
                                  sGDIPStatusCodes(%StatusOutOfMemory               ) = "Out Of Memory
                                  sGDIPStatusCodes(%StatusObjectBusy                ) = "Object Busy
                                  sGDIPStatusCodes(%StatusInsufficientBuffer        ) = "Insufficient Buffer
                                  sGDIPStatusCodes(%StatusNotImplemented            ) = "Not Implemented
                                  sGDIPStatusCodes(%StatusWin32Error                ) = "Win32 Error
                                  sGDIPStatusCodes(%StatusWrongState                ) = "Wrong State
                                  sGDIPStatusCodes(%StatusAborted                   ) = "Aborted
                                  sGDIPStatusCodes(%StatusFileNotFound              ) = "File Not Found
                                  sGDIPStatusCodes(%StatusValueOverflow             ) = "Value Overflow
                                  sGDIPStatusCodes(%StatusAccessDenied              ) = "Access Denied
                                  sGDIPStatusCodes(%StatusUnknownImageFormat        ) = "Unknown Image Format
                                  sGDIPStatusCodes(%StatusFontFamilyNotFound        ) = "Font Family Not Found
                                  sGDIPStatusCodes(%StatusFontStyleNotFound         ) = "Font Style Not Found
                                  sGDIPStatusCodes(%StatusNotTrueTypeFont           ) = "Not TrueType Font
                                  sGDIPStatusCodes(%StatusUnsupportedGdiplusVersion ) = "Unsupported Gdiplus Version
                                  sGDIPStatusCodes(%StatusGdiplusNotInitialized     ) = "Gdiplus Not Initialized
                                  sGDIPStatusCodes(%StatusPropertyNotFound          ) = "Property Not Found
                                  sGDIPStatusCodes(%StatusPropertyNotSupported      ) = "Property Not Supported
                                  RETURN
                              
                              END FUNCTION
                              '------------------------------------------------------------------------
                              ' main dialog callback function
                              '
                              CALLBACK FUNCTION MainDlgCB()
                                  LOCAL s AS STRING
                                  STATIC hPicWnd      AS DWORD
                              
                                  SELECT CASE AS LONG CBMSG
                                      CASE %WM_INITDIALOG
                                          ' create another dialog on which the image will be displayed.
                                          ' It didn't have to be a dialog, but if a control in the main dialog
                                          ' was used then it would have to be sub- or super-classed to receive its
                                          ' own WM_ERASEBKGND messages. This is just the easiest (DDT) way to do it.
                                          DIALOG NEW CBHNDL, "", 85, 5, 190, 125, %WS_POPUP OR %WS_BORDER OR _
                                              %WS_POPUP OR %WS_CHILD OR _
                                              %WS_CLIPSIBLINGS OR %WS_VISIBLE OR %DS_3DLOOK OR %DS_NOFAILCREATE OR _
                                              %DS_SETFONT, %WS_EX_CONTROLPARENT OR %WS_EX_TOOLWINDOW OR _
                                              %WS_EX_TOPMOST OR %WS_EX_LEFT OR %WS_EX_LTRREADING TO hPicWnd
                                          DIALOG SHOW MODELESS hPicWnd, CALL PicDlgCB 'TO lRslt
                              
                                      CASE %WM_COMMAND
                                          SELECT CASE AS LONG CBCTL
                                              CASE %IDC_getpic_bn
                                                  IF HI(WORD,CBWPARAM) = %BN_CLICKED THEN
                                                      sendmessage hPicWnd, %WM_USER + 401, 0, 0
                                                  END IF
                                          END SELECT
                                  END SELECT
                              END FUNCTION
                              '------------------------------------------------------------------
                              FUNCTION MainDlg(BYVAL hParent AS DWORD) AS LONG
                                  LOCAL lRslt AS LONG
                                  LOCAL hDlg  AS DWORD
                              
                                  DIALOG NEW hParent, "using GDI+ to draw text on image", 139, 129, 279, 135, _
                                      %WS_POPUP OR %WS_BORDER OR %WS_DLGFRAME OR %WS_SYSMENU OR _
                                      %WS_CLIPSIBLINGS OR %WS_VISIBLE OR %DS_MODALFRAME OR %DS_3DLOOK OR _
                                      %DS_NOFAILCREATE OR %DS_SETFONT, _
                                      %WS_EX_CONTROLPARENT, TO hDlg
                                  CONTROL ADD BUTTON, hDlg, %IDC_getpic_bn, "find a picture", 5, 5, 75, 15
                                  DIALOG SHOW MODAL hDlg, CALL MainDlgCB TO lRslt
                                  FUNCTION = lRslt
                              END FUNCTION
                              '=======================================================================
                              FUNCTION PBMAIN()
                                  STATIC nstatus AS LONG
                                  STATIC token AS DWORD
                                  STATIC StartupInput AS GdiplusStartupInput
                              
                                  StartupInput.GdiplusVersion = 1
                                  nStatus = GdiplusStartup(token, StartupInput, BYVAL %NULL)
                                  IF nStatus THEN
                                      MSGBOX  "Error initializing GDI+", %MB_APPLMODAL, "Warning"
                                      EXIT FUNCTION
                                  END IF
                                  MainDlg %HWND_DESKTOP
                                  GdiplusShutdown token
                              
                              END FUNCTION
                              Last edited by Chris Holbrook; 23 Oct 2008, 06:35 AM.

                              Comment

                              Working...
                              X