Results 1 to 10 of 10

Thread: Cairo graphics (RC6): Dilate image with transparent regions

  1. #1

    Thread Starter
    Fanatic Member
    Join Date
    Jul 2017
    Posts
    761

    Question Cairo graphics (RC6): Dilate image with transparent regions

    Hello!

    I have been following this tutorial: https://www.vbforums.com/showthread....an-Cairo-do-it as I am still trying to make a graphic appear like a paper cut out.

    It does not work in my case because the object in my image is irregular.
    Simply offsetting copies of the original image creates something like that:

    Name:  offset.png
Views: 391
Size:  244.6 KB

    Can somebody tell me if he knows a way to relatively easily "dilate" (I believe that is the term) such an image, or do I have to use OpenCV, ConvexHull detection and maximas?

    Thank you.
    Attached Files Attached Files
    Last edited by tmighty2; Nov 17th, 2024 at 08:48 PM.

  2. #2
    Frenzied Member
    Join Date
    Apr 2012
    Posts
    1,272

    Re: Cairo graphics (RC6): Dilate image with transparent regions

    If you create a blurred version of your image, and then paint that with a single colour, you should be able to use that as an outline for your actual image.
    If you don't know where you're going, any road will take you there...

    My VB6 love-children: Vee-Hive and Vee-Launcher

  3. #3

    Thread Starter
    Fanatic Member
    Join Date
    Jul 2017
    Posts
    761

    Re: Cairo graphics (RC6): Dilate image with transparent regions

    Thank you.
    I feel so stupid, I don't manage it.

    I tried it for 4 hours.

    Can you fix my code?
    Code:
    Public Function CreateDilate(ByRef uSrc As cCairoSurface, ByVal uColor As Long, ByVal uDilateWidth As Long) As cCairoSurface
    
        Dim sBlur As cCairoSurface
        Set sBlur = uSrc.CreateSimilar(CAIRO_CONTENT_COLOR_ALPHA, , , True)
        sBlur.FastBlur 30
    
        With Cairo.CreateSurface(uSrc.Width * (uDilateWidth * 2), uSrc.Height * (uDilateWidth * 2)).CreateContext
            .RenderSurfaceContent sBlur, 0, 0, sBlur.Width, sBlur.Height, , 1
            .SetSourceColor uColor
            .MaskSurface .Surface
            Set CreateDilate = .Surface
        End With
        
    End Function

  4. #4
    PowerPoster
    Join Date
    Aug 2010
    Location
    Canada
    Posts
    2,892

    Re: Cairo graphics (RC6): Dilate image with transparent regions

    Try this code (the meat was written by Olaf, I just did some surrounding stuff and added comments to try to explain what the code is doing):

    Code:
       Dim lo_SrfImage As RC6.cCairoSurface
       Dim lo_SrfBorder As RC6.cCairoSurface
       Dim b() As Byte
       Dim re As Byte
       Dim gr As Byte
       Dim bl As Byte
       
       ' Load main image
       Set lo_SrfImage = Cairo.CreateSurface(0, 0, , "C:\myimage.png")   ' Change path to path to your image
       
       ' Create blurred image surface for the border
       Set lo_SrfBorder = lo_SrfImage.GaussianBlur(15, 15)   ' Change this number to change the border width
    
       ' Get border colour RGB
       bl = (vbRed And &HFF0000) \ &H10000 ' Change vbRed to whatever colour you want the border to be
       gr = (vbRed And &HFF00&) \ &H100&
       re = vbRed And &HFF
       
       ' Remove transparency and change colour
       lo_SrfBorder.BindToArray b
    
       For y = 0 To UBound(b, 2): For x = 0 To UBound(b, 1) Step 4
             If b(x + 3, y) > 5 And b(x + 3, y) < 255 Then   'when semi-transparent (in a certain range)...
                ' Colors are stored in BGRA order
                
                b(x + 0, y) = bl
                b(x + 1, y) = gr
                b(x + 2, y) = re
                b(x + 3, y) = 255 '...set all 4 components of the whole pixel to fully opaque
             Else
                b(x + 0, y) = 0   '...set all 4 components of the whole pixel to fully transparent
                b(x + 1, y) = 0
                b(x + 2, y) = 0
                b(x + 3, y) = 0
             End If
          Next x
       Next y
    
       lo_SrfBorder.ReleaseArray b
       
       ' Draw original image over top border image
       lo_SrfBorder.CreateContext.RenderSurfaceContent lo_SrfImage, lo_SrfBorder.Width / 2 - lo_SrfImage.Width / 2, lo_SrfBorder.Height / 2 - lo_SrfImage.Height / 2
       
       lo_SrfBorder.DrawToDC Me.hDC  ' Draw the image with border
    Should produce a result like this:

    Name:  2024-11-18_13-07-24.jpg
Views: 236
Size:  43.3 KB

  5. #5

    Thread Starter
    Fanatic Member
    Join Date
    Jul 2017
    Posts
    761

    Re: Cairo graphics (RC6): Dilate image with transparent regions

    Thank you so much!!

  6. #6

    Thread Starter
    Fanatic Member
    Join Date
    Jul 2017
    Posts
    761

    Re: Cairo graphics (RC6): Dilate image with transparent regions

    I am trying to locate a post that is about dropshadow with RC6 / Cairo Graphics, but I don't find one.

    Can somebody recommend his way of doing it?

  7. #7
    PowerPoster
    Join Date
    Aug 2010
    Location
    Canada
    Posts
    2,892

    Re: Cairo graphics (RC6): Dilate image with transparent regions

    Might be better to start a new topic for this, but I recommend playing around with GaussianBlur, then convert to grayscale (using Olaf's method here), and maybe even play with the gamma/brightness/contrast using the CCairoSurface.AdjustColors method. Finally draw the shadow at an XY position offset from center and draw the main image over top at the center.

  8. #8

    Thread Starter
    Fanatic Member
    Join Date
    Jul 2017
    Posts
    761

    Re: Cairo graphics (RC6): Dilate image with transparent regions

    Thank you, I did that now.

  9. #9

    Thread Starter
    Fanatic Member
    Join Date
    Jul 2017
    Posts
    761

    Re: Cairo graphics (RC6): Dilate image with transparent regions

    You mean this one?

    ->

    Code:
    Private Sub RenderDisabledIco(CC As cCairoContext, Srf As cCairoSurface, x, y)
          CC.SetSourceColor vbWhite
          CC.MaskSurface Srf, x, y
          CC.Operator = Cairo_OPERATOR_HSL_LUMINOSITY
            CC.RenderSurfaceContent Srf, x, y
          CC.Operator = CAIRO_OPERATOR_OVER
    End Sub
    They greyscale functions on that page produce the following image for me which is perhaps "disabled", but not really greyscale:

    Name:  disabled1.png
Views: 280
Size:  1.4 KB
    Last edited by tmighty2; Nov 18th, 2024 at 09:14 PM.

  10. #10

    Thread Starter
    Fanatic Member
    Join Date
    Jul 2017
    Posts
    761

    Re: Cairo graphics (RC6): Dilate image with transparent regions

    Ok, I got it now, I hope.
    I didn't use the right parameter for Make(...), and Y in that function should be 0, not 1.

    Here is the full code now:


    Code:
    Public Sub MakeSemiTransparentFullyOpaqueBlack(Srf As cCairoSurface, ByVal uShadowAlpha As Byte, Optional ByVal UpperAlpha As Byte = 128)
      Dim X As Long, y As Long, b() As Byte
    
      Srf.BindToArray b
    
      For y = 0 To UBound(b, 2): For X = 0 To UBound(b, 1) Step 4
        If b(X + 3, y) > 0 And b(X + 3, y) > UpperAlpha Then 'when semi-transparent (in a certain range)...
           
           b(X + 0, y) = 0
           b(X + 1, y) = 0
           b(X + 2, y) = 0
           b(X + 3, y) = uShadowAlpha '255 = completely black/opaque 0=completely transparent, 124=halftransparent
        End If
      Next X, y
      
      Srf.ReleaseArray b
    End Sub
    Public Function CreateDropShadow(ByRef uSurf As cCairoSurface, ByVal uRadius As Long, ByVal uColor As Long, ByVal uAlpha As Double) As cCairoSurface
    
        Dim btAlpha As Byte
        btAlpha = pConvertAlpha(uAlpha)
    
        Dim nCopyOrigS As cCairoSurface
        Set nCopyOrigS = uSurf.CreateSimilar(CAIRO_CONTENT_COLOR_ALPHA, , , True)
    
        MakeSemiTransparentFullyOpaqueBlack nCopyOrigS, btAlpha, 0
      
        'debugging:
        'nCopyOrigS.WriteContentToPngFile "d:\weg\bla2.png"
    
        Dim nCopyOrigC As cCairoContext
        Set nCopyOrigC = nCopyOrigS.CreateContext
    
        Dim lRetRadius&
        lRetRadius = uRadius
     
        Set nCopyOrigS = nCopyOrigS.GaussianBlur(lRetRadius / 2, lRetRadius, False)
    
        Dim lWidthOrig&
        lWidthOrig = uSurf.Width
        
        Dim lWidthShadow&
        lWidthShadow = nCopyOrigS.Width
    
        Dim lAdd&
        lAdd = (lWidthShadow - lWidthOrig)
        
      '  Me.Caption = "Input radius: " & uRadius & ", ret radius: " & lRetRadius & ", diff: " & lAdd
        Set CreateDropShadow = nCopyOrigS
        
    End Function

Tags for this Thread

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