I am using a PrintDocument to print a page. At one point I want to rotate the text 90 degrees and print it ie print text vertically. Any ideas ???
g.RotateTransform(90);
does not work for OnPaint.
When you call RotateTransform you will need to pay attention to where the coordinate system ends up. If you run the following code, the "Tilted text" will appear to the left of the left edge; so it's not visible:
e.Graphics.Clear(SystemColors.Control);
e.Graphics.DrawString("Normal text", this.Font, SystemBrushes.ControlText, 10, 10);
e.Graphics.RotateTransform(90);
e.Graphics.DrawString("Tilted text", this.Font, SystemBrushes.ControlText, 10, 10);
Since you have tilted the drawing surface 90 degrees (clock wise), the y coordinate will now move along the right/left axis (from your perspective) instead of up/down. Larger numbers are further to the left. So to move the tilted text into the visible part of the surface, you will need to decrease the y coordinate:
e.Graphics.Clear(SystemColors.Control);
e.Graphics.DrawString("Normal text", this.Font, SystemBrushes.ControlText, 10, 10);
e.Graphics.RotateTransform(90);
e.Graphics.DrawString("Tilted text", this.Font, SystemBrushes.ControlText, 10, -40);
By default the coordinate system has its origo in the top left corner of the surface, so that is the axis around which RotateTransform will rotate the surface.
Here is an image that illustrates this; black is before call to RotateTransform, red is after call to RotateTransform(35):
Related
Spiral:
I have coded squares in C# based on the Fibonacci series exactly as shown in the included image. The problem I am having is trying to draw the arcs. I am not sure if I should be using arcs, curves or bezier curves. I assume an arc is what I want, but I have been unable to get the results I am trying for.
If someone could show me an example of how to draw an arc from corner to corner within a square it would be very much appreciated. I just hard coded the squares for fun. I want to try to write an algorithm to generate them, but right now I am stumped by the behavior of the arcs.
Bitmap bmp = new Bitmap(50, 50);
using (Graphics g = Graphics.FromImage(bmp))
{
g.DrawArc(Pens.Black, new Rectangle(0, 0, 100, 100), 0, 90);
}
Parameters
Stroke color
Bounding box for the circle the arc would be part of
Starting angle (in degrees)
Ending angle (in degrees)
The arc is drawn clockwise from the starting arc. To do a counterclockwise arc, supply a negative value for the ending angle.
Bitmap bmp = new Bitmap(50, 50);
using (Graphics g = Graphics.FromImage(bmp))
{
g.DrawArc(Pens.Black, new Rectangle(0, 0, 100, 100), 0, 90);
}
It seems the bounding box must be twice the size of the square in order for the arc to go from corner to corner.
Curve
The "rectangle" is a square. The center of the arc is a corner, the radius is a side, the starting angle is a multiple of 90° and the sweep angle is 90°. No rocket science.
I have a colormap plot and want to apply mesh dimensions on the picture plot. This request was successfully done by using the following code:
// draw mesh pattern
Pen transPen = new Pen(Color.FromArgb(128, 150, 150, 150),2);
g.DrawRectangle(transPen, (float)X,
(float)Y,
(float)dx,
(float)dy);
// draw contour square (brush , x , y , dx , dy)
g.FillRectangle(myContourBrush,
(float)X,
(float)Y,
(float)dx,
(float)dy);
Now my question is : the first transparent rectangle are transparent just in border area or all rectangle area? I don't want to affect colormap color, I just want to have mesh pattern.
The DrawRectangle method only draws the edge. If you want to fill it, you must use FillRectangle. Take a look for yourself. You might have to zoom in quite a bit to notice the color change.
I've tried several methods here on stackoverflow, and the closest one is the following:
Border DesignBorder = new Border();
DesignBorder.BorderThickness = new System.Windows.Thickness(2.0);
DesignBorder.BorderBrush = Brushes.Black;
GeneralTransform transform = Selected.TransformToVisual(canvasDrawingArea);
Rect R = transform.TransformBounds(new Rect(0, 0, Selected.ActualWidth, Selected.ActualHeight));
DesignBorder.SetValue(Canvas.LeftProperty, R.Left);
DesignBorder.SetValue(Canvas.TopProperty, R.Top);
DesignBorder.SetValue(Canvas.WidthProperty, R.Width);
DesignBorder.SetValue(Canvas.HeightProperty, R.Height);
canvasDrawingArea.Children.Add(DesignBorder);
Selected is the image that has been rotated.
When the Image is rotated in increments of 90 degrees, everything looks great. However, at 45, 135, etc. degrees, the bounding box is not nearly close enough
picture link for 90 degrees
picture link for 45 degrees
Is this just the best that can be done? Or is there a way to improve the bounding box?
EDIT:
I thought it was working find for 90 degree rotates, but it only gave the appearance of working as the image I was working with was nearly a square. As soon as I put a more rectangular image in, it became obvious that 90 degree increments also do not work.
I've been looking all over SO today and I can't get anything to work for my needs.
I have a web application that let's users drag and drop text/images and then it sends the details to the server to draw those to a pdf. I'm trying to enable rotation, but I can't get a hold of the translatetransform stuff. My image in testing prints out great, rotated well, but it is not in the correct location. I'm missing how the intitial translatetransform changes things and my mind is shot at the end of the day. Do I have to draw this as a bitmap first using a different graphics instance, and then draw that bitmap to my background? Any help on this would be great! Thanks!
CODE:
i is the image object from the browser
coord is the x & y of the upper corner of the image on the canvas (990wx1100h) on the browser
size is the h & w of the element on the browser
Bitmap b = new Bitmap(wc.OpenRead(i.img));
if (i.rotation != 0)
{
g.TranslateTransform(this.CanvasDetails.size.width/2, this.CanvasDetails.size.height/2);
g.RotateTransform(i.rotation);
g.DrawImage(b, new Rectangle(- i.coord.x/2, -i.coord.y/2, i.size.width, i.size.height), 0, 0, b.Width, b.Height, GraphicsUnit.Pixel, ia);
}
else
{
g.DrawImage(b, new Rectangle(i.coord.x, i.coord.y, i.size.width, i.size.height), 0, 0, b.Width, b.Height, GraphicsUnit.Pixel, ia);
}
EDIT
I added the translatransform reversal as suggested by Adam, but the image is still drawn in a different location.
g.TranslateTransform(this.CanvasDetails.size.width / 2, this.CanvasDetails.size.height / 2);
g.RotateTransform(i.rotation);
g.TranslateTransform(-this.CanvasDetails.size.width / 2, -this.CanvasDetails.size.height / 2);
g.DrawImage(b, new Rectangle(-i.coord.x / 2, -i.coord.y / 2, i.size.width, i.size.height), 0, 0, b.Width, b.Height, GraphicsUnit.Pixel, ia);
Examples:
Browser View
.NET drawn version
Ok, completely reworking this answer to try to explain it clearer. A couple of things to know are that transformations 'accumulate' and rotation transforms happen around the origin. So to just explain the affect of accumulating (multiplying) transforms, look at this example:
//draw an ellipse centered at 200,200
g.DrawEllipse(Pens.Red, 195, 195, 10, 10);
//apply translate transform - shifts origin to 200,200
g.TranslateTransform(200, 200);
//draw another ellipse, should draw around first ellipse
//because translate tranforms essentially moves our coordinates 200,200
g.DrawEllipse(Pens.Blue, -7, -7, 14, 14);
//now do rotate transform
g.RotateTransform(90f); //degree to rotate object
//now, anything we draw with coordinates 0,0 is actually going to be draw at 200,200 AND be rotated by 45*
//this line will be vertical, through 200,200, instead of horizontal through 0,0
g.DrawLine(Pens.Green, -20,0,20,0);
//If we add another translate, this time 50x, it would normally translate by 50 in the X direction
//BUT - because we already have transforms applied, including the 90 rotate, it affects this translation
//so this in effect because a 50px translation in Y, because it's rotated 90*
g.TranslateTransform(50, 0);
//so even though we translated 50x, this line will draw 50px below the last line
g.DrawLine(Pens.Green, -20, 0, 20, 0);
So for your case, you want to draw an object Centered at CenterPoint and rotated by Angle. So you would do:
g.TranslateTransform(-CenterPoint.X, -CenterPoint.Y);
g.RotateTransform(Angle);
g.DrawImage(b, -ImageSize/2, -ImageSize/2, ImageSize, ImageSize);
You'd then need to reset the transforms for additional drawing, which you can do with:
g.ResetTransform();
If that doesn't leave the image where you want it, then you'll need to check the values you're using to position it. Are you storing it's center? Or top left? Etc.
I have a List<Point> of multiple points. How can I draw these points into a bitmap, to get the same as this:
http://img291.imageshack.us/img291/4462/outputtz.png
Points are known, I just need to achieve this gradient effect somehow.
Please note that the gradient isn't radial, if you untwist the polygonal line to a straight one, you would get simple linear gradient from one end to another. I just need this linear gradient twisted along the line's "breaking points".
My current solution is drawing each line separately, while calculating the proper start-color and end-color for each line, so I can use LinearGradientBrush and then DrawLine.
1) Is there any other solution, than calculating the colors myself?
2) How to draw a line with round ends (as on image)? My solution is by drawing ordinary line, with ellipse on each end, but those ellipses won't have gradient, so if the line is VERY short, there is no gradient.
About the rounded ends you can set this property for you Pen
Graphics g = e.Graphics;
Pen p = new Pen(Color.Brown, 15);
// round ends
p.StartCap = LineCap.Round;
p.EndCap = LineCap.Round;
g.DrawLine(p, 30, 80, Width - 50, 80);//can be replace with you code
so on your image you can change the canvas pen.