Follow along with the video below to see how to install our site as a web app on your home screen.
Note: This feature may not be available in some browsers.
the OP didn't originally mention an antialias requirement
Lparameters tcSourceImage, tnCornerSize, tnImageWidth, tnImageHeight, tcSaveImageAs
#Define RESIZED 1
#Define ROUNDED 2
tcSourceImage = Evl(tcSourceImage, Home()+'fox.bmp')
tcSaveImageAs = Evl(tcSaveImageAs, Forceext(tcSourceImage,"png"))
If Upper(tcSaveImageAs)==Upper(tcSourceImage)
tcSaveImageAs = Forceext(Justpath(tcSaveImageAs)+"\"+Juststem(tcSaveImageAs)+"rounded","png")
Endif
tnCornerSize = 2*Evl(tnCornerSize, 0)
* Double what you ask for, because the rounded rectange
* will be constructed from four arcs, each being a quarter circle
* at the corner of a square positioned at the corners of the image.
* A quarter circle only cuts off a quarter of the corner square,
* so the square needs to have double width and height.
* The arcs transition into the straight border edge at the offset
* you pass in as original tnCornerSize by using this original value
* as radius of the arc. That results in the corner size you want.
tnImageWidth = Evl(tnImageWidth, 0)
tnImageHeight = Evl(tnImageHeight, 0)
* ensure gdiplusx system.app is loaded already or will be started here
Local loGdiPlusXSystem
Try
loGdiPlusXSystem = _Screen.System
Catch
* you might want to use a configured path to system.app here or
* put it into the same directory as your EXE and use Justpath(Sys(16,0))
* for starters simply once DO SYSTEM.APP to not get here
* or (just once) manually locat the VFPX gdiplusx system.app
Do (Locfile("System.App"))
loGdiPlusXSystem = _Screen.System
Endtry
With loGdiPlusXSystem.Drawing
Local originalImg, resizedPNG, roundedPNG, loGfx, bgBrush, fgBrush, lnWdith, lnHeight, lnProcessed
originalImg = .Bitmap.New(tcSourceImage)
lnProcessed = 0
If tnImageWidth>0 And tnImageHeight>0
* Resizing to passed in size
lnWdith = tnImageWidth
lnHeight = tnImageHeight
Else
* keep original size
lnWdith = originalImg.Width
lnHeight = originalImg.Height
Endif
If Not (lnWdith == originalImg.Width And lnHeight == originalImg.Height)
* resizing (for example to fit image control width/height
* create a new bitmap with new size for that purpose
resizedPNG = .Bitmap.New(w,h,w*4, .Imaging.PixelFormat.Format32bppARGB)
loGfx = .Graphics.FromImage(resizedPNG)
* draw the original image in that new size
loGfx.DrawImage(originalImg, 0, 0, lnWdith, lnHeight)
loGfx.Dispose()
* This signals a resized image was created and is available as resizedPNG object
lnProcessed = RESIZED
Endif
If tnCornerSize>0
* rouding the corners with the help of a rounded rectangle path
* yet another new bitmap "roundedPNG"
roundedPNG = .Bitmap.New(lnWdith, lnHeight, lnWdith*4, .Imaging.PixelFormat.Format32bppARGB)
loGfx = .Graphics.FromImage(roundedPNG)
canvasRect = .Rectangle.New(0, 0, lnWdith, lnHeight)
bgColor = .Color.New(0) && RGBA=0 means alpha=0, which is fully transparent
bgBrush = .SolidBrush.New(bgColor)
loGfx.FillRectangle(bgBrush, canvasRect) && fill roundedPNG with transparency
bgBrush.Dispose()
* Coordinates of Corner squares
Local xr, yb, tl, tr, bl, br
xr = lnWdith - tnCornerSize-1
yb = lnHeight - tnCornerSize-1
tl = .Rectangle.New( 0, 0, tnCornerSize, tnCornerSize)
tr = .Rectangle.New(xr, 0, tnCornerSize, tnCornerSize)
br = .Rectangle.New(xr,yb, tnCornerSize, tnCornerSize)
bl = .Rectangle.New( 0,yb, tnCornerSize, tnCornerSize)
* try .Drawing2D.SmoothingMode.None to see the difference
loGfx.SmoothingMode = .Drawing2D.SmoothingMode.AntiAlias
* smoothing mode is used for smoothing the path and the fill,
* so the rounded edges are smooth
* create a rounded rectangle path
Local rectPath
rectPath = .Drawing2D.GraphicsPath.New()
* quarter circle arcs, each sweeping 90 degrees clockwise of a cornersquare (tl,tr,br,bl)
rectPath.AddArc(tl, 180, 90)
rectPath.AddArc(tr, 270, 90)
rectPath.AddArc(br, 0, 90)
rectPath.AddArc(bl, 90, 90)
rectPath.CloseAllFigures()
If lnProcessed = RESIZED
* when the original image was resized, resizedPNG will be used as brush
fgBrush = .TextureBrush.New(resizedPNG)
Else
* otherwise originalImg will be used as brush for filling the rounded rectangle path
fgBrush = .TextureBrush.New(originalImg)
Endif
* fill the path with the (resized) image
loGfx.FillPath(fgBrush,rectPath)
fgBrush.Dispose()
loGfx.Dispose()
* This signals a rounded corner image was created and is available to save it
lnProcessed = lnProcessed + ROUNDED
Endif
Do Case
Case lnProcessed = 0 && neither resized nor rounded
* save the loaded image in PNG format. This just converts the image format
originalImg.Save(tcSaveImageAs, .Imaging.ImageFormat.Png)
Case lnProcessed = RESIZED && ONLY resized, not rounded
* save the resized image in PNG format
resizedPNG.Save(tcSaveImageAs, .Imaging.ImageFormat.Png)
Otherwise && rounded (no matter wether resized or not)
* save roundedPNG
roundedPNG.Save(tcSaveImageAs, .Imaging.ImageFormat.Png)
Endcase
Endwith
ROUNDEDEDIMAGE("yourimage.jpg",50) && 50 pixel sized rounded corners.
ROUNDEDEDIMAGE("yourimage.jpg",50,800,450) && 50 pixel sized corners cut off the image first resized to 800x450
ROUNDEDEDIMAGE("yourimage.jpg",50,800,450,GETENV("TEMP")+"\yourimage.png") && as before, just explicitly using yourimage.png as result file name.