Draw a Grid over a Picturebox in c# - c#

I am trying to make a tool in c# which allows the user to put a grid on the screen on a picturebox. At the moment i don't know how to do this, so when a button is clicked, the picturebox comes up with a grid. It needs to be a grid which is spaced out enough that users can find out locations of objects on the picture in the picturebox. Help with what code i can use to do this would be very helpful as i was going to use ControlPaint.DrawGrid but not sure of the values i need to put in it to get my desired effect?
Thanks

Form the Documentation od controlpaint.Drawgrid,
I suppose you need to decide on the cell size in x- amd y-direction and pass this as a size parameter to Drawgrid:
public static void DrawGrid(
Graphics graphics,
Rectangle area,
Size pixelsBetweenDots,
Color backColor
)
for example, a 100*200 pixels square grid would be generated by
setting graphcis to the context you want to draw upon,
Setting area to the top left right and bottom parameters of your image
setting size.x to 100 and size.y to 200
setting color to any color you like.
Update
Something like this should do.
Rectangle myRect = new System.drawings.Rectangle();
myRect.Location := new System.Drawing.Point(0,0);
myRect.Height = 50;
myRect.Width = 50;
Drawgrid(FromImage(yourImage), mygrid , yourImage.Size, System.Drawing.Color.Black);
Disclaimer: i don't develope in c#, so above code is not tested for anything. I just picked stuff from the documentation (msdn).

Related

Rectangle coordinates drawn on Image in Xamarin Forms

I am trying to get following usecase implemented in Xamarin forms
(Using with SFImageEditor from syncfusion but can try if other options)
Display an image in editor.
Display an initial rectangle.
User resizes the rectangle to best fit and clicks "go".
Need to Capture the coordinates of this rectangle in reference to the image.
Send the image and rectangle coordinates for further processing.
Can someone pls provide guidance on step 4 for identifying the coordinates of the rectangle.
(X Y height width) or (coordinates of 4 corners). Either format is fine.
Appreciate your help.
code to set SFImageEditor in Xamarin.Forms with Syncfusion.
Xaml code
<imageeditor:SfImageEditor x:Name="present_image" >
<imageeditor:SfImageEditor.ToolbarSettings>
<imageeditor:ToolbarSettings IsVisible="True" />
</imageeditor:SfImageEditor.ToolbarSettings>
</imageeditor:SfImageEditor>
code behind
public ImgEditPage( )
{
InitializeComponent();
var origImage = ImageSource.FromUri(
new Uri("https://xxx.xx/xxxxxx.jpg")); ;
present_image.Source = origImage;
}
This will open up the image in an editor window, The editor allows to draw a rectangle object.
User can click the button to draw rectangle I want to get the coordinates of the rectangle drawn by user.
We would like to let you know that the you can get the coordinates of the rectangle added on an image by using the Bounds property. On selecting a shape, ItemSelected event will be triggered. From this, you will get settings of selected shape with Bounds property. The value of the Bounds will be in percentage, the value of the shape frame should fall between 0 and 100. For more information, please refer the below link.
https://www.syncfusion.com/kb/8880/how-to-show-dimension-of-shapes-while-resizing
https://help.syncfusion.com/xamarin/image-editor/shapes#pensettings
You can get the actual bounds of the image rendered in SfImageEditor control using the property ActualImageRenderedBounds.
You can get the original image size by using the property of OriginalImageSize.

How to make graphics (Shape, animation) in c#

How to make a circle with text inside ?? then move it from one location to another, and then access it later (to delete it).
I want to make something like this
Your question is really very broad and you got a few nice links you should study to learn all about GDI+ drawing.
But if taken literally there is a slightly exotic alternative which puts the burdon of most chores onto the Chart control from DataVisualization.Charting.
You can create EllipseAnnotations and add them to a Chart control.
Disable the Axes and clear the Legends and then use code like this to add a moveable circle wit thext inside:
EllipseAnnotation ea = new EllipseAnnotation();
ea.X = 11; // put at..
ea.Y = 11; // 11% of the chart's area
ea.AllowMoving = true;
ea.BackColor = Color.BlanchedAlmond;
ea.Text = (chart1.Annotations.Count + 1) + "";
chart1.Annotations.Add(ea);
Note that there are quite a few annotation types available. which allow you to add Rectangles, Images, Polygons, Lines and pure Text.
And another pro is that saving or loading the graphics takes only one line each, as you can serialize a Chart out of the box!
:-)
GraphX for .NET is an advanced open-source graph layout and visualization library that supports different layout algorithms and provides many means for visual customizations It is capable of rendering large amount of vertices
https://github.com/panthernet/GraphX
To draw shapes follow here.Also you need a complete tut,you can follow here
Some insight is here:
To draw a simple shape at design time Drag the OvalShape or
RectangleShape control from the Visual Basic PowerPacks tab (to
install, see Visual Basic Power Packs Controls)in the Toolbox to a
form or container control.
Drag the sizing and move handles to size and position the shape. You
can also size and position the shape by changing the Size and Position
properties in the Properties window To create a rectangle with rounded
corners, select the CornerRadius property in the Properties window
and set it to a value that is greater than 0. In the Properties
window, optionally set additional properties to change the appearance
of the shape. To draw a simple shape at run time On the Project
menu, click Add Reference. In the Add Reference dialog box, select
Microsoft.VisualBasic.PowerPacks.VS, and then click OK. In the Code
Editor, add an Imports or using statement at the top of the module:
using Microsoft.VisualBasic.PowerPacks; Add the following code in an Event procedure:
ShapeContainer canvas = new ShapeContainer();
// To draw an oval, substitute
// OvalShape for RectangleShape.
RectangleShape theShape = new RectangleShape();
// Set the form as the parent of the ShapeContainer.
canvas.Parent = this;
// Set the ShapeContainer as the parent of the Shape.
theShape.Parent = canvas;
// Set the size of the shape.
theShape.Size = new System.Drawing.Size(200, 300);
// Set the location of the shape.
theShape.Location = new System.Drawing.Point(100, 100);
// To draw a rounded rectangle, add the following code:
theShape.CornerRadius = 12;
Customizing Shapes When you use the default settings, the OvalShape and RectangleShape controls are
displayed with a solid black border that is one pixel wide and a
transparent background. You can change the width, style, and color of
the border by setting properties. Additional properties enable you to
change the background of a shape to a solid color, a pattern, a
gradient fill, or an image. Before you change the background of a
shape, you should know how several of the properties interact. The
BackColor property setting has no effect unless the BackStyle property
is set to Opaque. If the FillStyle property is set to Solid, the
FillColor overrides the BackColor. If the FillStyle property is set to
a pattern value such as Horizontal or Vertical, the pattern will be
displayed in the FillColor. The background will be displayed in the
BackColor, provided that the BackStyle property is set to Opaque. In
order to display a gradient fill, the FillStyle property must be set
to Solid and the FillGradientStyle property must be set to a value
other than None. Setting the BackgroundImage property to an image
overrides all other background settings.
This SO link I found is also nice here

Redraw panel contents after ClientSizeChanged

So my application runs in fixed size window and in full screen. The problem I'm facing is how to properly scale the current contents of the panel (which depend on the application use) when the window is resized. This is my current code:
private void Form1_ClientSizeChanged(object sender, EventArgs e)
{
System.Drawing.Drawing2D.Matrix transformMatrix = new System.Drawing.Drawing2D.Matrix();
float px = panel2.Width;
float py = panel2.Height;
panel2.Width = this.Width / 2;
panel2.Height = panel2.Width;
panel2.Location = new Point(this.Width - panel2.Width - 30, 30);
transformMatrix.Scale(panel2.Width / px, panel2.Height / py);
panel2.Region.Transform(transformMatrix);
//Rest of the code
}
But the drawn content doesn't scale, and if I use Invalidate() or Refresh() the drawn content gets cleared (the panel is redrawn empty). What am I missing?
.NET doesn't remember what's drawn on the panel, as simple as that. As soon as anything invalidates the windows bitmap buffer (causing a WM_PAINT), it's going to be repainted again. So, you have to draw what you want to draw using the Paint event (or overriding OnPaint).
However, there is another way that might be easier to implement - don't paint into a Panel. Instead, paint into a PictureBox (or rather, a Bitmap assigned to the Image property of the PictureBox). The Bitmap will be reused when invalidating (and redrawing) the picture box, so nothing will be lost. By using PictureBox.ScaleMode, you can define how you want the picture box to scale the bitmap, and it will do so as well as it can.
In any case, transforming the Region property doesn't do anything useful - you're simply changing the region, not doing anything to the drawing itself. To use 2D transformation matrices, you want to apply them on a Graphics object during the drawing (in Paint handler or OnPaint override) - drawing anything on the Graphics object will then transform everything you're trying to draw, which in your case means scaling the painting.
So you have to decide: do you want to just scale a stored bitmap with the painted image, or do you want to redraw it all from scratch (which also means you can pick any level of detail you can provide)?
I think that you're mistaking what the Region property is meant for. According to the MSDN docs (empasis mine, replace 'window' with 'control' when reading):
The window region is a collection of pixels within the window where the operating system permits drawing. The operating system does not display any portion of a window that lies outside of the window region. The coordinates of a control's region are relative to the upper-left corner of the control, not the client area of the control.
All that you're doing is changing the region that the OS will allow painting, which explains why you're not seeing anything. I think that you should be resizing the control when the form is resized, either through Anchor, or through my preference of Dock with several controls, or a panel like TableLayoutPanel where it will handle scaling and relative sizing for you.
Thank you for your answers, but I wrote my own function and logic that serves the purpose for this application. Basically the function checks for the state of the application variables, and calls the appropriate function that originally drew the content, and since those functions use the panel width and height as arguments they properly scale the drawn content and retain the drawing composition.
P.S. I'll accept Luaan's answers since it offers a valid alternative and is complete.

ChartFX export chart cuts the borders

I have a problem with exporting a chart. I use the ChartFX chart with
chart.ExportImageSize = new Size(600, 450);
and if the size of the image is larger than this (1127, 537), it cuts the right and the bottom border in the exported image.
For exporting, I use simple
chart.Export(FileFormat.Bitmap);
No custom controls are used in exporting the chart, and the chart looks normal in the application (borders all around, and I use simple black border).
Few interesting things I realized trying to solve this.
First I have no border
chart.Border = new SimpleBorder(SimpleBorderType.None, cOffice2007BackColor);
Than, I add the new border object just to export the chart with the border.
chart.Border = new SimpleBorder(SimpleBorderType.Color, Color.Black);
chart.Export(FileFormat.Bitmap);
Than I revert the border. And, it exports the chart with the new border, but it doesn't resize the border. If it's larger than ExportImageSize, I see only left and top border, and if it's smaller, I get a part of the chart that goes outside the borders.
So, I set the the border to begin with, and only change the color for the exporting.
One more realization, explicitly setting the ExportImageSize can lead to some interesting side-effects. Even dough your plot looks really good, it sometimes cuts the legend, if it is to large

How do I get the dimensions of the ImageRectangle in PictureBox?

Background
I want to be able to get the drawn dimensions of a zoomed image inside the picturebox (I'll explain below).
The PictureBox.ImageRectangle property seems to be exactly what I'm looking for because it shows the height and width of the resized image, as well as it's relative top, left position inside the control.
The trouble is PictureBox.ImageRectangle is private and so I can't read the values without using reflection (which is obviously not ideal).
Actual Question
My question is, is there another way that I can easily get to these values without writing a method to calculate what the values "ought" to be? I can do that easily enough, but I feel I'd be reinventing the wheel.
Context:
I'm writing a simple image processing app in C# and one of the things it has to do is allow the user to draw a selection around a portion of the image (a lot like the Marquee tool in Photoshop).
I need to know the dimensions of the rendered image so I know where to set the bounds of my marquee tool and also to translate the values of the drawn rectangle to points on the scaled bitmap inside the control.
My answer look simple so maybe I'm missing something, but I think Control.DisplayRectangle suits your need.
EDIT
OK, missed the point; however see How to get the value of non- public members of picturebox?
if you want to access dimension of the image in picture box you can use
GraphicsUnit units = GraphicsUnit.Point;
RectangleF imgRectangleF = pictureBox1.Image.GetBounds(ref units);
Rectangle imgRectangle = Rectangle.Round(imgRectangleF);

Categories