How to zoom picturebox along with graphics - c#

I want to zoom picture box along with graphics.
this will Zoom the only image part not the graphics part.
public Image PictureBoxZoom(Image imgP, Size size)
{
Bitmap bm = new Bitmap(imgP, Convert.ToInt32(imgP.Width * size.Width), Convert.ToInt32(imgP.Height * size.Height));
Graphics grap = Graphics.FromImage(bm);
grap.InterpolationMode = InterpolationMode.HighQualityBicubic;
return bm;
}
private void zoomSlider_Scroll(object sender, EventArgs e)
{
if (zoomSlider.Value > 0 && img != null)
{
pictureBox1.SizeMode = PictureBoxSizeMode.CenterImage;
pictureBox1.Image = null;
pictureBox1.Image = PictureBoxZoom(img, new Size(zoomSlider.Value, zoomSlider.Value));
}
}
the source of image is:
img = Image.FromStream(openFileDialog1.OpenFile());
Picture is zooming but when we draw the rectangle outside image then it's not zooming along with image.
See image:

You can do this (rather) easily by scaling the e.Graphics object in the Paint event.. See here for an example!
So to work with you code you probably should add this to the Paint event:
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
g.ScaleTransform(zoom, zoom);
// now do your drawing..
// here just a demo ellipse and a line..
Rectangle rect = panel1.ClientRectangle;
g.DrawEllipse(Pens.Firebrick, rect);
using (Pen pen = new Pen(Color.DarkBlue, 4f)) g.DrawLine(pen, 22, 22, 88, 88);
}
To calculate the zoom factor you need to do a little calculation.
Usually you would not create a zoomed Image but leave that job to the PictureBox with a SizeMode=Zoom.
Then you could write:
float zoom = 1f * pictureBox1.ClientSize.Width / pictureBox1.Image.Width;
To center the image one usually moves the PictureBox inside a Panel. And to allow scrolling one sets the Panel to Autocroll=true;
But since you are creating a zoomed Image you should keep track of the current zoom by some other means.
Note:
But as you use PictureBoxSizeMode.CenterImage maybe your problem is not with the zooming after all?? If your issue really is the placement, not the size of the drawn graphics you need to do a e.Graphics.TranslateTransform to move it to the right spot..

Related

c# drawing, circle goes outside form

I am trying to draw a circle within my form.
But it is strange to me I set form width and height to a fixed number, i do the same for the circle, but the circle figure goes outside the form.
private void Form3_Paint(object sender, PaintEventArgs e)
{
this.SuspendLayout();
gr = this.CreateGraphics();
gr.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
Brush fill_circ3 = Brushes.Blue;
Pen ellipse_pen = new Pen(Color.Blue);
ellipse_pen.Width = (float)2.0;
this.Width = this.Height = 400;
Rectangle rect = new Rectangle(0, 0, this.Width, this.Height);
gr.DrawEllipse(ellipse_pen, rect);
this.ResumeLayout();
}
The 3rd and 4th parameters of the Rectangle constructor defines the size in width and height of the circle.
See the circle I got
Why does the circle goes outside the form???! I have set form and circle sizes the same!!!
It's because you use the Window size, not the "client" size. Just replace your code by this:
gr.DrawEllipse(ellipse_pen, this.ClientRectangle);
The client area of a control is the bounds of the control, minus the
nonclient elements such as scroll bars, borders, title bars, and
menus.

image getting blurred when enlarging picture box

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!

C# How to get pixel from stretched bitmap/picturebox

Okay, i have a pictureBox with an image, with a sizeMode set to: StretchImage,
Now, i want to get the pixel that i click. (bitmap.GetPixel(x,y)).
But when the image is streched from the normal size, i get the original pixel. as in the pixel that would be there before the strech(if that makes sense?)
My Code:
Private void pictureBox1_MouseUp(object sender, MouseEventArgs e) {
Bitmap img = (Bitmap)pictureBox1.Image;
var color = img.GetPixel(e.X, e.Y)
}
Thanks In Advance
There should be a way to compensate for the stretching factor induced by the picture box. I'm thinking about taking the stretched width and height from the picture box, and the width and height from the original image, computing a stretching factor, and multiplying these with the e.X and e.Y coordinates.
Maybe something like:
Bitmap img = (Bitmap)pictureBox1.Image;
float stretch_X = img.Width / (float)pictureBox1.Width;
float stretch_Y = img.Height / (float)pictureBox1.Height;
var color = img.GetPixel((int)(e.X * stretch_X), (int)(e.Y * stretch_Y));
Divide the e.X and e.Y with stretching factor. Here is the stretched image fills the entire picture box.
Bitmap img = (Bitmap)pictureBox1.Image;
float factor_x = (float)pictureBox1.Width / img.Width;
float factor_y = (float)pictureBox1.Height / img.Height;
var color = img.GetPixel(e.X / factor_x, e.Y / factor_y)
By doing so, we make sure that e.X and e.Y will not exceed the limits of the original image.
You could store the original image and leave that untouched. It would be easier than resizing the stretched image and getting the specified pixel afterwords. Make sure that e.X and e.Y don't go outside the bounds of the original bitmap.
private Bitmap _img;
public void LoadImage(string file) {
// Get the image from the file.
pictureBox1.Image = Bitmap.FromFile(file);
// Convert it to a bitmap and store it for later use.
_img = (Bitmap)pictureBox1.Image;
// Code for stretching the picturebox here.
// ...
}
private void pictureBox1_MouseUp(object sender, MouseEventArgs e) {
var color = _img.GetPixel(e.X, e.Y);
}
EDIT: Disregard. Maximilian's answer is better.

Image in PictureBox Become Blurry While Rotating

I am trying to rotate an image that is in side of a PictureBox in a C# WinForm. I rotate the image with every tick of the timer1 (Interval = 100). As I am rotating, however, the image becomes blurrier and blurrier. I am not sure if there is a way to fix this. I have enabled the Form to be double buffered.
Here is the code I am using:
public static Image RotateImage(Image img, float rotationAngle)
{
Bitmap bmp = new Bitmap(img.Width, img.Height);
bmp.SetResolution(img.HorizontalResolution, img.VerticalResolution);
Graphics gfx = Graphics.FromImage(bmp);
gfx.TranslateTransform((float)bmp.Width / 2, (float)bmp.Height / 2);
gfx.RotateTransform(-rotationAngle);
gfx.TranslateTransform(-(float)bmp.Width / 2, -(float)bmp.Height / 2);
gfx.DrawImage(img, new Point(0, 0));
gfx.Dispose();
return bmp;
}
private void timer1_Tick(object sender, EventArgs e)
{
Image bmp = Form1.RotateImage(pictureBox1.Image, 10);
pictureBox1.Image = bmp;
}
Consider keeping your original image around, and each time you rotate, calculate the new image by applying the cumulative rotation to the original image.
What you're seeing is an unavoidable consequence of the rotation, which can only approximate the original image given the finite number of pixels it has to work with. You're seeing approximations of approximations, and they'll just get worse each time you rotate.

Convert Image to Graphic in c#

How to convert Image to Graphic?
You can't convert a Graphics object into an image, as the Graphics object doesn't contain any image data.
The Graphics object is just a tool used to draw on a canvas. That canvas is typically a Bitmap object or the screen.
If the Graphics object is used for drawing on a Bitmap, then you already have the image. If the Graphics object is used for drawing on the screen, you would have to make a screen shot to get an image of the canvas.
If the Graphics object was created from a window control, you could use the control's DrawToBitmap method to render the control on an image instead of on the screen.
You need an Image in order to draw your Graphics on, so you probably already have the image:
Graphics g = Graphics.FromImage(image);
As Darin states, you probably already have the image. If you don't, you can create a new one and draw to that one
Image bmp = new Bitmap(width, height);
using (Graphics g = Graphics.FromImage(bmp)) {
// draw in bmp using g
}
bmp.Save(filename);
Save saves the image to a file on your hard drive.
If you're drawing directly on a Control's graphics, you can create a new Bitmap with the same dimensions as the control and then call Control.DrawToBitmap(). However, the better way to go is usually to start with a Bitmap, draw to its graphics (as suggested by Darin), and then paint the bitmap onto the Control.
The best method to turn graphics into a bitmap is to get rid of the 'using' stuff:
Bitmap b1 = new Bitmap(Screen.PrimaryScreen.Bounds.Width,Screen.PrimaryScreen.Bounds.Height);
Graphics g = Graphics.FromImage(b1);
g.CopyFromScreen(0, 0, Screen.PrimaryScreen.Bounds.X, Screen.PrimaryScreen.Bounds.Y, new Size(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height));
b1.Save("screen.bmp");
I discovered this while figuring out how to turn graphics into a bitmap, and it works like a charm.
I have some examples on how to use this:
//1. Take a screenshot
Bitmap b1 = new Bitmap(Screen.PrimaryScreen.Bounds.Width,Screen.PrimaryScreen.Bounds.Height);
Graphics g = Graphics.FromImage(b1);
g.CopyFromScreen(0, 0, Screen.PrimaryScreen.Bounds.X, Screen.PrimaryScreen.Bounds.Y, new Size(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height));
b1.Save("screen.bmp");
//2. Create pixels (stars) at a custom resolution, changing constantly like stars
private void timer1_Tick(object sender, EventArgs e)
{
/*
* Steps to use this code:
* 1. Create new form
* 2. Set form properties to match the settings below:
* AutoSize = true
* AutoSizeMode = GrowAndShrink
* MaximizeBox = false
* MinimizeBox = false
* ShowIcon = false;
*
* 3. Create picture box with these properties:
* Dock = Fill
*
*/
//<Definitions>
Size imageSize = new Size(400, 400);
int minimumStars = 600;
int maximumStars = 800;
//</Definitions>
Random r = new Random();
Bitmap b1 = new Bitmap(imageSize.Width, imageSize.Height);
Graphics g = Graphics.FromImage(b1);
g.Clear(Color.Black);
for (int i = 0; i <r.Next(minimumStars, maximumStars); i++)
{
int x = r.Next(1, imageSize.Width);
int y = r.Next(1, imageSize.Height);
b1.SetPixel(x, y, Color.WhiteSmoke);
}
pictureBox1.Image = b1;
}
With this code, you can use all the commands for the Graphics Class, and copy them to a bitmap, therefore allowing you to save anything designed with the graphics class.
You may use this to your advantage.

Categories