Results 1 to 37 of 37

Thread: Image Annotation & Markup Tools (RC6/Cairo Based)

  1. #1

    Thread Starter
    PowerPoster
    Join Date
    Aug 2010
    Location
    Canada
    Posts
    2,709

    Image Annotation & Markup Tools (RC6/Cairo Based)

    Want to give users the ability to annotate images with lines, shapes, highlights, and text? This project provides flexible drawing tools and customization options for a variety of use-cases.

    Screenshot

    Name:  2025-03-16_15-29-16.jpg
Views: 629
Size:  35.4 KB

    The above example shows a base image that has been marked up with a text box, polygon (that also happens to be "selected"), line with arrowhead endpoint, and a highlighted date/time.

    Features

    • Open BMP, PNG, and JPEG images.

    • Draw Lines with optional endpoints (Arrowhead, Ball, Bar).

    • Create rectangles and polygons with customizable fill and stroke.

    • Multiple polygon edge styles (Flat/Straight, Smooth/Bezier Curved, Ratcheted, Zig Zag, and Cloud/Bubbly).

    • Draw multi-line Text Boxes with definable font face, size, colour, and style (Bold, Italic, Underline, and Strikethrough).

    • Adjust stroke thickness, color, and style (Solid, Dashed, Dotted) for supported objects.

    • Improved Dotted stroke drawing (using Round line cap).

    • Set Background Fill Colour and Translucency for fillable shapes (Rectangles, Polygons, and Text Boxes).

    • Highlight rectangular areas for emphasis.

    • Move drawn objects around the image by mouse-click and drag, or using the arrow keys for precise positioning (hold Shift for larger movement).

    • Resize/Reshape drawn objects.

    • Undo/Redo actions.

    • Bring objects forward or backward in the Z-order with SendToFront, SendToBack, SendForward, and SendBackward methods.

    • Right-click to finalize drawing objects (Polygons, Highlighter rectangles, etc.), allowing full mouse-only interaction.

    • Select all objects via Ctrl+A or SelectAllObjects method.

    • Delete selected objects via DeleteSelectedObjects method.

    • Programmatic movement of selected objects via MoveSelectedObjects method.

    • Alternate yellow/blue dashed outline for selected objects, ensuring visibility on light and dark backgrounds.

    • Save Composite image (Base image + Drawn Objects in JPG or PNG format).

    • Export overlay images (annotations on a transparent background) as PNG.

    • Save and restore all drawn object data in JSON format.

    • Ability to set text horizontal and vertical alignment.

    • Custom text input handling via RequestText event (bypassing default InputBox).

    • Double-click text boxes to trigger the TextRequested event for editing.

    • UI refresh handling for tool mode changes via ToolModeChanged event.

    • Option to disable all built-in keyboard shortcuts via EnableKeyboardShortcuts property.

    • Optional global drop shadow rendering via EnableGlobalDropShadow property (thanks for the idea @SearchingDataOnly).

    • Zoom/Fit to Viewport


    SOURCE CODE

    RC6ImageMarkupTools19.zip

    NOTES

    • Requires Olaf Schmidt's RC6 library available at https://www.vbrichclient.com/ - so make sure to have it installed and registered on your dev machine.
    • This is a first-pass and the project has only been lightly tested so far. There are likely to be bugs, so please report any issues you discover and I will try to fix them ASAP.


    Enjoy!
    Last edited by jpbro; Apr 7th, 2025 at 02:23 PM.

  2. #2
    Fanatic Member
    Join Date
    Jun 2016
    Location
    EspaƱa
    Posts
    588

    Re: Image Markup Tools

    Very good work.
    Sometimes it gets stuck when you draw.
    But it works pretty well.

  3. #3

    Thread Starter
    PowerPoster
    Join Date
    Aug 2010
    Location
    Canada
    Posts
    2,709

    Re: Image Markup Tools

    Thanks for trying it out yokesee - I haven't been able to get it to stick myself, so any additional information you can provide it that regard would be helpful/appreciated.

    Some notes on the drawing though, as the way it has been designed to behave might be different than what you are used to from a drawing program.

    • While click and hold/drag is supported, the primary input method is to click and release to drop object points at desired positions as this enables more accurate placement.
    • The highlighter tool behaves a bit differently than the other tools in that the highlighter mode remains active after you draw your first rectangle. This is so you can continue drawing more and more highlight rectangles, and when they are filled, the translucency will be uniform even on overlapping rectangles. You can stop drawing highlights by pressing the Return key.
    • The polygon tool is similar to the highlighter tool in that regard as you can keep adding points as needed, then you will finish the polygon by pressing the Return key.

  4. #4

    Thread Starter
    PowerPoster
    Join Date
    Aug 2010
    Location
    Canada
    Posts
    2,709

    Re: Image Markup Tools

    Latest version in first post update with the following:

    • Fixed bug in Send to Back method
    • Exposed SendToBack/BringToFront in demo UI
    • Demo UI controls now enabled properly when the demo image is present and loaded at startup

  5. #5

    Thread Starter
    PowerPoster
    Join Date
    Aug 2010
    Location
    Canada
    Posts
    2,709

    Re: Image Markup Tools

    Latest version in first post updated with the following:

    • Improved hit-testing when objects have stroked borders (border width now included in test)
    • Fixed a bug that could cause "wild" movement of selected objects on double-click.
    • Fixed a bug that could cause Highlighter rects (after the first) to start at the top-left corner of the canvas instead of at the mouse position on double-click.
    • Selected object stroke now alternates between yellow/blue dashes so it is visible over light and dark backgrounds.
    • Fixed an unhandled "subscript out of range" error that could be raised when a Highlighter Rect's point values were all the same.
    • Other minor improvements/added comments.
    Last edited by jpbro; Mar 18th, 2025 at 04:16 PM.

  6. #6

    Thread Starter
    PowerPoster
    Join Date
    Aug 2010
    Location
    Canada
    Posts
    2,709

    Re: Image Markup Tools

    Latest version in first post updated with the following:

    • Added SendForward and SendBackward methods, and changed BringToFront to SendToFront so that all ZOrder modifier methods are more easily discoverable via Intellisense (Send*)
    • Added SendForward/Backward buttons to the demo UI
    • Improvements to Dotted stroke drawing (using Round line cap)
    • Right-click will now finalize drawing all objects (especially useful for Polygons and Highlighter rectangles). Previously only pressing the Return key would finalize objects, but now you can work "mouse only".
    Last edited by jpbro; Mar 18th, 2025 at 04:16 PM.

  7. #7
    Fanatic Member
    Join Date
    Jun 2016
    Location
    EspaƱa
    Posts
    588

    Re: Image Markup Tools

    It works much better.
    I've noticed that when you draw the rectangle and move it, it gets stuck, especially if you move it quickly.
    But it doesn't in edit mode, it works perfectly.
    Regards

  8. #8

    Thread Starter
    PowerPoster
    Join Date
    Aug 2010
    Location
    Canada
    Posts
    2,709

    Re: Image Markup Tools

    Quote Originally Posted by yokesee View Post
    It works much better.
    I've noticed that when you draw the rectangle and move it, it gets stuck, especially if you move it quickly.
    But it doesn't in edit mode, it works perfectly.
    Regards
    Thanks for the clarifications, and glad to hear things are working better. Unfortunately I have been unable to reproduce the issue with the rectangle getting stuck on move so far, but I will run some more tests and see if I can reproduce/fix that behaviour.

  9. #9

    Thread Starter
    PowerPoster
    Join Date
    Aug 2010
    Location
    Canada
    Posts
    2,709

    Re: Image Markup Tools

    Latest version in first post updated with the following:

    • Added EnableKeyboardShortcuts property that you can set to False to disable all built-in keyboard handling.
    • Added Arrow key movement of selected objects (hold Shift for larger movement) when EnableKeyboardShortcuts = True (default).
    • Added DeleteSelectedObjects method (in case you would like to add a UI to delete selected objects).
    • Added MoveSelectedObjects method in case you want to move selected objects via UI.
    • Added SelectAllObjects method (in case you would like to add a UI to select all objects).
    • Added RequestText event when the Text tool mode is selected (instead of using ugly built-in InputBox, you can use your own input form to request text from the user).
    • Added ToolModeChanged event (in case you want to update UI based on tool mode changes).
    • Added Ctrl+A shortcut to select all objects when EnableKeyboardShortcuts = True (default).
    Last edited by jpbro; Mar 18th, 2025 at 04:16 PM.

  10. #10

    Thread Starter
    PowerPoster
    Join Date
    Aug 2010
    Location
    Canada
    Posts
    2,709

    Re: Image Markup Tools

    Latest version in first post updated with the following:

    • Ability to set text horizontal and vertical alignment.
    • Other minor changes/improvements.


    NOTE: The RC6 DrawText method only supports Top and Middle vertical alignment AFAICT. Hopefully Olaf will consider adding Bottom alignment support, but if not then I will add bottom alignment support in this project.
    Last edited by jpbro; Mar 18th, 2025 at 04:16 PM.

  11. #11

    Thread Starter
    PowerPoster
    Join Date
    Aug 2010
    Location
    Canada
    Posts
    2,709

    Re: Image Markup Tools

    Latest version in first post updated with the following:

    • Double-clicking a Text box will raise the TextRequested event so you can give users an opportunity to edit text for existing objects (in case of typos for example).

  12. #12
    Junior Member anycoder's Avatar
    Join Date
    Jan 2025
    Posts
    26

    Re: Image Markup Tools

    Nice work, and thanks for the contribution!
    I modified the CPolygon code to draw smooth polygons, theoretically the ratio for adding curves by hand should be 1/6 but in most cases it gives a very strong result, so the ratio 0.14 is used in this example.

    Name:  smooth.png
Views: 390
Size:  414.9 KB


    Code:
    Private Type IntPt
      X As Long
      Y As Long
    End Type
    ...
    Private Sub InterP(Result As IntPt, Pt As CPoint, Pt1 As CPoint, Pt2 As CPoint, ByVal t As Single)
        Result.X = Pt.X + (Pt1.X - Pt2.X) * t
        Result.Y = Pt.Y + (Pt1.Y - Pt2.Y) * t
    End Sub
    
    Private Sub IDrawable_Draw(po_CairoContext As RC6.cCairoContext, Optional ByVal po_LivePoint As CPoint = Nothing, Optional ByVal p_PathOnly As Boolean = False, Optional ByVal p_IsSelected As Boolean = False, Optional ByVal p_DrawHandles As Boolean = False, Optional ByVal p_Zoom As Double = 1#)
       Dim lo_Points As RC6.cArrayList
       Dim lo_Pt As CPoint
       Dim ii As Long
       Dim Ctrls() As IntPt
       Dim Prv As CPoint, nxt As CPoint
       Dim last As Long, nx As Long
       With po_CairoContext
          Set lo_Points = Me.Points(True)
          
          If Me.BorderThickness > 0 Then OffsetPolygonPoints lo_Points, Me.BorderThickness * PointsPerPixel / 2
           If Not po_LivePoint Is Nothing Then
              lo_Points.Add po_LivePoint
           End If
          ReDim Ctrls(0 To lo_Points.Count * 2 - 1)
          For ii = 0 To lo_Points.Count - 1
             Set lo_Pt = lo_Points(ii)
             nx = ii + 1: If nx = lo_Points.Count Then nx = 0
             last = ii - 1: If last < 0 Then last = lo_Points.Count - 1
             Set nxt = lo_Points(nx)
             Set Prv = lo_Points(last)
             Call InterP(Ctrls(last * 2 + 1), lo_Pt, Prv, nxt, 0.14)
             Call InterP(Ctrls(ii * 2), lo_Pt, nxt, Prv, 0.14)
          Next
          
          Set lo_Pt = lo_Points(0)
          .MoveTo lo_Pt.X, lo_Pt.Y
          Dim p1 As IntPt, p2 As IntPt
          last = 0
          For ii = 1 To lo_Points.Count - 1
              Set lo_Pt = lo_Points(ii)
              p1 = Ctrls(last)
              p2 = Ctrls(last + 1)
              .CurveTo p1.X, p1.Y, p2.X, p2.Y, lo_Pt.X, lo_Pt.Y
              last = last + 2
          Next
           
          Set lo_Pt = lo_Points(0)
          p1 = Ctrls(last)
          p2 = Ctrls(last + 1)
          .CurveTo p1.X, p1.Y, p2.X, p2.Y, lo_Pt.X, lo_Pt.Y
     'end of smooth  code 
          .ClosePath
    
          If p_PathOnly Then
             .ClearPath
          
          Else
             .Save
    
             If Me.BorderThickness > 0 Then
                If Me.BorderAlpha > 0 Then
                   SetLineStyle po_CairoContext, Me.BorderStyle, Me.BorderThickness * PointsPerPixel
                   
                   .SetLineWidth Me.BorderThickness * PointsPerPixel
                   .SetSourceColor Me.BorderColor, Me.BorderAlpha
                   .Stroke True
                End If
             End If
    
             If Me.BackgroundAlpha > 0 Then
                .ClearPath
                
                With Me.Points(True)
                   Set lo_Pt = .Item(0)
                   po_CairoContext.MoveTo lo_Pt.X, lo_Pt.Y
             
                   For ii = 1 To .Count - 1
                      Set lo_Pt = .Item(ii)
                      po_CairoContext.LineTo lo_Pt.X, lo_Pt.Y
                   Next
                End With
                
                If Not po_LivePoint Is Nothing Then
                   ' Extend polygon to current mouse position when it is the new object
                   .LineTo po_LivePoint.X, po_LivePoint.Y
                End If
                
                po_CairoContext.SetSourceColor Me.BackgroundColor, Me.BackgroundAlpha
                po_CairoContext.Fill True
             End If
    
             .ClearPath
    
             If p_IsSelected Then
                ' Offset polygon to draw selection highlight polygon
                OffsetPolygonPoints lo_Points, Me.BorderThickness * PointsPerPixel / 2 + SelectionStrokeThickness
    
                Set lo_Pt = lo_Points(0)
                .MoveTo lo_Pt.X, lo_Pt.Y
    
                For ii = 1 To lo_Points.Count - 1
                   Set lo_Pt = lo_Points(ii)
                   .LineTo lo_Pt.X, lo_Pt.Y
                Next
    
                If Not po_LivePoint Is Nothing Then
                   ' Extend polygon to current mouse position when it is the new object
                   .LineTo po_LivePoint.X, po_LivePoint.Y
                End If
    
                .ClosePath
    
                StrokeSelectionPath po_CairoContext
    
                If p_DrawHandles Then
                   ' Draw resize handles
                   DrawHandles po_CairoContext, Me.Points(False)
                End If
             End If
    
             .Restore
          End If
       End With
    End Sub

  13. #13

    Thread Starter
    PowerPoster
    Join Date
    Aug 2010
    Location
    Canada
    Posts
    2,709

    Re: Image Markup Tools

    Quote Originally Posted by anycoder View Post
    Nice work, and thanks for the contribution!
    I modified the CPolygon code to draw smooth polygons, theoretically the ratio for adding curves by hand should be 1/6 but in most cases it gives a very strong result, so the ratio 0.14 is used in this example.

    Name:  smooth.png
Views: 390
Size:  414.9 KB
    That looks really cool, and thanks for the contribution right back at ya!

    I'll try to get this rolled in to the main code base today.

  14. #14
    Member
    Join Date
    Feb 2013
    Location
    Brasil
    Posts
    50

    Re: Image Annotation & Markup Tools (RC6/Cairo Based)

    Excellent Code and Contribution...
    thanks!

  15. #15

    Thread Starter
    PowerPoster
    Join Date
    Aug 2010
    Location
    Canada
    Posts
    2,709

    Re: Image Annotation & Markup Tools (RC6/Cairo Based)

    Quote Originally Posted by ThiagoPSanches View Post
    Excellent Code and Contribution...
    thanks!
    Glad you found it interesting, and I hope you find it useful!

  16. #16

    Thread Starter
    PowerPoster
    Join Date
    Aug 2010
    Location
    Canada
    Posts
    2,709

    Re: Image Annotation & Markup Tools (RC6/Cairo Based)

    Latest version in first post updated with the following:

    • Added Polygon Edge styles: Smooth (Bezier curved, thanks anycoder!), Ratchet, ZigZag, and Cloud (see image below for examples)
    • Various code improvements/refactorings.


    Edge examples:

    Name:  2025-03-20_10-27-38.jpg
Views: 363
Size:  13.3 KB

  17. #17
    Frenzied Member
    Join Date
    Aug 2020
    Posts
    1,670

    Re: Image Annotation & Markup Tools (RC6/Cairo Based)

    Hi jpbro,
    I'm wondering if your code can do the following:
    (1) Add shadows to the perimeter of regular shapes such as rectangles, circles, and triangles
    (2) Add shadows to the perimeter of irregular shapes.

    Thanks.
    Attached Images Attached Images  
    Last edited by SearchingDataOnly; Mar 21st, 2025 at 09:29 AM.

  18. #18

    Thread Starter
    PowerPoster
    Join Date
    Aug 2010
    Location
    Canada
    Posts
    2,709

    Re: Image Annotation & Markup Tools (RC6/Cairo Based)

    Quote Originally Posted by SearchingDataOnly View Post
    Hi jpbro,
    I'm wondering if your code can do the following:
    (1) Add shadows to the perimeter of regular shapes such as rectangles, gardens, and triangles
    (2) Add shadows to the perimeter of irregular shapes.

    Thanks.
    One way would be to do a Gaussian Blur on the entire image and copy use the alpha channel only. If you put this code in the CompositeImage function right before the code that draws the objects it should do the trick:

    Code:
             ' Draw Drop Shadow
             Dim lO_SrfShadow As RC6.cCairoSurface
             Dim lo_CcShadow As RC6.cCairoContext
             
             Set lO_SrfShadow = Cairo.CreateSurface(lo_Cc.Surface.Width, lo_Cc.Surface.Height)
             Set lo_CcShadow = lO_SrfShadow.CreateContext
             For Each lo_DrawObject In mo_DrawObjects
                DrawObject lo_CcShadow, lo_DrawObject, False
             Next
             Set lO_SrfShadow = lo_CcShadow.Surface.GaussianBlur(8, , True)
             
             lo_Cc.RenderSurfaceContent lO_SrfShadow, -16, -16
    Not sure I want to include this is the main code though as the GaussianBlur method is fairly slow and it cause things like moving objects around to become a bit sluggish - might need to come up with a way skip drawing shadows when performing some actions like move/resize. Maybe detecting if the mouse button is down would be enough, I'll see.

  19. #19
    Frenzied Member
    Join Date
    Aug 2020
    Posts
    1,670

    Re: Image Annotation & Markup Tools (RC6/Cairo Based)

    I'll test your code carefully. Thank you very much, jpbro.

  20. #20

    Thread Starter
    PowerPoster
    Join Date
    Aug 2010
    Location
    Canada
    Posts
    2,709

    Re: Image Annotation & Markup Tools (RC6/Cairo Based)

    I made a mistake in case you read my message before I corrected it - the code should go in the CompositeImage function, not the Redraw Sub.

  21. #21

    Thread Starter
    PowerPoster
    Join Date
    Aug 2010
    Location
    Canada
    Posts
    2,709

    Re: Image Annotation & Markup Tools (RC6/Cairo Based)

    dupe
    Last edited by jpbro; Mar 21st, 2025 at 10:18 AM.

  22. #22

    Thread Starter
    PowerPoster
    Join Date
    Aug 2010
    Location
    Canada
    Posts
    2,709

    Re: Image Annotation & Markup Tools (RC6/Cairo Based)

    Latest version in first post updated with the following:

    • Optional Global Drop Shadow rendering via the EnableGlobalDropShadow property (example image below).
    • Other minor changes/refactorings.



    Drop Shadow Example:
    Name:  2025-03-21_10-50-12.jpg
Views: 333
Size:  33.8 KB

    NOTE ABOUT DROP SHADOW RENDERING: The GaussianBlur method is a bit slow, so drop shadow rendering is disabled when the mouse button is down while moving/drawing/resizing objects. Shadows will be re-rendered after releasing the mouse button.
    Last edited by jpbro; Mar 21st, 2025 at 10:20 AM.

  23. #23

    Thread Starter
    PowerPoster
    Join Date
    Aug 2010
    Location
    Canada
    Posts
    2,709

    Re: Image Annotation & Markup Tools (RC6/Cairo Based)

    Latest version in first post updated with the following:

    • Fixed SaveImage method so that it saves the image in its original size to avoid stretching/upscaling artifacts (was incorrectly saving it at the max viewport size previously)

  24. #24
    Frenzied Member
    Join Date
    Aug 2020
    Posts
    1,670

    Re: Image Annotation & Markup Tools (RC6/Cairo Based)

    Quote Originally Posted by jpbro View Post
    I made a mistake in case you read my message before I corrected it - the code should go in the CompositeImage function, not the Redraw Sub.
    I re-downloaded your new code and it works really well. Much appreciated.

  25. #25

    Thread Starter
    PowerPoster
    Join Date
    Aug 2010
    Location
    Canada
    Posts
    2,709

    Re: Image Annotation & Markup Tools (RC6/Cairo Based)

    Latest version in first post updated with the following:

    • Added IEnded interface for objects that support end point styles (currently only CLine).
    • Increased minimum arrow endpoint size for improved visibility at small stroke thickness values.
    • Click & Drag drawing and moving of objects now temporarily disables global shadow rendering for better performance.
    • Improved Serialize/Deserialize through centralized methods.
    • Improved Select All functionality by raising SelectionChanged event and drawing selected CHighlighter rectangles appropriately.

  26. #26
    Fanatic Member
    Join Date
    Jun 2016
    Location
    EspaƱa
    Posts
    588

    Re: Image Annotation & Markup Tools (RC6/Cairo Based)

    error not defined in
    Code:
    Private Sub IDrawable_Draw(po_CairoContext As RC6.cCairoContext, Optional ByVal po_LivePoint As CPoint = Nothing, Optional ByVal p_PathOnly As Boolean = False, Optional ByVal p_IsSelected As Boolean = False, Optional ByVal p_DrawHandles As Boolean = False, Optional ByVal p_Zoom As Double = 1#)
       Dim lo_IDrawable As IDrawable
       Dim lo_Rect As CRect
       
       Set lo_IDrawable = Me.Rect
       lo_IDrawable.Draw po_CairoContext, po_LivePoint, p_PathOnly, p_IsSelected, p_DrawHandles
       
       po_CairoContext.SelectFont Me.Font.Name, _
                                  Me.Font.Size * PointsPerPixel, _
                                  Me.TextColor, _
                                  Me.Font.Bold, _
                                  Me.Font.Italic, _
                                  Me.Font.Underline, _
                                  Me.Font.Strikethrough
       
       Set lo_Rect = Me.Rect.NormalizedRect   ' Normalize the rectangle so that the text appears if the rect was drawn any direction other than top-left to bottom-right
       
       If Me.VerticalAlignment = verticalalign_Bottom Then
          ' TODO:
          ' RC6 CairoContext.DrawText Method only supports Top/Middle alignment, so we have to do our own bottom alignment text rendering
    
          DrawTextBottomAlign po_CairoContext, _
                                   lo_Rect.X1, _
                                   lo_Rect.Y1, _
                                   lo_Rect.Width, _
                                   lo_Rect.Height, _
                                   Me.Text, _
                                   False, _
                                   Choose(Me.HorizontalAlignment + 1, vbLeftJustify, vbCenter, vbRightJustify), _
                                   10
       Else
          po_CairoContext.DrawText lo_Rect.X1, _
                                   lo_Rect.Y1, _
                                   lo_Rect.Width, _
                                   lo_Rect.Height, _
                                   Me.Text, _
                                   False, _
                                   Choose(Me.HorizontalAlignment + 1, vbLeftJustify, vbCenter, vbRightJustify), _
                                   10, _
                                   Me.VerticalAlignment
       End If
    End Sub
    everything else works very well

  27. #27

    Thread Starter
    PowerPoster
    Join Date
    Aug 2010
    Location
    Canada
    Posts
    2,709

    Re: Image Annotation & Markup Tools (RC6/Cairo Based)

    Quote Originally Posted by yokesee View Post
    error not defined in
    Code:
    Private Sub IDrawable_Draw(po_CairoContext As RC6.cCairoContext, Optional ByVal po_LivePoint As CPoint = Nothing, Optional ByVal p_PathOnly As Boolean = False, Optional ByVal p_IsSelected As Boolean = False, Optional ByVal p_DrawHandles As Boolean = False, Optional ByVal p_Zoom As Double = 1#)
       Dim lo_IDrawable As IDrawable
       Dim lo_Rect As CRect
       
       Set lo_IDrawable = Me.Rect
       lo_IDrawable.Draw po_CairoContext, po_LivePoint, p_PathOnly, p_IsSelected, p_DrawHandles
       
       po_CairoContext.SelectFont Me.Font.Name, _
                                  Me.Font.Size * PointsPerPixel, _
                                  Me.TextColor, _
                                  Me.Font.Bold, _
                                  Me.Font.Italic, _
                                  Me.Font.Underline, _
                                  Me.Font.Strikethrough
       
       Set lo_Rect = Me.Rect.NormalizedRect   ' Normalize the rectangle so that the text appears if the rect was drawn any direction other than top-left to bottom-right
       
       If Me.VerticalAlignment = verticalalign_Bottom Then
          ' TODO:
          ' RC6 CairoContext.DrawText Method only supports Top/Middle alignment, so we have to do our own bottom alignment text rendering
    
          DrawTextBottomAlign po_CairoContext, _
                                   lo_Rect.X1, _
                                   lo_Rect.Y1, _
                                   lo_Rect.Width, _
                                   lo_Rect.Height, _
                                   Me.Text, _
                                   False, _
                                   Choose(Me.HorizontalAlignment + 1, vbLeftJustify, vbCenter, vbRightJustify), _
                                   10
       Else
          po_CairoContext.DrawText lo_Rect.X1, _
                                   lo_Rect.Y1, _
                                   lo_Rect.Width, _
                                   lo_Rect.Height, _
                                   Me.Text, _
                                   False, _
                                   Choose(Me.HorizontalAlignment + 1, vbLeftJustify, vbCenter, vbRightJustify), _
                                   10, _
                                   Me.VerticalAlignment
       End If
    End Sub
    everything else works very well
    Thanks yokesee - you can comment that line out for now, I forgot to (it's a placeholder for the bottom aligned text drawing that isn't implemented yet). I'll update the main source with this bit commented out ASAP.

  28. #28

    Thread Starter
    PowerPoster
    Join Date
    Aug 2010
    Location
    Canada
    Posts
    2,709

    Re: Image Annotation & Markup Tools (RC6/Cairo Based)

    Updated latest source in first post to fix the problem yokesee reported in Post #26. Thank your for reporting the problem!

  29. #29
    Addicted Member Mojtaba's Avatar
    Join Date
    Dec 2020
    Posts
    224

    Re: Image Annotation & Markup Tools (RC6/Cairo Based)

    Hi jpbro, very good, thank you.
    I don't know why the software takes so long to load for me!
    I have a suggestion: add a ruler. And maybe guide lines
    I wrote a simple example.
    Of course, I'm not a professional like you.

    Name:  Ruler.jpg
Views: 241
Size:  18.9 KB
    Attached Files Attached Files

  30. #30

    Thread Starter
    PowerPoster
    Join Date
    Aug 2010
    Location
    Canada
    Posts
    2,709

    Re: Image Annotation & Markup Tools (RC6/Cairo Based)

    Quote Originally Posted by Mojtaba View Post
    Hi jpbro, very good, thank you.
    Glad you like it

    Quote Originally Posted by Mojtaba View Post
    I don't know why the software takes so long to load for me!
    You probably have a lot of fonts - the demo app/form loads all fonts into the combobox and it is quite slow. The more fonts, the worse it gets. There are better ways to populate combos with fonts, but they're outside the scope of this demo (here's one example by LaVolpe)

    Quote Originally Posted by Mojtaba View Post
    I have a suggestion: add a ruler. And maybe guide lines
    It's a good idea, but I'm not sure I want to add them as features to the base class. Instead I have decided on the concept of an Underlay and Overlay layer. The underlay appears above the base background image and below the annotation layer. The overlay appears above all other layers.

    There are 2 new events: BeforeRenderUnderlay and BeforeRenderOverlay, each of which provide a cCairoContext that you can draw anything you like against. The underlay would be good for rulers, and the overlay would be good for something like tooltips/coordinate reporting that follows the mouse.

    Name:  2025-03-29_8-01-51.jpg
Views: 188
Size:  36.1 KB

    NOTE: In the above image, the yellow diagonal line is painted on the underlay layer (drawing under the polygon in the annotation layer). The green diagonal line appears in the overlay layer (drawing over the polygon in the annotation layer).

    I'll probably need to add some additional features to make this more useful (like exposing the mouse coords, and zoom factor so that you can adjust ruler values appropriately), but it's a good starting point if you want to play around with it and report back with any problems or places where it lacks necessary info you need to draw what you would like.
    Last edited by jpbro; Mar 29th, 2025 at 07:06 AM.

  31. #31

    Thread Starter
    PowerPoster
    Join Date
    Aug 2010
    Location
    Canada
    Posts
    2,709

    Re: Image Annotation & Markup Tools (RC6/Cairo Based)

    Latest version in first post updated with the following:

    • Added BeforeRenderUnderlay and BeforeRenderOverlay events that provide a cCairoContext object for you to draw anything you like (thanks Mojtaba for the idea to allow for the drawing of ruler/gridlines)
    • Fixed bug when exporting images to file with global drop shadow enabled (shadow wasn't scaling properly).
    • Fixed render bug with cHighlighter (broke the single fill of multiple rectangles, even if they were overlapping in an earlier release)

  32. #32
    Addicted Member Mojtaba's Avatar
    Join Date
    Dec 2020
    Posts
    224

    Re: Image Annotation & Markup Tools (RC6/Cairo Based)

    Quote Originally Posted by jpbro View Post
    Glad you like it
    You probably have a lot of fonts - the demo app/form loads all fonts into the combobox and it is quite slow. The more fonts, the worse it gets. There are better ways to populate combos with fonts, but they're outside the scope of this demo (here's one example by LaVolpe)
    I've talked about this before.
    software runs late after compilation
    This problem exists if you use the GDI+ library in fonts.
    Of course, if the number of fonts exceeds about 600 or 700
    the program's slow loading becomes clearly visible, but below these numbers it is not so noticeable.
    There are several other suggestions: the ability to zoom in and take screenshots, and . . .
    I noticed a small problem: when you load a new photo or minimize the program window, the image disappears and does not refresh.
    And you must click on the board to see the image again.

  33. #33

    Thread Starter
    PowerPoster
    Join Date
    Aug 2010
    Location
    Canada
    Posts
    2,709

    Re: Image Annotation & Markup Tools (RC6/Cairo Based)

    Quote Originally Posted by Mojtaba View Post
    I noticed a small problem: when you load a new photo or minimize the program window, the image disappears and does not refresh.
    And you must click on the board to see the image again.
    Thanks for reporting, this is fixed in the latest source in the first post.

    Quote Originally Posted by Mojtaba View Post
    I've talked about this before.
    software runs late after compilation
    This problem exists if you use the GDI+ library in fonts.
    Of course, if the number of fonts exceeds about 600 or 700
    the program's slow loading becomes clearly visible, but below these numbers it is not so noticeable.
    This project doesn't use GDI+ at all, so that shouldn't be an issue.

    If you comment out the following code in Form_Load:

    Code:
       For ii = 0 To Screen.FontCount - 1
          Me.cmbFont.AddItem Screen.Fonts(ii)
       Next
    And replace it with:

    Code:
       Me.cmbFont.AddItem "Segoe UI"
    Does it load faster?

    Quote Originally Posted by Mojtaba View Post
    There are several other suggestions: the ability to zoom in and take screenshots, and . . .
    Zoom is a possibility, but I don't think I'll get into screenshots as it is outside the scope of what this project is meant for. Just FYI the goal isn't for a full-featured paint application, nor a replacement for something like the Windows snipping tool or SnagIt. But feel free to expand on the source as required for your needs.

  34. #34
    Addicted Member Mojtaba's Avatar
    Join Date
    Dec 2020
    Posts
    224

    Re: Image Annotation & Markup Tools (RC6/Cairo Based)

    Quote Originally Posted by jpbro View Post
    Thanks for reporting, this is fixed in the latest source in the first post.
    Does it load faster?
    Yes
    I use FontCombo for projects where I need to select fonts.
    CommonControls (Replacement of the MS common controls)
    Loads all fonts without slowing down
    But I couldn't find a solution to the problem with GDI+.
    I agree with you on the screenshot as well.

  35. #35

    Thread Starter
    PowerPoster
    Join Date
    Aug 2010
    Location
    Canada
    Posts
    2,709

    Re: Image Annotation & Markup Tools (RC6/Cairo Based)

    Latest version in first post updated with the following:

    • Added Zoom/Scaling Support via CanvasZoomPercent property.
    • Fixed bug related to deleting CHighlighter objects after Select All operation.
    • CHighlighter drawing is now excluded from global dropshadow rendering (it was darkening the highlight which seem counter to the intention of the tool).
    • Various minor fixes/improvements.


    I think the project is complete feature-wise with this update - it does everything I need it to and more. I'll continue to fix bugs as needed, but otherwise I'm signing off.

    I hope some of you find this project useful, enjoy!

  36. #36

    Thread Starter
    PowerPoster
    Join Date
    Aug 2010
    Location
    Canada
    Posts
    2,709

    Re: Image Annotation & Markup Tools (RC6/Cairo Based)

    Whoops, I mucked something up in the latest version - don't download it yet or drawing in Fit to Viewport mode won't work.

  37. #37

    Thread Starter
    PowerPoster
    Join Date
    Aug 2010
    Location
    Canada
    Posts
    2,709

    Re: Image Annotation & Markup Tools (RC6/Cairo Based)

    First post update with fix to the problems with Fit To Viewport mode, everything should be working now.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width