Zoom to fit for drawing in Winforms Panel C# - c#

I have an app that will draw many shapes (rectangle, line and circle) on a panel.
the panel can zoom in and out this shapes.
What I'm trying to do is when the application is fired I need to have the shapes zoomed to fit the window.
How I can do that, I read a lot about defined Images but not shapes.
here is my snap shot
private void panel1_Paint(object sender, PaintEventArgs e)
{
SolidBrush brushs = new SolidBrush(Color.White);
e.Graphics.Clip = new Region(new Rectangle(0, 0, Viewer.Width, Viewer.Height));
e.Graphics.FillRegion(brushs, e.Graphics.Clip);
Graphics g = e.Graphics;
g.TranslateTransform(_ImgX, _ImgY);
g.ScaleTransform(_Zoom, _Zoom);
g.SmoothingMode = SmoothingMode.AntiAlias;
SolidBrush myBrush = new SolidBrush(Color.Black);
Pen p = new Pen(Color.Red);
foreach (CircuitData.ResistorRow resistorRow in ResistorData.Resistor)
{
RectangleF rec = new RectangleF((float)(resistorRow.CenterX - resistorRow.Length/ 2), (float)(resistorRow.CenterY - resistorRow.Width/ 2), (float)resistorRow.Length, (float)resistorRow.Width);
float orientation = 360 - (float)resistorRow.Orientation;
PointF center = new PointF((float)resistorRow.CenterX, (float)resistorRow.CenterY);
PointF[] points = CreatePolygon(rec, center, orientation);
if (!Double.IsNaN(resistorRow.HiX) && !Double.IsNaN(resistorRow.HiY))
{
g.FillEllipse(myBrush, (float)resistorRow.HiX - 2 , (float)resistorRow.HiY - 2, 4, 4);
g.DrawLine(p, new PointF((float)resistorRow.HiX , (float)resistorRow.HiY ), center);
}
g.FillPolygon(myBrush, points);
}
}
Thanks

Draw your shapes onto a Metafile. Its dimensions will be calculated automatically after it is created. At the end you can zoom it safely when you draw it onto the panel.
// the reference Graphics can be taken from your form, its size does not matter
Graphics refGraph = this.CreateGraphics();
IntPtr hdc = refGraph.GetHdc();
Metafile result = new Metafile(hdc, EmfType.EmfOnly, "Shapes");
using (var g = Graphics.FromImage(result))
{
// draw your shapes here (zooming is not necessary)
DrawShapes(g);
}
refGraph.ReleaseHdc(hdc);
refGraph.Dispose();
// use this metafile on the panel
return result;

Related

How to make a diagonal line divide two panels in C# WinForms?

this is my form and I'm trying to make it so the diagonal line in the middle divides the left and the right parts of my form evenly. The line is drawn in a separate panel, with a script instructing it where to position the line (also, the background of this panel was set to transparent). The left part of my form is another panel as well as the black part in the upper right corner. The login elements (the email and password fields, the register and sign-in buttons, etc) are attached to the form itself.
Image of the form when I run it
Image of the form in the editor
I tried adding other lines in the same place in the other panels but it still didn't look as I wanted it to because those panels were still overlapping despite the transparent background of the original panel with the line.
I don't know what to do, so help would be much appreciated ;)
If you want to divide the left and the right parts of the form evenly with the diagonal line in the middle, you can refer to the following code:
private void panel3_Paint(object sender, PaintEventArgs e)
{
base.OnPaint(e);
using (Graphics g = e.Graphics)
{
g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
var p = new Pen(Color.Red, 3);
var point1 = new Point(0, 0);
var point2 = new Point(panel3.Width, panel3.Height);
g.DrawLine(p, point1, point2);
}
}
You can change the color and size of the diagonal line in the code.
I would put this into an own user control. Afterwards you could set everything through ForeColor, BackgroundColor, Thickness and RightToLeft:
public class DiagonalSeparator : UserControl
{
private int thickness = 3;
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
using (Graphics g = e.Graphics)
{
g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
var p = new Pen(ForeColor, thickness);
var point1 = RightToLeft == RightToLeft.No ? new Point(0, 0) : new Point(Width, 0);
var point2 = RightToLeft == RightToLeft.No ? new Point(Width, Height) : new Point(0, Height);
g.DrawLine(p, point1, point2);
}
}
[DefaultValue(3)]
[Description("The thickness of the drawn line"), Category("Appearance")]
[Browsable(true), EditorBrowsable(EditorBrowsableState.Always)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public int Thickness
{
get
{
return thickness;
}
set
{
thickness = value;
Invalidate();
}
}
}
This control can then be used as any other control within the designer and you can check if the visualization works as expected.

Get pixel perfect zooming [duplicate]

I am developing an application for image processing. To zoom the image, I enlarge PictureBox. But after enlarging I get below image as result.
But I want result like below image
Here is my Code :
picturebox1.Size = new Size((int)(height * zoomfactor), (int)
(width* zoomfactor));
this.picturebox1.Refresh();
The PictureBox by itself will always create a nice and smooth version.
To create the effect you want you need to draw zoomed versions yourself. In doing this you need to set the
Graphics.InterpolationMode = InterpolationMode.NearestNeighbor;
Then no blurring will happen..
Example:
private void trackBar1_Scroll(object sender, EventArgs e)
{
Bitmap bmp = (Bitmap)pictureBox1.Image;
Size sz = bmp.Size;
Bitmap zoomed = (Bitmap)pictureBox2.Image;
if (zoomed != null) zoomed.Dispose();
float zoom = (float)(trackBar1.Value / 4f + 1);
zoomed = new Bitmap((int)(sz.Width * zoom), (int)(sz.Height * zoom));
using (Graphics g = Graphics.FromImage(zoomed))
{
if (cbx_interpol.Checked) g.InterpolationMode = InterpolationMode.NearestNeighbor;
g.PixelOffsetMode = PixelOffsetMode.Half;
g.DrawImage(bmp, new Rectangle( Point.Empty, zoomed.Size) );
}
pictureBox2.Image = zoomed;
}
Of course you need to avoid setting the PBox to Sizemode Zoom or Stretch!

Winforms Transformation

The current application am developing has lot of drawings. The Origin of the drawing start from Left,Bottom instead of Top,Left. Drawings works perfectly except "DrawingString".
Graphics g;
g.TranslateTransform(0, Height);
g.ScaleTransform(1, -1);
//All drawings
g.DrawString("1", new Font("Segoei UI", 9), Brushes.Green, new Point(x, y));
The result I get is upside down Text [![enter image description here][1]][1]
I wanted to draw only the text normal and rest of the drawings should always start from the bottom left?
EDIT
private void panel1_Paint(object sender,PaintEventArgs e)
{
var g = e.Graphics;
var height = panel1.Height;
g.TranslateTransform(0,height);
g.ScaleTransform(1,-1);
g.DrawRectangle(new Pen(Brushes.Black,1),new Rectangle(10,10,100,100));
g.DrawString("Test",new Font("Segoei UI",9),Brushes.Green,new Point(10,110));
}
RESULT
I want only the text to be flipped. Keeping the drawing as it is
Flip it over again.
See the example below. The text Sunday appears normally. Then we transpose the graphics object's matrix and write Monday, so Monday appears laterally inverted on the Y-axis, and finally we flip over the Y-axis yet again so it restores itself to its original state before writing Tuesday, which appears normally.
private void Form1_Paint(object sender, PaintEventArgs e)
{
var graphics = e.Graphics; // this.CreateGraphics();
var font = new Font("Georgia", 12.0F);
var brush = new SolidBrush(Color.Black);
var pointF = new PointF(20F, 20F);
graphics.DrawString("Sunday", font, brush, pointF);
graphics.ScaleTransform(1F, -1F);
pointF = new PointF(10F, -210F);
graphics.DrawString("Monday", font, brush, pointF);
graphics.ScaleTransform(1, -1);
pointF = new PointF(200F, 200F);
graphics.DrawString("Tuesday", font, brush, pointF);
brush.Dispose();
font.Dispose();
}
Do that in your code, making sure to calculate the value of the Y-axis where you want your text to appear.
g.ScaleTransform(1,-1);
g.DrawRectangle(new Pen(Brushes.Black,1),new Rectangle(10,10,100,100));
g.ScaleTransform(1,-1);
g.DrawString("Test",new Font("Segoei UI",9),Brushes.Green,new Point(10, -110));

Apply the opacity of a LinearGradientBrush to an image in winforms

I want to apply the opacity of a linear gradient to an image, but all I have been able to get is the gradient painted on top of the image.
Following this stackoverflow post, I created a user control that inherits from PictureBox and I overrode the OnPaint method
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
LinearGradientBrush linearGradientBrush = new LinearGradientBrush(
this.ClientRectangle,
Color.FromArgb(255, Color.White),
Color.FromArgb(0, Color.White),
0f);
e.Graphics.FillRectangle(linearGradientBrush, this.ClientRectangle);
}
However, that simply paints the linear gradient on top of the image.
How do I apply the opacity of the linear gradient to the image?
I find examples in XAML (), but not for winforms.
It is not necessary to use a user control and override the OnPaint event. Just create a graphics object from a blank image and do your image manipulation and assign the image to a PicturePox.
First draw the linearGradientBrush to the background and afterwards draw the image over it. Always take care about the sequence of your image operations.
FileInfo inputImageFile = new FileInfo(#"C:\Temp\TheSimpsons.png");
Bitmap inputImage = (Bitmap)Bitmap.FromFile(inputImageFile.FullName);
// create blank bitmap with same size
Bitmap combinedImage = new Bitmap(inputImage.Width, inputImage.Height);
// create graphics object on new blank bitmap
Graphics g = Graphics.FromImage(combinedImage);
// also use the same size for the gradient brush and for the FillRectangle function
LinearGradientBrush linearGradientBrush = new LinearGradientBrush(
new Rectangle(0,0,combinedImage.Width, combinedImage.Height),
Color.FromArgb(255, Color.White), //Color.White,
Color.FromArgb(0, Color.White), // Color.Transparent,
0f);
g.FillRectangle(linearGradientBrush, 0, 0, combinedImage.Width, combinedImage.Height);
g.DrawImage(inputImage, 0,0);
previewPictureBox.Image = combinedImage;
Result with black as the forms background color and the example image with transparency.
EDIT:
I may have misunderstood the intention, and either haven't found an easy way like in WPF, but it is not this much difficult.
FileInfo inputImageFile = new FileInfo(#"C:\Temp\TheSimpsons.png");
Bitmap inputImage = (Bitmap)Bitmap.FromFile(inputImageFile.FullName);
// create blank bitmap
Bitmap adjImage = new Bitmap(inputImage.Width, inputImage.Height);
// create graphics object on new blank bitmap
Graphics g = Graphics.FromImage(adjImage);
LinearGradientBrush linearGradientBrush = new LinearGradientBrush(
new Rectangle(0, 0, adjImage.Width, adjImage.Height),
Color.White,
Color.Transparent,
0f);
Rectangle rect = new Rectangle(0, 0, adjImage.Width, adjImage.Height);
g.FillRectangle(linearGradientBrush, rect);
int x;
int y;
for (x = 0; x < adjImage.Width; ++x)
{
for (y = 0; y < adjImage.Height; ++y)
{
Color inputPixelColor = inputImage.GetPixel(x, y);
Color adjPixelColor = adjImage.GetPixel(x, y);
Color newColor = Color.FromArgb(adjPixelColor.A, inputPixelColor.R, inputPixelColor.G, inputPixelColor.B);
adjImage.SetPixel(x, y, newColor);
}
}
previewPictureBox.Image = adjImage;

C#: Rectangles drawn with DrawRectangle on a non-primary monitor doesn't render top and left borders

I have a full screen form and in the handler for the Paint event I am drawing a 2px border around the entire form. I create one of these forms for each screen attached to the computer. For some reason, the top and left borders are not drawing on any non-primary monitors. The form's background covers the entire screen but I can't see to draw (using GDI) on area about 3px down from the top and 3px in from the left of the screen.
My Paint event handler code is below.
private void OnPaint(object sender, PaintEventArgs e)
{
using (Graphics g = this.CreateGraphics())
{
int border = 2;
int startPos = 0;
// offset used to correctly paint all the way to the right and bottom edges
int offset = 1;
Rectangle rect = new Rectangle(startPos, startPos, this.Width - border + offset, this.Height - border + offset);
Pen pen = new Pen(Color.Red, border);
// draw a border
g.DrawRectangle(pen, rect);
}
}
Has anyone seen this before?
Your code works Correct.
You should know when you are using this.Width or this.Height, these values calculating with the frame that surround your form.
For the Height, the height of your form controls added to calculated height.
You can using this code :
using (Graphics g = this.CreateGraphics())
{
int border = 2;
int startPos = 0;
// offset used to correctly paint all the way to the right and bottom edges
int offset = 1;
Rectangle rect = new Rectangle(startPos, startPos, this.Width-20, this.Height-40);
Pen pen = new Pen(Color.Red, border);
// draw a border
g.DrawRectangle(pen, rect);
}
UPDATE :
If you want to calculating exact size you can use this code :
int width,height;
public Form1()
{
InitializeComponent();
PictureBox pc = new PictureBox();
pc.Dock = DockStyle.Fill;
this.Controls.Add(pc);
pc.Visible = false;
width = pc.Width;
height = pc.Height;
pc.Dispose();
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
using (Graphics g = this.CreateGraphics())
{
int border = 2;
int startPos = 0;
// offset used to correctly paint all the way to the right and bottom edges
int offset = 1;
Rectangle rect = new Rectangle(startPos, startPos, width,height);
Pen pen = new Pen(Color.Red, border);
// draw a border
g.DrawRectangle(pen, rect);
}
}

Categories

Resources