2 Attachment(s)
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:
Attachment 193501
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.
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.
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
1 Attachment(s)
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:
Attachment 193511
Re: Cairo graphics (RC6): Dilate image with transparent regions
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?
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.
Re: Cairo graphics (RC6): Dilate image with transparent regions
Thank you, I did that now.
1 Attachment(s)
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:
Attachment 193516
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