×
INTELLIGENT WORK FORUMS
FOR COMPUTER PROFESSIONALS

Contact US

Log In

Come Join Us!

Are you a
Computer / IT professional?
Join Tek-Tips Forums!
  • Talk With Other Members
  • Be Notified Of Responses
    To Your Posts
  • Keyword Search
  • One-Click Access To Your
    Favorite Forums
  • Automated Signatures
    On Your Posts
  • Best Of All, It's Free!

*Tek-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.

Posting Guidelines

Promoting, selling, recruiting, coursework and thesis posting is forbidden.

Students Click Here

How to make edges of picture rounded?
5

How to make edges of picture rounded?

How to make edges of picture rounded?

(OP)
Hi experts... I have an image put in my form, which is square... I want to have its corner rounded... Can you do rounded corner for images on the form? if so, please teach me how... Thanks and God bless....

RE: How to make edges of picture rounded?

The image control always is a rectangle, so the only way would be to edit the image to have rounded corners which should be transparent and saved as PNG format.

Chriss

RE: How to make edges of picture rounded?

You can do this easily in a photo-editing program. My choice would be Paint.Net, which is a bit like PhotoShop, but simpler to use and with the advantage of being free. This isn't the place to give a tutorial on using that sort of program, but a a very quick guide:

1. Use the program's Selection tool to select a rounded rectangle around the edge of the image (a bit like selecting text in Word).

2. Invert the selection - so that the area that was previously outside the selected area is now selected, and vice versa.

3. Delete the selected area. So the area outside the rounded rectangle will now be transparent.

4. Save the image as a PNG (not a JPEG, which does not support transparency).

5. Drop the image onto your VFP form.

The details will vary according to which photo-editing program you use, but the principle will be the same.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads

RE: How to make edges of picture rounded?

I don't know how many images you want to show with rounded corners, if it's a large batch like any product image for a POS system, it can be an advantage that Gimp (n alternative to Paintnet graphics software) offers batch processing, I don't know but also don't think Paint.net does offer that.

Well, but in any case, the most preferred solution would be to not need to modify the images at all. You can put objects on top of objects it would work to have the inverse, an image with a transparent rounded rectangle and grey or whatever background color you need in the corners, which could be put in front of any other image and only show the portion of the image below that is in the transparent rounded rectangle area. So in short like using a passe-partout.

A disadvantage of that is, that the corners then are in the color of the passe-partout image and if your form color changes or you have a gradient of colors, that passe-partout has to be adjusted.

There's the capability to paint or compute images with the help of GDIplusX, too, but I doubt it makes things easier, though it could take in the normal rectangular images and round the corners off on the fly, storing that as PNG for the current session of the application to use it. Which would make it easier to introduce more images as they can stay as they are and the rounding is always done on the fly.

Chriss

RE: How to make edges of picture rounded?

Mandy, just an afterthought to my earlier post ...

Instead of a PNG, if you can save the image as a BMP, you could select the area outside the rounded rectangle, and then fill it with white. With BMPs, white areas become transparent when placed on a VFP form. I'm not sure, but you might be able to do that in the Paint program that comes with Windows.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads

RE: How to make edges of picture rounded?

It's a shame FoxPro controls don't have an hWnd - there's a neat little trick with Windows Regions that would solve this

RE: How to make edges of picture rounded?

You're thinking of the good old news2news implementation of irregular shaped forms. It's still there, moved to VFPX as Win32API repository.

https://github.com/VFPX/Win32API/blob/master/sampl...

You could do it and create any shape you want, then add the function SetParent to embed this form into another, which would also move when the parent form is moved, so it looks like being part of the parent form, still its THISFORM isn't the parent form. For display of an image that idea would work.

But then I think using GDI+ for image processing would be simpler. PNG transparency can create nicer shaprer/rounder edges, as the alpha transparency can go from 0 to 255 per pixel, whereas the form regions are shaped on basis of pixels being fully transparent or opaque.

I remember the VFP9 version without any SP had issues with some PNG formats, but that was fixed in SP1.

Chriss

RE: How to make edges of picture rounded?

>You're thinking of the good old news2news

Is that comment for me? If so, then no I am certainly not. If the FoxPro image control was an actual window with an hWnd, then my solution involves adding about 2 lines of code. Sadly the Fox developers decided to do their own implementation of the various controls rather than simply wrapping the ones provided by the OS.

RE: How to make edges of picture rounded?

Strongm, yes, I meant you. I thought you know it from there as that sample was how the whole VFP community got introduced to the possibility of transparency of forms. It works with regions, too, specifically by using the SetWindowRgn Windows API function.

Well, I don't see how it's just a two liner, even not taking into account the DECLARE DLL call, you also have to define a region, which needs a struct and further API calls. And then you have a rectangle region, not yet a rounded rectangle.

Chriss

RE: How to make edges of picture rounded?

I couldn't resist searching, I see there is CreateRoundRectRgn to create a rounded rectangle region. But looking for usage of it I see it does not support anti aliasing the rounded edges.

PNG still is the most straight forward solution also supporting alpha levels per pixel for very smooth antialiased rounded corners.

Chriss

RE: How to make edges of picture rounded?

(OP)
Oh… hmmmm… I see… thanks Mike and Chriss… i would try the PNG format… God bless…

RE: How to make edges of picture rounded?

I don't know what graphic software you have available, Mike has posted the steps to do it in Paint.Net,
I make it easier for myself and point out a nice and short tutorial about deleting corners from an image with Gimp: https://www.youtube.com/watch?v=CoYDIrppc2s

Chriss

RE: How to make edges of picture rounded?

>I thought you know it from there as that sample was how the whole VFP community got introduced to the possibility of transparency of forms

Nah. We were playing with SetLayeredWindowAttributes and SetWindowRegion about 20 years ago in the VB6 forum

>CreateRoundRectRgn

Bingo!

>does not support anti aliasing the rounded edges

Yep, definitely a drawback of the old Region methods - but on the other hand the OP didn't originally mention an antialias requirement smile


RE: How to make edges of picture rounded?

Quote:

the OP didn't originally mention an antialias requirement

I'm a bit annoyed about this stance to only exactly deliver what is asked for.

If you want rounded corners, you surely don't have a white form layout and product pictures with white background, as rounded corners make no difference, then. And as rounded corners are very obviously an esthetic design goal, it makes sense to give a solution that satisfies that the best, too, and so to think about it even though it wasn't even asked for.

With the Gimp rounded rectangle tool you get antialiased edges that won't look jiggy without even thinking about it, it's a standard, and it's annoying me how little Microsoft pays attention to such design details, it's no wonder they lost so many market shares to Apple. Even though they follow design trends or even try to set them first with Aero, then with flat bicolor designs and also complex though still very subtle and therefore also unnecessary animations.

It's very telling that there is a setting for turning animations off, though:


Okay, I'll stop my rant here, but I won't follow this idea of not adding things to the answer that go beyond what was asked.

As said, I'm just a bit annoyed.

Chriss

RE: How to make edges of picture rounded?

The other solution I proposed was using a passe-partout image that has a transparent round rectanlge region. To not need a different image per size you can split this up into the 4 corners and here I created 4 rounded corners as PNG images you can put into 4 image controls and position them at the corners of any image, which could then be any format, also formats not supporting transparency. Because the clipping and the round edge is done by these images, which are PNG and have an antialiased (smooth) round edge.


top left ... top right:
...

bottom left ... bottom right:
...

The form surrounding this just needs the grey tone of these edges, and you could adjust that color, but also, as I said, need to adjust this color, if you want the corners to blend in to the rest of the form. It also won't work if the form background is set to an image itself, to let that shine through at the corners you need a PNG image with transparency at the corners.

Chriss

RE: How to make edges of picture rounded?

Last not least, here's code using the VFPX project GDIPlusX to create an image with rounded corners. I post this, as it means you can use it on the fly on any image you use in your EXE already as is, as it computes a rounded corner variant of any image at runtime. You then won't need to manually prepare images.

Before you start
The GDIPlusX project is located at https://github.com/VFPX/GDIPlusX
The simplest way to download it is to click on the green "Code" button/dropdown and pick "Download ZIP". That way you get all of this GitHub repository. What you finally need is a file System.app. See the paragraph Distribution files.

You find further info and Doug Henning, who owns the repository also has written some article about the usage of it at https://doughennig.com/papers/Pub/IntrotoGDIPlusX....
I got the idea from his papers example to draw an image on a circle in his code sample on page 11 of the PDF (result image on page 12). He uses a method called FillEllipse and I found out there's also FillPath, which uses the concept of describing an area by a closed path - the border of an area, a rectangle with rounded corners, for example, as you need it.

Then I found out how to define and use such a path and some pitfalls of it.

Once you have System.App unzipped from the download you can put it in your project directory and later install it together with the EXE. It remains a separate file and isn't embedded into your EXE when you build it. You can also take the full source code and embed it into your project, but for easier usage just DO System.App and it will generate an environment necessary to make usage of many graphical functionalities all under the roof of the GDIPlus.dll which is part of the VFP runtimes and at the same time is a Windows system resource for drawing besides Direct2D or even Direct3D, which are more powerful but also more complicated to use.

Take a look around, this package also is usable for graphics in reports and more. The homepage and also Doug's paper mention an image control class imgCanvas that can replace the VFP image control and is well integrated with the gdiplusx library and it would be an idea to subclass this as imgRoundedCanvas, for example, with Cornersize as property and automatic processing of whatever you set as its Picture. But I decided against that, as it makes it more complex to integrate this in your project.

What you can do with the following function saved as ROUNDEDEDIMAGE.PRG is create a version of image files with rounded corners. Minimally you need to pass in the original file name of the image and the cornersize you want (in pixelsize). The function then saves the result as filename with "rounded" added to the end of the name. The PNG format is used, to support transparency. Whatever the original image format is doesn't matter, as long as it's BMP,GIF,JPEG,JPG, anything VFP can support, so any format your images will already have.

To use that new image you then, of course, need to set an image.Picture to the result file of this code. Another way of using that would be to once process all the images you want to have with rounded corners and use them in your project. That way you wouldn't need to integrate it into your project but only use it from VFP to prepare your image. It's easy to process a whole list of files using ADIR() to get an array of file names and then call this PRG for each image file.

CODE --> ROUNDEDEDIMAGE.PRG

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 

Minimal usage is by calling

CODE

ROUNDEDEDIMAGE("yourimage.jpg",50) && 50 pixel sized rounded corners. 
The result of that is an image file "yourimagerounded.png" in the same directory as "yourimage.jpg".

The parameters offer more control than just the corner size. In prospect of the image control on a form not being the size of the original image but smaller, you can also use further parameters to shrink the image before rounding the corners, using the imagecontrol.width and height as the basis.

So for example "yourimage.jpg" may be a desktop-sized image and your form image control is only perhaps 30% of that size. If you cut off 50 pixel rounded corners from the desktop size image and the image control then stretches or better shrinks it down, the corners will also get smaller. If you instead first resize the whole image and then cut off the corners, you get the corner size you want to see on your form.

CODE

ROUNDEDEDIMAGE("yourimage.jpg",50,800,450) && 50 pixel sized corners cut off the image first resized to 800x450 
Of course, any other size than 800x450, just as you need. That could be the size form.image1.width, form.image1.height, for example. This could be called in image.Init() and also adjust the image.Picture to be the new file. Again, the result image file is "yourimagerounded.png" in the same directory as "yourimage.jpg".

Caution! The function overwrites existing files. To cause no harm to your original files I built in to check whether the save file name differs from the original file name, also when you explicitly specify the same save file name. And that is another usage of the PRG in this syntax with full parameterization:

CODE

ROUNDEDEDIMAGE("yourimage.jpg",50,800,450,GETENV("TEMP")+"\yourimage.png") && as before, just explicitly using yourimage.png as result file name. 
This way you can also specify another path of the result file. You can store it anywhere else, as this example does by saving it into the %TEMP% system directory.

And, of course, the first parameter ideally also has file names including their paths. Otherwise, the GDI+ library may not find the file. I'm not sure it's even aware of VFPs default path. I mean the systems gdiplus.dll, not the VFP code in system.app You can try and then thank the System.app developers they take the default directory into account, I think.

You either put this PRG into your default path, a path in SET PATH or you SET PROCEDURE to it before using it.

And to round this post off, here's an image and rounded image I created with the function:


Original file public domain from https://unsplash.com/photos/nOsJYzXEG98

Chriss

RE: How to make edges of picture rounded?

It's fun to play around with paths. You could also get round edges, as you literally asked for.


(The path is not yet ideal, but to give an impression of how you could shape images)

Chriss

RE: How to make edges of picture rounded?

(OP)
oH EMMMM Geeeee Chris!!!! You're really amazing.... can i give 50 stars? Thank you so much... I really time to understand it well and able to use and eventually put it in my project.... Thanks and God bless....

RE: How to make edges of picture rounded?

You have to thank many others that provided GDIPlusX. I think Cesar Chalom started it. Though there also is a gdi+ library in VFP9 FFC classes, _gdiplus.vcx, Cesar Chalom and later other contributors made this whole add-on that enables easier use of the GDI+ features of the Windows API. In the end, it is "just" Windows itself used, but the API functions of GDI+ are very intertwined and it's not easy to start from scratch. And this library makes it easy to get at GDI+ features, use Bitmaps, Graphics, Brushes, Pens, Geometric figures, etc.

You might also like https://github.com/VFPX/FoxCharts based on GdiPlusX.

Chriss

Red Flag This Post

Please let us know here why this post is inappropriate. Reasons such as off-topic, duplicates, flames, illegal, vulgar, or students posting their homework.

Red Flag Submitted

Thank you for helping keep Tek-Tips Forums free from inappropriate posts.
The Tek-Tips staff will check this out and take appropriate action.

Reply To This Thread

Posting in the Tek-Tips forums is a member-only feature.

Click Here to join Tek-Tips and talk with other members! Already a Member? Login

Close Box

Join Tek-Tips® Today!

Join your peers on the Internet's largest technical computer professional community.
It's easy to join and it's free.

Here's Why Members Love Tek-Tips Forums:

Register now while it's still free!

Already a member? Close this window and log in.

Join Us             Close