I have two PictureBoxes pbOriginal and pbFace. After Selecting a "face" from an image in pbOriginal I clone the rectangle selection and place it into pbFace.
However, Because pbOriginal is using SelectionMode=Stretch the actual area being copied is not the same as the area being selected.
How do I convert the coordinates of the Rectangle so that they truly reflect the coordinates of the Stretched Image?
Here is an example that draws the second rectangle right along as you draw the first one..:
Point mDown = Point.Empty;
Point mCurr = Point.Empty;
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{ mDown = e.Location; }
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{ mCurr = e.Location; pictureBox1.Invalidate(); }
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
Rectangle r = new Rectangle(mDown.X, mDown.Y, mCurr.X - mDown.X, mCurr.Y - mDown.Y);
e.Graphics.DrawRectangle(Pens.Orange, r);
pictureBox2.Invalidate();
}
private void pictureBox2_Paint(object sender, PaintEventArgs e)
{
if (pictureBox2.Image == null) return;
float stretch1X = 1f * pictureBox1.Image.Width / pictureBox1.ClientSize.Width;
float stretch1Y = 1f * pictureBox1.Image.Height / pictureBox1.ClientSize.Height;
int x = (int)(mDown.X * stretch1X);
int y = (int)(mDown.Y * stretch1Y);
int x2 = (int)(mCurr.X * stretch1X);
int y2 = (int)(mCurr.Y * stretch1Y);
Rectangle r = new Rectangle(x, y, x2 - x, y2 - y);
e.Graphics.DrawRectangle(Pens.Orange, r);
}
Note that it assumes that you are drawing top-left to bottom-right..
If you want to copy the selection you can use the same factors and the same Rectangle as the source for a DrawImage call:
float stretch1X = 1f * pictureBox1.Image.Width / pictureBox1.ClientSize.Width;
float stretch1Y = 1f * pictureBox1.Image.Height / pictureBox1.ClientSize.Height;
Point pt = new Point((int)(mDown.X * stretch1X), (int)(mDown.Y * stretch1Y));
Size sz = new Size((int)((mCurr.X - mDown.X) * stretch1X),
(int)((mCurr.Y - mDown.Y) * stretch1Y));
Rectangle rSrc = new Rectangle(pt, sz);
Rectangle rDest= new Rectangle(Point.Empty, sz);
Bitmap bmp = new Bitmap(sz.Width, sz.Height);
using (Graphics G = Graphics.FromImage(bmp))
G.DrawImage(pictureBox1.Image, rDest, rSrc , GraphicsUnit.Pixel);
pictureBox2.Image = bmp;
You may want to code the MouseUp event to store the finla mCurr position and trgger the copying..
Related
I need to get the location of the cursor relative to pictureBox1, not the Windows Form itself.
My current code is returning the location relative to the form, and not pictureBox1.
This is an issue as I am using that point to draw graphics on the image in the Picture box, and due to the different relative locations, it is causing the graphics to overlay at an offset depending on how much the image on the pictureBox1 is scaled, etc.
My current code for getting the cursor location and drawing (simplified to reduce lines and is all in the one forms c# code):
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
lastPoint = e.Location;
mouseDown = true;
}
private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
lastPoint = e.Location;
mouseDown = false;
}
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (mouseDown == true && lastPoint != null)
{
using (Graphics g = Graphics.FromImage(pictureBox1.Image))
{
g.DrawLine(pen, lastPoint, e.Location);
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
}
pictureBox1.Invalidate();
lastPoint = e.Location;
}
}
Here is a demo of the issue (GIF):
I'd greatly appreciate some help.
Thanks very much,
Darcy.
Experimented a bit with scaling the location. Following code seems to work but i still expect some problems. I presumably mixed up x,y height,width somewhere. Just push the e.Location through this everytime you need the location relative to the image .
I used Sizemode = Zoom for this.
private Point GetScaledImageLocation(Point location)
{
double imgWidth = pictureBox1.Image.Width;
double imgHeight = pictureBox1.Image.Height;
double boxWidth = pictureBox1.Size.Width;
double boxHeight = pictureBox1.Size.Height;
double X = location.X;
double Y = location.Y;
double scale;
if (imgWidth / imgHeight > boxWidth / boxHeight)
{
scale = boxWidth / imgWidth;
double blankPart = (boxHeight - scale * imgHeight) / 2;
Y -= blankPart;
}
else
{
scale = boxHeight / imgHeight;
double blankPart = (boxWidth - scale * imgWidth) / 2;
X -= blankPart;
}
X /= scale;
Y /= scale;
return new Point((int)Math.Round(X), (int)Math.Round(Y));
}
I need to draw a Fermat spiral in C#. I did it, but I want my drawing to be filled in PictureBox, no matter how big real size is.
public void DrawSpiral(double delta, double numCycles, int oX, int oY, SpiralType spiralType, Color color, Graphics g)
{
double a = Convert.ToInt32(textBox1.Text);
Pen p = new Pen(color, 1);
double prevX = oX;
double prevY = oY;
double X = oX;
double Y = oY;
double fi = Convert.ToInt32(textBox2.Text);
double radius = 0;
while (fi <= (numCycles * 360))
{
fi += delta;
if (spiralType == SpiralType.FermaPlus)
{
radius = a * Math.Sqrt(fi);
}
else if (spiralType == SpiralType.FermaMinus)
{
radius = -a * Math.Sqrt(fi);
}
prevX = X;
prevY = Y;
X = (radius * Math.Cos(fi / 180 * Math.PI)) + oX;
Y = (radius * Math.Sin(fi / 180 * Math.PI)) + oY;
g.DrawLine(p, (float)prevX, (float)prevY, (float)X, (float)Y);
}
}
private void DrawButton_Click(object sender, EventArgs e)
{
pictureBox1.Refresh();
Graphics g = pictureBox1.CreateGraphics();
DrawSpiral(2, 5, 150, 150, SpiralType.FermaPlus, Color.Blue, g);
DrawSpiral(2, 5, 150, 150, SpiralType.FermaMinus, Color.Red, g);
}
So, what should I do to have my drawing to be full filled in the PictureBox.
Here is one way to do it:
Change the signature of the DrawSpiral to include the ClientSize of the PictureBox instead of some center coordinates:
public void DrawSpiral(double delta, double numCycles, int spiralType,
Color color, Graphics g, Size sz)
Then calculate the center dynamically:
int oX = sz.Width / 2;
int oY = sz.Height / 2;
double prevX = oX;
double prevY = oY;
double X = oX;
double Y = oY;
Next calculate the factor a :
a = sz.Width / 2 / Math.Sqrt( numCycles * 360);
Finally call the method only from the Paint event, passing out the valid Graphics object:
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
Size sz = pictureBox1.ClientSize;
DrawSpiral(2, 5, SpiralType.FermaPlus, Color.Blue, g, sz);
DrawSpiral(2, 5, SpiralType.FermaMinus, Color.Red, g, sz);
}
Upon resizing the PictureBox it will still fill the area with the same number of loops..:
A few notes:
The quality and performance could be improved by first collecting the data in a List<Point> pointsand then using DrawLines(pen, points.ToArray())
I used just the width when I calculated the factor a. Use Math.Min(sz.Width, sz.Height) to always fit it into a non-square box!
I left your offset calculation in place; but you could instead do a g.TranslateTransform()..
The PictureBox will Invalidate/Refresh itself upon resizing. If you change any parameters do call Invalidate to pick them up!
I am working on a project for school, we need to make a basic top down race game in C# without using XNA.
First of all let me tell you that the stuff we have learned about programming so far has little to do with making something that even remotely looks like a racegame. It didn't get any more difficult than array's, loops etc.
So we didn't learn about graphics or anything like that.
Having said all that I am having the following problem.
We have created a Graphics object, and then use DrawImage and use a bitmap from a car.jpg.
graphics = e.Graphics;
graphics.RotateTransform(angle);
graphics.DrawImage(car, xPos, yPos, car.Width, car.Height);
Then we wait for a key press e.g Right
case Keys.Right:
if (angle != 360)
{
angle += 10;
}
else
{
angle = 0;
}
this.Refresh();
break;
The problem we have is that the pivot point for the rotation is in the top left corner. So as soon as we move the car to something like (20,25) and start to rotate it, it will use (0,0) as the center of rotation. What we want to achieve is to have the center point of rotation at the center of our car.
We have tried looking for ways to change the centerX and centerY of the RotateTransform but have come to the conclusion that this isn't possible with the bitmap.
We have been struggling with this problem for over 2 days and can't seem to find any solution for achieving the thing we want.
Is there something we are doing wrong creating the Graphics object, or is there a totally different way to change centerX and centerY for the car?
To draw a rotated Bitmap you need to do a few steps to prepare the Graphics object:
first you move its origin onto the midpoint of the rotation
then you rotate by the desired angle
next you move it back
now you can draw the Bitmap
finally you reset the Graphics
This needs to be done for each bitmap.
Here are the steps in code to draw a Bitmap bmp at position (xPos, yPos):
float moveX = bmp.Width / 2f + xPos;
float moveY = bmp.Height / 2f+ xPosf;
e.Graphics.TranslateTransform(moveX , moveY );
e.Graphics.RotateTransform(angle);
e.Graphics.TranslateTransform(-moveX , -moveY );
e.Graphics.DrawImage(bmp, xPos, yPos);
e.Graphics.ResetTransform();
There is one possible complication: If your Bitmap has different dpi resolution than the screen i.e. than the Graphics you must first adapt the Bitmap's dpi setting!
To adapt the Bitmapto the usual 96dpi you can simply do a
bmp.SetResolution(96,96);
To be prepared for future retina-like displays you can create a class variable you set at startup:
int ScreenDpi = 96;
private void Form1_Load(object sender, EventArgs e)
{
using (Graphics G = this.CreateGraphics()) ScreenDpi = (int)G.DpiX;
}
and use it after loading the Bitmap:
bmp.SetResolution(ScreenDpi , ScreenDpi );
As usual the DrawImage method uses the top left corner of the Bitmap. You may need to use different Points for the rotation point and possibly also for the virtual position of your car, maybe in the middle of its front..
Here is static class which will paint the image in desired location within desired area. Change the rotationangle value to rotate the image. And you can also pan and zoom the image.
Add this class in your Project and call the static functions from Win Form.
public static class FullImage
{
public static Image image;
public static RectangleF DisplayRect, SourceRect;
public static Size ParentBoundry;
public static float rotationangle=0;
internal static void Paint(Graphics graphics)
{
if (image == null)
return;
float hw = DisplayRect.X + DisplayRect.Width / 2f;
float hh = DisplayRect.Y + DisplayRect.Height / 2f;
System.Drawing.Drawing2D.Matrix m = graphics.Transform;
m.RotateAt(rotationangle, new PointF(hw, hh), System.Drawing.Drawing2D.MatrixOrder.Append);
graphics.Transform = m;
graphics.DrawImage(image, new RectangleF(DisplayRect.X, DisplayRect.Y, DisplayRect.Width, DisplayRect.Height), SourceRect, GraphicsUnit.Pixel);
graphics.ResetTransform();
}
public static void LoadImage(Image img)
{
image = img;
SizeF s = GetResizedSize(image, ParentBoundry);
SourceRect = new RectangleF(0, 0, image.Width, image.Height);
DisplayRect = new RectangleF(ParentBoundry.Width / 2 - s.Width / 2, ParentBoundry.Height / 2 - s.Height / 2, s.Width, s.Height);
}
public static Size GetResizedSize(Image ImageToResize, Size size)
{
int sourceWidth = ImageToResize.Width;
int sourceHeight = ImageToResize.Height;
float nPercent = 0;
float nPercentW = 0;
float nPercentH = 0;
nPercentW = ((float)size.Width / (float)sourceWidth);
nPercentH = ((float)size.Height / (float)sourceHeight);
if (nPercentH < nPercentW)
nPercent = nPercentH;
else
nPercent = nPercentW;
int destWidth = (int)(sourceWidth * nPercent);
int destHeight = (int)(sourceHeight * nPercent);
return new Size(destWidth, destHeight);
}
internal static void MouseWheel(int delta)
{
if (delta > 0)
DisplayRect = ZoomImage(DisplayRect,CurrentMouse, .1f);
else
DisplayRect = ZoomImage(DisplayRect, CurrentMouse, -.1f);
}
private RectangleF ZoomImage(RectangleF ImageRectangle, PointF MouseLocation, float ScaleFactor)
{
/// Original Size and Location
SizeF OriginalSize = ImageRectangle.Size;
PointF OriginalPoint = ImageRectangle.Location;
///Mouse cursor location -located in width% and height% of totaloriginal image
float mouse_widthpercent = System.Math.Abs(OriginalPoint.X - MouseLocation.X) / OriginalSize.Width * 100;
float mouse_heightpercent = System.Math.Abs(OriginalPoint.Y - MouseLocation.Y) / OriginalSize.Height * 100;
///Zoomed Image by scalefactor
SizeF FinalSize = new SizeF(OriginalSize.Width + OriginalSize.Width * ScaleFactor, OriginalSize.Height + OriginalSize.Height * ScaleFactor);
if (FinalSize.Width < 15 || FinalSize.Height < 15)
return ImageRectangle;
if (FinalSize.Width > 60000 || FinalSize.Height > 60000)
return ImageRectangle;
/// How much width increases and height increases
float widhtincrease = FinalSize.Width - OriginalSize.Width;
float heightincrease = FinalSize.Height - OriginalSize.Height;
/// Adjusting Image location after zooming the image
PointF FinalLocation = new System.Drawing.PointF(OriginalPoint.X - widhtincrease * mouse_widthpercent / 100,
OriginalPoint.Y - heightincrease * mouse_heightpercent / 100);
ImageRectangle = new RectangleF(FinalLocation.X, FinalLocation.Y, FinalSize.Width, FinalSize.Height);
return ImageRectangle;
}
static bool drag = false;
static Point Initial, CurrentMouse;
internal static void MouseMove(Point location)
{
CurrentMouse = location;
if (drag)
{
DisplayRect = new RectangleF(DisplayRect.X + location.X - Initial.X, DisplayRect.Y + location.Y - Initial.Y, DisplayRect.Width, DisplayRect.Height);
Initial = location;
}
}
internal static void MouseDown(Point location)
{
Initial = location;
drag = true;
}
internal static void MouseUp(Point location)
{
drag = false;
}
}
After Adding this code in your project (Better add in separate cs file), Call the functions from Win Form class (Form1.cs).
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.DoubleBuffer, true);
this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
this.SetStyle(ControlStyles.ResizeRedraw, true);
FullImage.ParentBoundry = new Size(this.Width, this.Height);
// Enter the image path
FullImage.LoadImage(Image.FromFile(#"D:\a.jpg"));
}
//Create a paint event
private void Form1_Paint(object sender, PaintEventArgs e)
{
FullImage.Paint(e.Graphics);
}
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
Vault.FullImage.MouseDown(e.Location);
this.Invalidate();
}
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
Vault.FullImage.MouseMove(e.Location);
this.Invalidate();
}
private void Form1_MouseUp(object sender, MouseEventArgs e)
{
Vault.FullImage.MouseUp(e.Location);
this.Invalidate();
}
protected override void OnMouseWheel(MouseEventArgs e)
{
Vault.FullImage.MouseWheel(e.Delta);
this.Invalidate();
}
Now, if you want to rotate the image, just set the value however you want (with slider, button or add some more functions to detect the mouse movement and then rotate)
Example: add a button and each time the button clicked increase the value by 1.
private void button1_clicked(object sender, EventArgs e)
{
FullImage.rotationangle++;
this.invalidate();
}
To rotate the top left from the center you first need to know the angle of it then adjust it by the angle you want and re-calculate the new top left by the new angle:
var newXPos = (int)(xPos + car.Width / 2.0 + Math.Cos(Math.Atan2(-car.Height / 2, -car.Width / 2)
+ angle / 180.0 * Math.PI) * -car.Width / 2.0);
var newYPos = (int)(yPos + car.Height / 2.0 + Math.Sin(Math.Atan2(-car.Height / 2, -car.Width / 2)
+ angle / 180.0 * Math.PI) * -car.Height / 2.0);
graphics = e.Graphics;
graphics.RotateTransform(angle);
graphics.DrawImage(car, newXPos, newYPos, car.Width, car.Height);
I am creating a screenshot maker/uploader and everything works great but now i wanna intergrate something like paint. So first i am creating the pencil function. But there starts the problems i can draw :D but not on the position of my mouse. He takes other position then my cursor?
So the question is:
Hoe to get the mouse positions on a zoomed picturebox?
My code:
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (draw && pencil)
{
Graphics panel = Graphics.FromImage(ScreenShot);
Pen pen = new Pen(Color.Black, 14);
pen.EndCap = LineCap.Round;
pen.StartCap = LineCap.Round;
panel.DrawLine(pen, pX, pY, e.X, e.Y);
pictureBox1.CreateGraphics().DrawImage(ScreenShot, pictureBox1.Width, pictureBox1.Height);
pictureBox1.Invalidate();
}
Point p = pictureBox1.PointToClient(Cursor.Position);
pX = p.X;
pY = p.Y;
}
When using the mouse on a zoomed image the reported pixels are the zoomed coordinates. So we need to get at the real pixels..
After setting up things somehow..
float pbZoom = 3f; // the factor by which the PictureBox is zoomed in or out
pictureBox.SizeMode = PictureBoxSizeMode.Zoom;
pictureBox.ClientSize = new Size((int)(pictureBox.Image.Width * pbZoom),
(int)(pictureBox.Image.Height * pbZoom));
pictureBox.Paint += pictureBox_Paint;
pictureBox.MouseDown += pictureBox_MouseDown;
pictureBox.MouseMove += pictureBox_MouseMove;
pictureBox.MouseUp += pictureBox_MouseUp;
.. you can write the events to draw onto or into the zoomed image.
First a helper function to undo the zoom for a point:
PointF unZoomed(PointF pt) { return new PointF(pt.X / pbZoom, pt.Y / pbZoom );}
For simplicity lets keep a few things at class level:
PointF mDown = PointF.Empty; // mouse down point
PointF mCurrent = PointF.Empty; // current mouse location
We start each mouse event by calculating the unzoomed e.Location.
Our test draws a straight, moving red line on the surface until you release the mouse. Then that line is drawn into the Image in green.
The MouseDown simply stores the starting point, unzoomed:
void pictureBox_MouseDown(object sender, MouseEventArgs e)
{
mDown = unZoomed(e.Location);
}
In the MouseMove we store the current point and trigger the Paint event:
void pictureBox_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.None) return;
PointF e_ = unZoomed(e.Location);
mCurrent = e_;
pictureBox.Invalidate();
}
In the MouseUp we draw the line into the Image of the PictureBox, changing its pixels; then we set the Image and reset the points:
void pictureBox_MouseUp(object sender, MouseEventArgs e)
{
Bitmap bmp = (Bitmap) pictureBox.Image;
using (Graphics G = Graphics.FromImage(bmp))
{
G.SmoothingMode = SmoothingMode.HighQuality;
G.DrawLine(Pens.Green, mDown, mCurrent);
}
mDown = PointF.Empty;
mCurrent = PointF.Empty;
pictureBox.Image = bmp;
}
To draw onto the Control surface we use the Paint event. To draw scaled we use a Matrix..:
void pictureBox_Paint(object sender, PaintEventArgs e)
{
Matrix scaleMatrix = new Matrix();
scaleMatrix.Scale(pbZoom, pbZoom);
e.Graphics.MultiplyTransform(scaleMatrix);
e.Graphics.DrawLine(Pens.Red, mDown, mCurrent);
}
I also working with zoom image. I simply use this code, it's working. So you can just compare with bitmap (original image) before zoomed in/out.
private void pbInput_MouseMove(object sender, MouseEventArgs e) {
if (pbInput.Image == null) {
mouseY.Text = "";
mouseX.Text = "";
}
else {
Bitmap b = new Bitmap(pbInput.Image);
int x = b.Width * e.X / pbInput.Width;
int y = b.Height * e.Y / pbInput.Height;
mouseX.Text = x.ToString();
mouseY.Text = y.ToString();
}
}
this.Cursor = new Cursor(Cursor.Current.Handle);
Size size1 = pictureBox1.Image.Size;
Size size2 = pictureBox1.Size;
float x1 = (float)size1.Width / ((float)size2.Width + 1);
float y1 = (float)size1.Height / ((float)size2.Height + 1);
float divisor = x1 >= y1 ? x1 : y1;
divisor = divisor > 0 ? divisor : 1;
Size imagesize = new Size((int)(size1.Width / divisor), (int)(size1.Height / divisor));
int ex = imagesize.Width - size2.Width >= 0 ? imagesize.Width - size2.Width : size2.Width - imagesize.Width;
int ey = imagesize.Height - size2.Height >= 0 ? imagesize.Height - size2.Height : size2.Height - imagesize.Height;
float ftx = ((float)size1.Width / (float)imagesize.Width) * ((float)(Cursor.Position.X - this.Location.X - pictureBox1.Location.X - (ex / 2) - 8));
float fty = ((float)size1.Height / (float)imagesize.Height) * ((float)(Cursor.Position.Y - this.Location.Y - pictureBox1.Location.Y - (ey / 2) - 31));
Point LOP = new Point(Convert.ToInt32(ftx), Convert.ToInt32(fty)); //point of cursos on picturebox image pixel ...
I am trying to use the combination of the timer class and a codeproject to rotate an image smoothly in a picture box control (Visual Studio 2010 C#). The problem I am having is either the picture doesn't rotate or I get a threading exception. Something about "the object is in use elsewhere". Here's the main parts of the code, I would greatly appreciate any help you can provide. Thank you.
private void Form1_Load(object sender, EventArgs e)
{
timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
timer.Start();
}
private void timer_Elapsed(object sender, EventArgs e)
{
//Graphics graphic = Graphics.FromImage(pictureBox1.Image);
//graphic.RotateTransform(45);
this.Invoke(new MethodInvoker(delegate { RotateImage(pictureBox1.Image, 10); }));
}
public static Bitmap RotateImage(Image image, float angle)
{
// center of the image
float rotateAtX = image.Width / 2;
float rotateAtY = image.Height / 2;
bool bNoClip = false;
return RotateImage(image, rotateAtX, rotateAtY, angle, bNoClip);
}
public static Bitmap RotateImage(Image image, float angle, bool bNoClip)
{
// center of the image
float rotateAtX = image.Width / 2;
float rotateAtY = image.Height / 2;
return RotateImage(image, rotateAtX, rotateAtY, angle, bNoClip);
}
public static Bitmap RotateImage(Image image, float rotateAtX, float rotateAtY, float angle, bool bNoClip)
{
int W, H, X, Y;
if (bNoClip)
{
double dW = (double)image.Width;
double dH = (double)image.Height;
double degrees = Math.Abs(angle);
if (degrees <= 90)
{
double radians = 0.0174532925 * degrees;
double dSin = Math.Sin(radians);
double dCos = Math.Cos(radians);
W = (int)(dH * dSin + dW * dCos);
H = (int)(dW * dSin + dH * dCos);
X = (W - image.Width) / 2;
Y = (H - image.Height) / 2;
}
else
{
degrees -= 90;
double radians = 0.0174532925 * degrees;
double dSin = Math.Sin(radians);
double dCos = Math.Cos(radians);
W = (int)(dW * dSin + dH * dCos);
H = (int)(dH * dSin + dW * dCos);
X = (W - image.Width) / 2;
Y = (H - image.Height) / 2;
}
}
else
{
W = image.Width;
H = image.Height;
X = 0;
Y = 0;
}
//create a new empty bitmap to hold rotated image
Bitmap bmpRet = new Bitmap(W, H);
bmpRet.SetResolution(image.HorizontalResolution, image.VerticalResolution);
//make a graphics object from the empty bitmap
Graphics g = Graphics.FromImage(bmpRet);
//Put the rotation point in the "center" of the image
g.TranslateTransform(rotateAtX + X, rotateAtY + Y);
//rotate the image
g.RotateTransform(angle);
//move the image back
g.TranslateTransform(-rotateAtX - X, -rotateAtY - Y);
//draw passed in image onto graphics object
g.DrawImage(image, new PointF(0 + X, 0 + Y));
return bmpRet;
}
I think you should invalidate and paint in you OnPaint or OnDraw event
private void timer_Elapsed(object sender, EventArgs e)
{
//Graphics graphic = Graphics.FromImage(pictureBox1.Image);
//graphic.RotateTransform(45);
// this.Invoke(new MethodInvoker(delegate { RotateImage(pictureBox1.Image, 10); }));
pictureBox1.Invalidate();
}
In your form you should enable this styles for a better perfomance and smoothness
SetStyle( ControlStyles.ResizeRedraw, true );
SetStyle( ControlStyles.UserPaint, true );
SetStyle( ControlStyles.AllPaintingInWmPaint, true );
SetStyle( ControlStyles.OptimizedDoubleBuffer, true );