I am following the link to get the image cropped and rounded. However it does not work the way I want. I spent some time but did not understand where to fix the code to get what I want.
public Image CropToCircle(Image srcImage, PointF center, float radius, Color backGround)
{
Image dstImage = new Bitmap((int)Math.Round(Math.Ceiling(radius*2)), (int)Math.Round(Math.Ceiling(radius*2)), srcImage.PixelFormat);
using (Graphics g = Graphics.FromImage(dstImage))
{
RectangleF r = new RectangleF(center.X - radius, center.Y - radius, 2*radius, 2 * radius);
using (Brush br = new SolidBrush(backGround))
{
g.FillRectangle(br, 0, 0, dstImage.Width, dstImage.Height);
}
GraphicsPath path = new GraphicsPath();
path.AddEllipse(r);
g.SetClip(path);
g.DrawImage(srcImage, 0, 0);
return dstImage;
}
}
dstImage - should show the cropped image from main image at the given cursor position.
Above code works fine but output image location moves with X,Y coordinates. What I want is always show 100x100 square image from main image under the cursor position. (Like a lens moving on the image)
This is how I call the function
private void drawWindows(Point mousePoint)
{
Image RoundedImage = CropToCircle(StartImage, new PointF(mousePoint.X, mousePoint.Y), 75, Color.FromArgb(0, 101, 167));
PB.Image = RoundedImage;
}
I want to show the image under given location at the center of the image as follows:
But currently cropped image moves inside when I change the X,Y cordinates. I want the circular image to still be at center.
Where am I making the mistake? I feel like g.DrawImage(srcImage, 0, 0)
is likely the culprit.
Any ideas?
When you use a Control as the container for an Image and the Image is scaled to fit the container's bounds (e.g., setting a PictureBox.SizeMode to PictureBoxSizeMode.Zoom) so an Image can be shown in the UI with predefined measures, when you need to select a section of the Image, you need to calculate the scale factor. In other words, determine the ratio between the container's size and the Image real size.
It may be better to use the smaller container as reference, so you can then multiply instead of divide the relative measures by the scale ratio:
The position of the Lens inside the container - if you want the lens to follow the Mouse pointer's position - are give by the Pointer coordinates minus half of the lens size:
To determine the actual size of the Lens (the selection) dimension in relation to the actual size of the Bitmap, the Lens dimension must be scaled when a section of a Bitmap needs to be drawn or otherwise clipped:
Also, when showing the preview of the current selection represent by the Lens, the selection needs to be scaled to the size of the Container used to preview the Lens' selection:
These simple methods allows to calculate both the actual size of a selection in relation to the Image considered and also the size of Controls used for the preview.
When drawing the preview using the Lens selection, it can be a good idea to use a common method to draw the Image section: a method that can also be used to draw the selection in a new Bitmap, which can then be saved to disc or otherwise stored.
Here,
pctLens
is the PictureBox used for the preview,RectangleF section
is the Lens measure rescaled to thepctLens
size (for the preview) and of coursesourceImage
is the original Image:Visual result (Image:
1200x675
, PictureBox:300x175
,SizeMode: Zoom
)Complete source code to reproduce what is shown in the animation:
Bitmap sourceImage
is the original Bitmap, it must be set to an existing object.RectangleF imageLens
is the shape used to define the relative Lens size.Size lensPixelSize
is the size ofimageLens
in Pixels, relative to the UI representation.pctOriginal
is the PictureBox where the original Image is shown.pctLens
is the PictureBox where the Lens section preview is drawn.