Foxite.COM Community Weblog

Foxite.COM Community Weblog - free weblog service for the Visual FoxPro Community.
Welcome to Foxite.COM Community Weblog Sign in | Join | Help
in
Home Blogs Forum Photos Forum Archives

VFP IMAGING



  • Convert your buttons to BMPs keeping transparency with GdiPlusX - REVISITED

    This is just an update for an old post with the same title. Erik Gomez and Russel Campbell had some problems on the conversions of some specific PNG images, so I recoded this function, this time using a safer code.

    NEW UPDATE:

    Thanks to Bernard Bout and Craig Boyd, I've updated the code below. In fact it contained a small bug, that was not adjusting the White colors. Now it seems to be working nice. Thanks !

     

     

    This runs a little bit slower than the other aproach, but in my tests, the success was 100%.

     

    The function below converts any button image to a BMP to be used in VFP forms.

    There are lots of cool and free icons available on the web, but the vast majority are in .ICO, GIF or PNG image formats, that are not very familiar and reliable to be used in VFP. For us, the best image format, for a lot of reasons, is the BMP format.

    Some transformations are needed to make this BMP to show exactly how we desire, specially when converting source images in a PNG, GIF or ICO formats.

    VFP shows the pure white - RGB(255,255,255) as transparent in our buttons and image objects. The code below first converts the original whites to RGB(254,254,254) that is visually the same, but does not become transparent, and eliminates the need to create a mask image (.MSK) and next, converts the background color of the original bitmap to pure white, that will show transparent in VFP forms.

    For more details, please check these prior posts:

    BMPs with Transparent Backgrounds

    How to put one image over another in a form

     

    IMPORTANT
    Requires VFP9 and GdiPlusX to run. 
    Please make sure that you have the latest version, because this sample may be using some functions that were added or fixed recently.
    http://www.codeplex.com/VFPX/Wiki/View.aspx?title=GDIPlusX&referringTitle=Home

     

    Save the program below as BUTTON2BMP.PRG, and call it this way:

    Button2Bmp(GETPICT(), "c:\NewIcon.bmp")

    When you compile this program in your executable, please don't forget to remove the LOCFILE() command, and just use a DO System.App instead

     

    LPARAMETERS tcSourceFile, tcDestFile

    * tcSourcefile = GETPICT()
    * tcDestFile = FORCEEXT(tcSourceFile, "Bmp")
    
    DO LOCFILE("System.App")
    
    LOCAL loBmp AS xfcBitmap
    LOCAL loGfx AS xfcGraphics
    LOCAL loBorderClr AS xfcColor
    LOCAL loRect AS xfcRectangle
    LOCAL loAttr AS xfcImageAttributes
    LOCAL loColorMap AS xfcColorMap
    LOCAL loDestBmp as xfcBitmap
     
    WITH _SCREEN.SYSTEM.Drawing
    	loColorMap = .Imaging.ColorMap.New()
    	loAttr = .Imaging.ImageAttributes.New()
    	loBmp = .Bitmap.FromFile(tcSourceFile)
    	loGfx = .Graphics.FromImage(loBmp)
    
    	loDestBmp = .Bitmap.New(loBmp.Width, loBmp.Height, .Imaging.PixelFormat.Format24bppRGB)
    	loDestGfx = .Graphics.FromImage(loDestBmp)
    
    	* Clear the new bitmap
    	loDestGfx.Clear(.Color.White)
    
    	* By Craig Boyd - For enhancing the smoothless and quality
    	loDestGfx.SmoothingMode     = .Drawing2D.SmoothingMode.HighQuality 
    	loDestGfx.InterpolationMode = .Drawing2D.InterpolationMode.HighQualityBicubic
    	loDestGfx.PixelOffsetMode   = .Drawing2D.PixelOffsetMode.HighQuality
    
    	loRect = loBmp.GetBounds()
    
    	* Get the top left pixel color, presuming this color is the BackGround color to become transparent
    	* For our BMP case, this will become PURE WHITE - RGB(255,255,255)
    	* that becomes transparent when used in VFP objects
    	loBorderClr = loBmp.GetPixel(0,0)
    
    	* Convert original Whites RGB(255,255,255) to OFF WHITE - RGB(254,254,254)
    	* this way, the whites will remain without the need of a mask
    	loColorMap.OldColor = .Color.White
    	loColorMap.NewColor = .Color.FromARGB(255,254,254,254)
    
    	loAttr.SetRemapTable(loColorMap)
    	loDestGfx.DrawImage(loBmp, loRect, loRect, .GraphicsUnit.Pixel, loAttr)
    
    	* Next step, convert the borders to pure White, RGB(255,255,255) that will become transparent in buttons
    	loColorMap.OldColor = loBorderClr
    	loColorMap.NewColor = .Color.White
    	loAttr.SetRemapTable(loColorMap)
    
    	loDestGfx.DrawImage(loDestBmp, loRect, loRect, .GraphicsUnit.Pixel, loAttr)
    
    	loDestBmp.Save(tcDestFile, .Imaging.ImageFormat.Bmp)
    ENDWITH
    

     

     

  • FoxCharts 0.40 BETA Released

    New features:
    - Vertical lines and bars in the scale background
    - Alpha allowed in all of the chart shapes and in scale background
    - Triangular and cylinder bar charts
    - Angles compensation for pie and doughnut charts, allowing charts with good precision when width is bigger than the height (by Bo Durban).
    - New sample, see: FoxCharts_New, that allows you to interactively change almost every property of the charts, creating lots of different and interesting charts.
    - Included an EXE sample project, for testing purposes
    - BackGround line of chart can be set in width, and also use some predefined dotted lines
    - Hiding slices from pies or doughnuts allowed
    - MemberData scripts for picking colors - in the properties window, double clicking any property that receives a color, will fire the colorpicker window
    - Colors may be passed using the RGB value, or using a VFP expression, like: "=RGB(0,0,255)" or even just like the way VFP uses for its native color properties: "0,0,255".

     

    Lots of fixes were applied in this version
    - Fixed cylinder and bars positions.
    - Fixed font assignment
    - Fixed class initialization that caused erros
    - Now the class does not show the "X" image in the class initialization
    - Fixed plain gradient Pie chart bug, that sometimes did not show the chart
    - Fixed print command
    - FoxCharts resizes faster
    - .... and many minor other fixes



    SPECIAL THANKS:
    To the FoxBrazilian friends: Peter Wagner, Grego, Emerson Reed, Minari, Moshe, Arcadio, Edgar, Paulo Henrique, Ninja Takehana, Walfrans, Joni and others for their extensive testing, and for providing important suggestions.
    And also:
    Bo Durban (the best) and Carlos Alloatti (always there, with great insights)
    These guys have been providing important help and support. THANKS VERY MUCH !


    Any feedback will be very much appreciated.
    If you would like to contribute, find any bug or would like to have some specific features, feel free to post in the VFPX Discussions forum or send directly a message to vfpimaging@hotmail.com

     

    Get the latest release directly from the VFPX  / FoxCharts page at Codeplex:

    http://www.codeplex.com/VFPX/Release/ProjectReleases.aspx?ReleaseId=14851

     

    Below are some pictures showing what FoxCharts can do so far:

    Enjoy !

     







     






     





























     
     

















     
     
     
  • Full Justified texts in reports with GdiPlusX - REVISITED

    As I've shown in a previous post from last year, this is totally possible for us in VFP, using the GdiPlusX library together with ReportListeners, remember?

     

    BUT I've been receiving some emails about the Full-Justified ReportListener I published last year.

    It did not deal with the possibility of multipage reports. In fact, when a string that had to be printed in FullJustified mode had to be divided in more than one page, in the next page the whole string was redrawn.

    To solve this, I needed to make some adjustments in the report listener source, more specifically in the "Render" event, in order to deal with the parameters "nObjectContinuationType" and "cContentsToBeRendered". I had totally missed them. In the first version, I was only using the "Text" property that I retrieved in the "EvaluateContents" method. The first tells us if the text could be totally drawn, or partially. The 2nd, brings the text that is to be drawn, not the whole text.

    It's amazing how we can control our output with all these new enhancements from the VFP9 Reporting System. In fact, we can control almost everything !

    It's a pity I couldn't explore this tool as much as I would like, the possibilities seem to be infinite.

     

    In HELP I found all the info I needed to fix it:

    • nObjectContinuationType
      * Indicates the current continuation state for the rendered element. When layout elements span pages, they are rendered in multiple sections (once for each page).
      * Value  Continuation Type 
      *   0    Complete (no continuation).
      *   1    Start of layout element occurrence, will not finish on the current page.
      *   2    Mid-element, neither started nor finished on the current page.
      *   3    End of element, completed on the current page.

     

    • cContentsToBeRendered
      * Indicates the text to be rendered for Expression (Field) and Label layout elements.
      * If your derived class sends the text value through some additional processing, such as storage in a table, you can use the STRCONV() function, and its optional regional script parameter, to convert the string to DBCS first. For more information, see STRCONV( ) Function.

     

    Some important tweaks and fixes were needed in the GdiPlusX library too, more specifically in the xfcGraphics.DrawStringJustified function. I added to it a new parameter, "tlJustifyLast", in order fo force the justifying in the last sentence. This is for the case of reports, when an unfinished sentence needs to be justified as well.

     

    The source code is below, you can adapt it to your needs !

     

     

    The idea is to add a "<FJ>" tag in the USER tab or in the beginning of any string from a textbox in a report, to tell the ReportListener that it will draw the text using the DRAWSTRINGJUSTIFIED method from GdiPlusX. Special thanks to Victor Espinoza, from Miami, FL, for his important feedback, suggestions and fixes.

     

    The "FullJustifyListener" performs the following actions:

    - Initializes GdiPlusX

    - Creates a GDI+ Graphics object that will be used to draw in the report

    - Stores in an array the required information needed to draw the string(Font, Size, Style and Color)

    - Before Rendering the string, checks if the "<FJ>" tag is at the beginning of text or at the "USER" tab in the report designer - if yes, draws the string using the new method.

    Here are the steps for you to bring this to your reports:

     

    1 - Download the updated GdiPlusX library - the System.App file

    VERY IMPORTANT - READ THIS !

    This report listener needs the updated version of the GdiPlusX main file of the library, "System.App". As it will take some time till a new version will be released, I've uploaded this file separately, so that people can try this feature from now.

    Go to this link: http://www.codeplex.com/VFPX/Release/ProjectReleases.aspx?ReleaseId=8606

    And download the file "GdiPlusX Updated System.App for FullJustified purposes"

    If you prefer, this file is found in the downloadable source code from this article.

     

     

    2 - Save the ReportListener:

    Please Copy and Paste the code below, and save it as FJLISTENER.PRG in the samples folder of GdiPlusX 

     

    * Program : FJLISTENER.PRG
    * Version : 2.0
    * Purpose : Provides a Report Listener that allows rendering text in
    * Full Justify alignment.
    * Authors : Cesar Ch
    http://weblogs.foxite.com/vfpimaging
    * Class based on article "Listening to a report" by Doug Hennig
    * New tweaked version allows drawing strings that need to be divided in more than one page

    * Special thanks to Victor Espinoza 
    *
    http://msdn2.microsoft.com/en-us/library/ms947682.aspx

    DEFINE CLASS FullJustifyListener AS FXListener
    oGDIGraphics =
    NULL
    nSaveGraphicsHandle = 0
    nTimes = 1
    DIMENSION aRecords[1]
     
    * Before we run the report, go through the FRX and store information about any
    * field with our expected directive in its USER memo into the aRecords array.
    FUNCTION BEFOREREPORT
       DODEFAULT
    ()
       * Check if we already have the "System" object in "_Screen"
       IF NOT PEMSTATUS(_Screen,"System",5)
          DO LOCFILE("System.App")
       ENDIF
       WITH This
          .oGDIGraphics = _SCREEN.SYSTEM.Drawing.Graphics.New()
          .SetFRXDataSession()
          DIMENSION .aRecords[reccount(), 13]
          SCAN FOR "<FJ>" $ UPPER(User)
             .aRecords[recno(), 13] = "FJ"
          ENDSCAN
         .ResetDataSession()
       ENDWITH
    ENDFUNC

    FUNCTION BEFOREBAND(nBandObjCode, nFRXRecNo)
       This.SharedGDIPlusGraphics = This.GDIPLUSGRAPHICS
       This
    .oGDIGraphics.Handle = This.SharedGDIPlusGraphics
       DODEFAULT(nBandObjCode, nFRXRecNo)
    ENDFUNC
     
    PROCEDURE RENDER
    (tnFRXRecNo,;
       tnLeft,tnTop,tnWidth,tnHeight,;
       nObjectContinuationType, ;
       cContentsToBeRendered, GDIPlusImage)

       LOCAL lcText, llFlag
       llFlag = .F.
       lcText =
    This.aRecords(tnFRXRecNo,1)

       IF (VARTYPE(lcText) = "C" AND LEFT(lcText,4) = "<FJ>") OR ;
          (
    VARTYPE(This.aRecords(tnFRXRecNo,13)) = "C" AND This.aRecords(tnFRXRecNo,13) == "FJ")

          IF nObjectContinuationType > 0

          * nObjectContinuationType
          * -----------------------
          * Indicates the current continuation state for the rendered element. When layout elements span pages, they are rendered in multiple sections (once for each page).
          * Value Continuation Type
          * 0 Complete (no continuation).
          * 1 Start of layout element occurrence, will not finish on the current page.
          * 2 Mid-element, neither started nor finished on the current page.
          * 3 End of element, completed on the current page.

          * cContentsToBeRendered
          * ---------------------
          * Indicates the text to be rendered for Expression (Field) and Label layout elements.
          * If your derived class sends the text value through some additional processing, such as storage in a table, you can use the STRCONV() function, and its optional regional script parameter, to convert the string to DBCS first. For more information, see STRCONV( ) Function.

             lcText = STRCONV(cContentsToBeRendered,6)

                IF INLIST(nObjectContinuationType, 1, 2)
                   llFlag = .T.
                ENDIF
             ENDIF
     
             IF UPPER
    (LEFT(lcText,4)) = "<FJ>"
                lcText =
    SUBSTR(lcText,5) && Remove the <FJ> tag from string
             ENDIF

             WITH _SCREEN.SYSTEM.Drawing

             This.oGDIGraphics.Handle = This.GDIPlusGraphics
             *!* Create a GDI+ Rectangle which specifies where on the
             *!* surface we're drawing the text.
             LOCAL loRectF as xfcRectangleF
             loRectF = .RectangleF.New(tnLeft, tnTop, tnWidth, tnHeight)

             LOCAL loFont as xfcFont
             loFont = .
    Font.New(This.aRecords(tnFRXRecNo,2) ;
                ,
    This.aRecords(tnFRXRecNo,4), This.aRecords(tnFRXRecNo,3) ;
                , .GraphicsUnit.
    Point)

             * Retrieve colors for the background
             LOCAL lnRed, lnGreen, lnBlue, lnAlpha
             lnRed =
    This.aRecords[tnFRXRecno,5]
             lnGreen =
    This.aRecords[tnFRXRecno,6]
             lnBlue =
    This.aRecords[tnFRXRecno,7]
             lnAlpha =
    This.aRecords[tnFRXRecno,8]
             LOCAL loBackBrush as xfcSolidBrush
             loBackBrush = .SolidBrush.New(;
                .
    Color.FromArgb(lnAlpha,lnRed, lnGreen, lnBlue))

             This.oGdiGraphics.FillRectangle(loBackBrush, tnLeft, tnTop, tnWidth, tnHeight)

             * Retieve colors for the Text
             lnRed = This.aRecords[tnFRXRecno,9]
             lnGreen =
    This.aRecords[tnFRXRecno,10]
             lnBlue =
    This.aRecords[tnFRXRecno,11]
             lnAlpha =
    This.aRecords[tnFRXRecno,12]
             LOCAL loTextBrush as xfcSolidBrush
             loTextBrush = .SolidBrush.New(;
                .
    Color.FromArgb(lnAlpha,lnRed, lnGreen, lnBlue))

             This.oGdiGraphics.DrawStringJustified(lcText, loFont, loTextBrush, loRectF, llFlag)

             ENDWITH
          ELSE
          *!* If we're not drawing a full justified string,
          *!* let Fox draw the text as usual.
             DODEFAULT(tnFRXRecNo, tnLeft, tnTop, tnWidth, tnHeight, ;
                nObjectContinuationType, cContentsToBeRendered, GDIPlusImage)
          ENDIF

          *!* Since we already drew the text, we don't want the default
          *!* behavior to occur.
       NODEFAULT
    ENDPROC

    FUNCTION EvaluateContents
    (tnFRXRecno, toObjProperties)
       * Get the FRX data
       This.aRecords[tnFRXRecno,1] = toObjProperties.Text
       This
    .aRecords[tnFRXRecno,2] = toObjProperties.FontName
       This
    .aRecords[tnFRXRecno,3] = toObjProperties.FontStyle
       This.aRecords[tnFRXRecno,4] = toObjProperties.FontSize
       This
    .aRecords[tnFRXRecno,5] = toObjProperties.FillRed
       This.aRecords[tnFRXRecno,6] = toObjProperties.FillGreen
       This.aRecords[tnFRXRecno,7] = toObjProperties.FillBlue
       This.aRecords[tnFRXRecno,8] = toObjProperties.FillAlpha
       This.aRecords[tnFRXRecno,9] = toObjProperties.PenRed
       This.aRecords[tnFRXRecno,10] = toObjProperties.PenGreen
       This.aRecords[tnFRXRecno,11] = toObjProperties.PenBlue
       This.aRecords[tnFRXRecno,12] = toObjProperties.PenAlpha
    ENDFUNC

    ENDDEFINE

     

    3 - Update the report:

    Below is a short tutorial for the beginners:

    - Open any of your reports, that contains a field of more than one line that will receive the effect. Double-Click on that field, select the GENERAL tab, and add BEFORE your expression, this simple string: [  "<FJ>" +  ], like in the picture below.

     

     

    Another better option is to add the tag to the USER tab, that is available only in VFP9 Report Designer. Just like before, double-click in the desired field, select the "OTHER" tab, then click on the "EDIT USER DATA" button, and add the <FJ> tag to the window, just like the picture below. This is the most recommended approach, because the original data will not be affected, and if one day you decide to stop using the report listener, your report data will not be affected.

     

     

    4 - Run the report

     

    * Tell VFP that we'll be using the new report features
    SET REPORTBEHAVIOR 90
    LOCAL loReportListener
    loReportListener = CREATEOBJECT("FullJustifyListener")
    loReportListener.ListenerType = 1
    REPORT FORM YourReport OBJECT loReportListener

     

     

    Below a last screenshot, showing the of the continued field issue solved:

     

    Enjoy !!!

     

    CLICK HERE TO DOWNLOAD THE SOURCE CODE AND SAMPLE FROM THIS ARTICLE

  • GdiPlusX undocumented functions

     

    The GdiPlusX library is intended to be compatible with the .NET Framework’s System.Drawing namespace. That means that you can use the MSDN online documentation for the “System.Drawing” in order to obtain accurate information about the GdiPlusX classes. objects and functions. More than that, you can also convert the huge amount of samples published in various forums, blogs, articles and e-magazines to be used in VFP. It really does not matter if the sample was published in VB, C or ASP. The conversion to VFP is really intuitive.

     

    When GdiPlusX was coded, we used a .NET conversion tool, called Reflector, which showed us all the source codes involved in each function, bringing us the possibility to code calling the same API functions, working with the same parameters.

     

     

    BUT, during the coding phase, we had some great discussions about things that could be enhanced in order to ease user’s lives.

     

     

    We had a premise not changing the behavior of any function, even if we disagreed with some things there, in order to keep the full compatibility.

     

    On the other hand, we have decided that we could add new functions

     

     

    Below is a short list of some functions that have been added to GdiPlusX, that are not present in the .NET original classes. Most of them have already been used in some samples posted in this blog, but till now, no documentation was published. So, here are some of those new functions, that came to my mind. Probably Bo or Craig will remember to add something here. I hope to be updating this post with some other improvements that only VFP users have available.

     

    Of course, we know that GdiPlusX still needs some documentation, and we’re working on it. But for now, we hope that the list below will bring you some help.

     

     

     

     

     

    xfcGraphics class

     

    DrawStringJustified

     

                Draws the specified text string at the specified location with the specified Brush and Font objects in a Full Justified format.

     

                Parameters: tcString, ;

                            toFont as xfcFont, ;

                            toBrush as xfcBrush, ;

                            toRectangle as xfcRectangle

               

         where:

                            tcString: text to be drawn

                            toFont: Gdi+X font object

                            toBrush: Gdi+X brush object

                            toRectangle: Gdi+X Rectangle object with position and dimensions to draw

     

                Returns: Nothing

                See also: Full-Justified Text with GdiPlus-X

                               Full Justified Texts in your reports with GdiPlus X

     

                GdiPlusX Sample: FullJustified.scx  /  FullJustify.Prg

     

                Code sample:

     

     

    LOCAL lcText
    TEXT TO
    lcText
    NOSHOW
    This library
    was intended to provide Visual FoxPro 9.0 developers with an object based library to wrap the 600+ functions included with the GDI+ API. The intent is to mimic the System.Drawing namespace in the .NET Framework. All classes in the library are based on the classes included in the System.Drawing namespace and other classes that are dependencies for classes in the System.Drawing namespace. Some additional additional functionality has been added to take advantage of features built in to VFP 9.0

    ENDTEXT

    DO LOCFILE("System.app")
    WITH _Screen.System.Drawing
       LOCAL
    loGfx as xfcGraphics
       loGfx = .Graphics.FromHwnd(
    _Screen.HWnd
    )
       loGfx.DrawStringJustified(lcText, .
    Font
    .New("Tahoma",12);
          , .Brushes.Red, .Rectangle.New(0,0,250,400))
    ENDWITH

     

     

     

     

     

    xfcBitmap class

     

     

    ToClipboard

     

                Sends the current bitmap to the clipboard

     

                Parameters: None

                Returns: Nothing

                See also: Send Images to the Clipboard with GdiPlus-X Revisited

     

                Code sample:

     

    DO LOCFILE("System.app")

     
    WITH _Screen
    .System.Drawing

       LOCAL
    loBmp as xfcBitmap
       loBmp = .
    Bitmap.FromFile(GETPICT
    ())
       loBmp.ToClipboard()
    ENDWITH

     

     

     

     

     

    FromClipboard

     

                Creates a GDI+ bitmap object from the clipboard data

     

                Parameters: None

                Returns: Gdi+ bitmap object

     

                Code sample:

     

    DO LOCFILE("System.app")

    WITH _Screen.System.Drawing

       LOCAL
    loBmp as xfcBitmap
      
    loBmp = .
    Bitmap
    .FromClipboard()
       loBmp.
    Save
    ("c:\FromClip.png", .Imaging.ImageFormat.Png)

    ENDWITH

     

     

     

     

    FromVarbinary

     

                Creates an Image object from the specified VarBinary string. Useful to start manipulating an image directly without having to convert the binaries from the image to a file.

     

                Parameters: tcBinary

     

                Returns: GdiPlusX Bitmap object

     

                Code sample:

     


    DO LOCFILE("System.app")

    WITH _Screen.System.Drawing

       LOCAL
    lcBinary
       lcBinary =
    FILETOSTR(GETPICT
    ())

       LOCAL
    loBmp as xfcBitmap
       loBmp = .
    Bitmap
    .FromVarBinary(lcBinary)
       loBmp.
    Save
    ("c:\FromVarBinary.png", .Imaging.ImageFormat.Png)

    ENDWITH

     

     

     

    FromScreen

     

                Captures the specified window or object image to a new GDI+ bitmap object

     

                Parameters:

    tHWnd,                 tiX, tiY, tiWidth, tiHeight, tlEnsureVisible

                                    toForm [, tiX, tiY, tiWidth, tiHeight [, tlEnsureVisible]]

                                   toControl [, tlEnsureVisible]

     

                Returns: Gdi+ bitmap object

     

                See also: Capture Screens with GdiPlus-X

     

                Code sample:

     

     
    DO LOCFILE
    ("System.app")

    WITH _Screen
    .System.Drawing

       LOCAL
    loBmp as xfcBitmap
       loBmp = .
    Bitmap.FromScreen()
       loBmp.
    Save("c:\FromScreen.png", .Imaging.ImageFormat.Png)

    ENDWITH

     

     

     

     

    GetMonochrome

     

                Returns a monochrome GDI+ bitmap (1bpp) of this Image object.

                The image must be saved in the BMP Image Format in order to keep the 1bpp format. Because the resulting bitmap is in an indexed pixel format, GDI+ cannot create a xfcGraphics object in order to draw on it. This function is recommended to be used immediately before saving to a file, in order to obtain the minimum file size. For some specific TIFF compression types, a monochrome image of 1bpp is required too, see more details in these articles:

     

                Parameters: None

     

                Returns: Gdi+ bitmap object

     

                See also: Convert Images to Monochrome with GdiPlus X

                            Using TIFFs with the new GDI+ classes - UPDATE

                            TIFFS and the latest release of GdiPlusX

     

                Code sample:

     


    DO LOCFILE("System.app")

    WITH _Screen
    .System.Drawing

       LOCAL
    loBmp as xfcBitmap
       loBmp = .
    Bitmap.FromFile(GETPICT
    ())

       LOCAL
    loMonoch as xfcBitmap
       loMonoch = loBmp.GetMonochrome()

       loMonoch.
    Save
    ("c:\Monoch.bmp", .Imaging.ImageFormat.Bmp)

    ENDWITH

     

     

     

     

    GetPictureVal

     

                Returns a String containing the PictureVal of this Image object, according to the ImageFormat passed. You can retrieve the binaries of the image with NO disk access, in any Image format supported by GDI+

     

                Parameters: ImageFormat Object

                                       EncoderParameter Object (optional)

                Returns: String

     

                See also: Manipulate images with no disk access with GdiPlusX

     

                Code sample:

     


    DO LOCFILE("System.App")

    LOCAL loBmp as xfcBitmap
    * Obtaining the PictureVal directly
    WITH _Screen
    .System
    .Drawing 
       loBmp = .Bitmap.FromFile(GETPICT())
       Thisform.Image1.PictureVal = loBmp.GetPictureVal (.Imaging.ImageFormat.Bmp)

    ENDWITH

     

     

     

     

    GetPictureValFromHBitmap

     

                Returns a String containing the PictureVal of this Image object using the HBitmap GDI technique. The binaries retrieved are always in BMP format, what makes it a big string in most times. But, in most cases, this technique runs about 40% faster than using GetPictureVal() function shown above. The ImageCanvas objects uses this function to obtain the binaries from the images drawn.

     

                Parameters: None

     

                Returns: String

     

                See also: Manipulate images with no disk access with GdiPlusX

     

     


    DO LOCFILE("System.App")

    LOCAL loBmp as xfcBitmap

    * Obtaining the PictureVal directly
    WITH _Screen
    .System
    .Drawing
       loBmp = .
    Bitmap.FromFile(GETPICT
    ())
       Thisform.Image1.PictureVal = loBmp.GetPictureValFromHBitmap()

    ENDWITH

     

     

     

     

    ApplyColorMatrix

     

                Applies the received color matrix to the current bitmap object

                This is very useful, and provides an easy and quick way to apply image transformations in just one step, without having to use the ImageAttributes class.

     

                Parameters:

                            toColorMatrix

     

                Returns: NULL

     

                See also: Special effects on images with GdiPlusX- Part1

                               Special effects on images with GdiPlusX – Part2

                               Draw Logos in your images with GdiPlusX - Part 2

                           

                Code sample:

     


    DO LOCFILE("System.app")

    WITH _Screen.System.Drawing 
       LOCAL loBmp as xfcBitmap
       loBmp = .
    Bitmap.FromFile(GETPICT())
     
       LOCAL loClrMatrix as xfcColorMAtrix
       loClrMatrix = .Imaging.ColorMatrix.New(;
          0.33, 0.33, 0.33, 0, 0, ;
          0.33, 0.33, 0.33, 0, 0, ;
          0.33, 0.33, 0.33, 0, 0, ;
          0, 0, 0, 1, 0, ;
          0, 0, 0, 0, 1) 
       loBmp.ApplyColorMatrix(loClrMatrix)
       loBmp.
    Save("c:\ClrMatrix.Png", .Imaging.ImageFormat.Png)

    ENDWITH

     

     

     

     

     

    GetMask

     

               Returns a Bitmap object with the mask from the current bitmap

               In fact this function returns a bitmap with all the transparent parts of the image. Useful when you need to convert a PNG image that contains transparencies to be used in the BMP image format.

     

                Parameters: None

     

                Returns: Gdi+ bitmap object

     

                See also: Convert your buttons to BMPs keeping transparency with GdiPlusX

     

     

     

     

     

     

     

    ToPrinter

     

                Sends the image object to the Printer

               

    Parameters: tnStretch, tcPrinterName, tnOrientation, tnAlignment

                           

                            tnStretch

                            *   Specifies how an image is sized to fit inside a control.

                            *   0 - Clip. The image is clipped to fit the page. (Default)

                            *   1 - Isometric. The image resizes to fit the page while maintaining its original proportions.

                            *   2 - Stretch. The image resizes to fit the page, but does not maintain its original proportions.

                           

                            tcPrinterName

                            *   Specifies the name of the printer, the same of GETPRINTER()

                           

                            tnOrientation:

                            *   0 - Portrait

                            *   1 - Landscape

                           

                            tnAlignment

                            *   Specifies a numerical value representing the alignment of the image in the page.

                            *   0 - Vertically Centered Left.

                            *   1 - Vertically Centered Right.

                            *   2 - Centered. Centers image vertically and horizontally.

                            *   4 - Top Left. Aligns image in top left corner of the page.

                            *   5 - Top Right. Aligns image in top right corner of the page.

                            *   6 - Top Center. Aligns image at the top and horizontally centered on the page.

                            *   7 - Bottom Left. Aligns image in the bottom left corner of the page.

                            *   8 - Bottom Right. Aligns image in bottom right corner of the page.

                            *   9 - Bottom Center. Aligns image at the bottom and vertically centered on the page.

     

                Returns: Nothing

     

                Code sample:

     

     

    DO LOCFILE("System.app")

     
    WITH _Screen
    .System.Drawing

       LOCAL
    loBmp as xfcBitmap
       loBmp = .
    Bitmap.FromFile(GETPICT
    ())
       loBmp.ToPrinter()
    ENDWITH

     

     

     
     

     

     

    xfcColorMatrix class

     

    MatrixMultiply

     

                Returns a new Color Matrix object resulting of the multiplication of two color matrices. This is very useful when more than one color matrix is needed to be applied to an image. Multiplying the color matrices before they are applied to the image will bring a HUGE gain of performance.

     

                Parameters: toColorMatrixOne, ;

                            toColorMatrixTwo

                           

                Returns: a new color matrix containing the resultant matrix

     

                Code sample:

     

     

    DO LOCFILE("System.app")


    WITH _Screen
    .System.Drawing


       LOCAL
    loBmp as xfcBitmap
       loBmp = .
    Bitmap.FromFile(GETPICT())

       LOCAL loClrMatrix1 as xfcColorMatrix && GreyScale matrix 
       loClrMatrix1 = .Imaging.ColorMatrix.New(;
          0.33, 0.33, 0.33, 0, 0, ;
          0.33, 0.33, 0.33, 0, 0, ;
          0.33, 0.33, 0.33, 0, 0, ;
          0, 0, 0, 1, 0, ;
          0, 0, 0, 0, 1)

       LOCAL loClrMatrix2 as xfcColorMatrix && Half Brightness Matrix
       loClrMatrix2 = .Imaging.ColorMatrix.New(;
          0.5, 0, 0, 0, 0, ;
          0, 0.5, 0, 0, 0, ;
          0, 0, 0.5, 0, 0, ;
          0, 0, 0, 1, 0, ;
          0, 0, 0, 0, 1)

       LOCAL loNewClrMatrix as xfcColorMatrix
       loNewClrMatrix = loClrMatrix1.Multiply(loClrMatrix1, loClrMatrix2)

       loBmp.ApplyColorMatrix(loNewClrMatrix)
       loBmp.
    Save("c:\MultClrMatrix.Png", .Imaging.ImageFormat.Png)

    ENDWITH

     

     

     

     

     

    xfcSize class

     

    ToRectangle

                Returns a xfcRectangle object from the current xfcSizeF object

     

     

     

     

     

    xfcSizef class

     

    ToRectanglef

                Returns a xfcRectangleF object from the current xfcSizeF object

  • FoxCharts 0.20 Alpha

    Here's a new release of FoxCharts

    https://www.codeplex.com/Release/ProjectReleases.aspx?ProjectName=VFPX&ReleaseId=13477

     

    Prerequisites:
    Visual FoxPro 9 and the GdiPlusX library from VFPX 









     

    As you can see, 2 new charts are now available:

    - Stacked Area

    - Cylinder

     

    • The StackedArea chart can be defined using the "ChartType" property, that must be set to the numeric 10
    • The Cylinder chart is derived from the original Bars chart. To have it, select ChartType for the bar option, and then set the BarType property to numeric 1 (0 = Bar Default; 1 = Cylinder)

     

    Apart from this, many other important modifications were applied:

    The main difference is that now FoxCharts' base class is a Container, that contains the GdiPlusX ImageCanvas, and the legend objects, responsible for drawing all the text needed.

    Now we can customize any of those labels in lots of ways. Every piece of text, legend in the chart now has the following properties:


    Alignment - 0 Left; 1 Right; 2 Center
    BackColor
    BackColorAlpha - this is cool, (0-255) determines the transparency of the background of the label
    Caption
    FontBold
    FontItalic
    FontName
    FontSize
    FontStrikethru
    FontUnderline
    ForeColor
    ForeColorAlpha - determines the transparency of the label


    The legends are represented by the following objects:

    Title
    SubTitle
    XAxis
    XAxisLegend2
    YAxis
    ShapeLegend
    ScaleLegend
    SideLegend

    This way, every piece of text in the chart can be fully customized, not only the font, but the backcolor and the alpha (transparency). Now you can also change the alignment of the text, for example, to set the title to Right Alignment, all you have to do is to:

    Thisform.FoxCharts1.Title.Alignment = 1 && Right

     

    I still need to remind you that this is still a preview version, destined for people that are interested in helping testing this tool.



    Please continue sending your suggestions and feedback!
    It is really very appreciated

    https://www.codeplex.com/Release/ProjectReleases.aspx?ProjectName=VFPX&ReleaseId=13477



    Contains the ALPHA version of the FoxCharts project.

    Unzip the file and run the form ChartsSample to see how it works.

    This version also distributes the two main files from GdiPlusX - System.app and GdiPlusX.vcx.
    If you are already a GdiPlusX user, you can use your own GdiPlusX version.
    Just make sure to be using the latest GdiPlusX version.

    GdiPlusX is also a VFPX project. For more information, please visit the GdiPlusX page at VFPX.


    More information and pictures about this project can be obtained at the VFPIMAGING weblog:

    http://weblogs.foxite.com/vfpimaging/archive/2008/04/04/5919.aspx

    http://weblogs.foxite.com/vfpimaging/archive/2008/04/24/6040.aspx


    This new release contains lots of enhancements:

    Chart Types
    - Bar charts
    - Multiple bars
    - Stacked bars

    - Pie
    - Doughnut

    - Lines
    - Area
    - Stacked Area
    - Points and Shapes


    Color variations:
    - Basic colors
    - Custom colors
    - Gradient colors
    - Random colors
    - Monochrome
    - Gradient or solid colors


    Legends in many places: Axys, shapes, side legends

    Scales

    Customize:
    - Titles
    - Subtitles
    - Backgrounds (solid or gradient)
    - Fonts
    - Colors

  • Crop Images with GdiPlusX

    Cropping an image is super simple using GdiPlusX

    Prerequisites
    Visual FoxPro 9 and the GdiPlusX library from VFPX 

    Please make sure that you have the latest version, because this sample may be using some functions that were added or fixed recently.
    http://www.codeplex.com/VFPX/Wiki/View.aspx?title=GDIPlusX&referringTitle=Home

     

    The cropping is done by the fuction "Clone()" from the Bitmap class. All we need is to pass a Rectangle object containing the X, Y, Width and Height of the desired image to be cropped.

    Original Image 

    Top Left  

                                    Center 

                                                       Bottom Right 

    Run the code below, selecting any image, and you will see the image cropped in three ways: the top-left part of the image, the bottom-right part, and the center.


    LOCAL lcSource, lnWidth, lnHeight
    lcSource =
    GETPICT
    ()
    IF EMPTY
    (lcSource)
       RETURN
    ENDIF

    DO LOCFILE
    ("System.App")

    WITH _SCREEN.System.Drawing
     
    * Load Image to GdiplusX
    LOCAL loBmp AS
    xfcBitmap
    loBmp = .
    Bitmap
    .FromFile(lcSource)
    lnWidth = loBmp.
    Width
    lnHeight = loBmp.Height

    * Crop Image
    LOCAL loCropped AS xfcBitmap

    * Crop Top-Left
    LOCAL loRect as xfcRectangle
    loRect = .Rectangle.New(0, 0, lnWidth / 2, lnHeight /2)
    loCropped = loBmp.Clone(loRect)
    loCropped.
    Save("c:\Crop-TopLeft.png", .Imaging.ImageFormat.Png)
    RUN /N explorer.EXE c:\Crop-TopLeft.png
     
    * Crop Bottom-Right
    * Now, the Rectangle region will be created inside the Clone function
    loCropped = loBmp.Clone(.Rectangle.New(lnWidth / 2, lnHeight /2, lnWidth /2, lnHeight /2))
    loCropped.
    Save("c:\Crop-BottomRight.png", .Imaging.ImageFormat.Png)
    RUN /N explorer.EXE c:\Crop-bottomright.png
     
    * Crop Center
    loCropped = loBmp.Clone(.Rectangle.New(lnWidth / 4, lnHeight /4, lnWidth /2, lnHeight /2))
    loCropped.
    Save("c:\Crop-Center.png", .Imaging.ImageFormat.Png)
    RUN /N explorer.EXE c:\Crop-Center.png
     
    ENDWITH
    RETURN
  • FIX: The toolbar on an SDI form is disabled in Visual FoxPro 9.0 Service Pack 2

    One fix for VFP9 SP2 has just been released:

    FIX: The toolbar on an SDI form is disabled in Visual FoxPro 9.0 Service Pack 2

    http://support.microsoft.com/kb/948528/en-us

     

    Good news is when they say: "This hotfix may receive additional testing. Therefore, if you are not severely affected by this problem, we recommend that you wait for the next Visual FoxPro 9.0 service pack that contains this hotfix."

  • FoxCharts 0.14 ALPHA released !

    I'm happy to announce that FoxCharts has recently been accepted as a VFPX project.

    Today I've just uploaded to VFPX at CodePlex a new version of FoxCharts. This is version 0.14 - still ALPHA - NOT FOR PRODUCTION !

    Prerequisites:
    Visual FoxPro 9 and the GdiPlusX library from VFPX 

    First of all I have to thank you all for your kind comments and feedback you provided in my last post. I had never expected to receive so many comments, in this blog, at the other VFP forums and by email. I really apreciated that. Be sure that your feedback resulted in a superpowered motivation to improve it.

    It is also important to tell everybody of the importance that both Bo Durban and Craig Boyd have in this project. They are the menthors and fathers of GdiPlusX. Without GdiPlusX this project would become almost impossible. If I had to use any other of the Gdi+ classes available for VFP, for sure it would have taken much more time - Believe-me, I've tried them all.

    Using GdiPlusX I can be indeed much more productive. Once you understand how it works, things b