I am new to Dot Net, I want to print a rectangle with 20mm width and 8mm height exactly if I measure with scale. I also want to print text exactly in the middle of rectangle.Can anyone suggest me how can I achieve this?
I am really sorry for not being clear earlier. I have tried using "PageUnits" its working fine. However, I have problem with the margins.
I am able to print correct margins(8.8mm left and 22mm Top) if I am using the printer "HP LaserJet P2035n". If print using "Canon iR2020 PCL5e" I am getting incorrect margins(8.1mm left and 8.0mm Top) where I should get 8.8mm left and 22mm top margins. Can someone explain me where I am doing wrong.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Printing;
namespace ConsoleApplication6
{
class DrawShape
{
public static void DrawRec()
{
PrintDocument doc = new PrintDocument();
doc.PrintPage += doc_PrintPage;
doc.Print();
}
static void doc_PrintPage(object sender, PrintPageEventArgs e)
{
Graphics g = e.Graphics;
PageSettings PageSet = new PageSettings();
float MarginX = PageSet.PrintableArea.X;
float MarginY = PageSet.PrintableArea.Y;
float x = (float)(8.8-((MarginX/100)*25.4));
float y = (float)(22-((MarginY/100)*25.4));
g.PageUnit = GraphicsUnit.Millimeter;
g.DrawRectangle(Pens.Black, x, y, 20, 8);
}
}
}
You may want to start with this:
private void button1_Click(object sender, EventArgs e)
{
using (Graphics formGraphics = this.CreateGraphics())
{
formGraphics.PageUnit = GraphicsUnit.Millimeter;
formGraphics.DrawRectangle(Pens.Blue, 0, 0, 20, 80);
}
}
You can then using DrawString on the Graphics object to draw text inside your rectangle.
Related
I’m using WinForms. In my Form I got a picuturebox and 4 textboxes margin_top, margin_bottom, margin_left, and margin_right. I want to be able to create margins for the images at appear in the print preview dialog-box, but I also want to scale the image proportionately when I provide the margins. I also want the images to be enclosed in the print-preview-page, meaning not having the images cut-of. Another question, is why my image is cutting of when the print-preview page is the same size as my image? I used an 850 width by 1100 Height image and when I clicked print preview the image it got cut off without me having to re-size it.
Below is a link for an image you can test on.
http://www.filedropper.com/850x1100
Below is an image that not displaying correctly in the print-preview screen. It is missing its right and bottom borders.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Printing_Image_Center
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
pictureBox1.Image = new Bitmap(#"C:\Users\Bob\Pictures\850x1100.png");
}
private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
var img_width = e.PageBounds.Width - e.MarginBounds.Left - Math.Abs(e.MarginBounds.Right - e.PageBounds.Width);
var img_height = e.PageBounds.Height - e.MarginBounds.Top - Math.Abs(e.MarginBounds.Bottom - e.PageBounds.Height);
e.Graphics.DrawImage(ResizeAcordingToImage(pictureBox1.Image, img_width, img_height),
e.MarginBounds.Left, e.MarginBounds.Top);
}
private void Btn_Print_Click(object sender, EventArgs e)
{
printPreviewDialog1.Document = printDocument1;
//PrintDocument.OriginAtMargins = true;
printDocument1.DefaultPageSettings.Margins.Top = Convert.ToInt32(txt_Top.Text);
printDocument1.DefaultPageSettings.Margins.Left = Convert.ToInt32(txt_Left.Text);
printDocument1.DefaultPageSettings.Margins.Right = Convert.ToInt32(txt_Right.Text);
printDocument1.DefaultPageSettings.Margins.Bottom = Convert.ToInt32(txt_bottom.Text);
printPreviewDialog1.ShowDialog();
}
private Image ResizeAcordingToImage(Image Source, int boxWidth, int boxHeight)
{
Image resizedImage;
double dbl = (double)Source.Width / (double)Source.Height;
//set height of image to boxHeight and check if resulting width is less than boxWidth,
//else set width of image to boxWidth and calculate new height
if ((int)((double)boxHeight * dbl) <= boxWidth)
{
resizedImage = new Bitmap(Source, (int)((double)boxHeight * dbl), boxHeight);
}
else
{
resizedImage = new Bitmap(Source, boxWidth, (int)((double)boxWidth / dbl));
}
return resizedImage;
}
}
}
Please provide the values of img.width and img.height in your code to resolve the problem. This is the only thing that you were missing.
var img = ResizeAcordingToImage(pictureBox1.Image, img_width, img_height);
e.Graphics.DrawImage(img, e.MarginBounds.Left, e.MarginBounds.Top, img.Width, img.Height);
Here is your result after the changes:
This question already has answers here:
How to resize an Image C#
(16 answers)
Closed 8 years ago.
This is the code in form1 i'm using now.
I'm capturing the desktop window using a timer each second.
In the end i have a button click event and if i click on it, it will create animated gif file on my hard disk from all the saved gif files.
But when i'm loading/running the animated gif on internet explorer for example i see the animation on the whole screen even bigger so i need to use and move the scrollbars to see it all each time.
How can i save the desktop window but half size for example ?
Now on my hard disk i have about 100 gif files each one at size 380-407kb.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Drawing.Imaging;
using System.IO;
using unfreez_wrapper;
namespace CapturedDesktop
{
public partial class Form1 : Form
{
int screens;
string gifsdirectory;
UnFreezWrapper unfreez;
public Form1()
{
InitializeComponent();
unfreez = new UnFreezWrapper();
timer1.Enabled = false;
screens = 0;
gifsdirectory = #"C:\Temp\CapturedDesktop\";
}
private void CaptureScreenshot()
{
screens++;
screenshots(gifsdirectory + screens.ToString("D6") + ".gif");
}
public static void screenshots(string filename)
{
//Create a new bitmap.
var bmpScreenshot = new Bitmap(Screen.PrimaryScreen.Bounds.Width,
Screen.PrimaryScreen.Bounds.Height,
PixelFormat.Format32bppArgb);
// Create a graphics object from the bitmap.
var gfxScreenshot = Graphics.FromImage(bmpScreenshot);
// Take the screenshot from the upper left corner to the right bottom corner.
gfxScreenshot.CopyFromScreen(Screen.PrimaryScreen.Bounds.X,
Screen.PrimaryScreen.Bounds.Y,
0,
0,
Screen.PrimaryScreen.Bounds.Size,
CopyPixelOperation.SourceCopy);
// Save the screenshot to the specified path that the user has chosen.
bmpScreenshot.Save(filename, ImageFormat.Gif);
bmpScreenshot.Dispose();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void timer1_Tick(object sender, EventArgs e)
{
CaptureScreenshot();
}
private void AnimatedGifButton_Click(object sender, EventArgs e)
{
List<string> myGifList = new List<string>();
FileInfo[] fi;
DirectoryInfo dir1 = new DirectoryInfo(gifsdirectory);
fi = dir1.GetFiles("*.gif");
for (int i = 0; i < fi.Length; i++)
{
myGifList.Add(fi[i].FullName);
}
unfreez.MakeGIF(myGifList, gifsdirectory + "agif", 100, true);
}
}
}
I want to capture take screenshots of the whole desktop window but when displaying it to show it not so big.
You can change the size from here
public static void screenshots(string filename)
{
//Create a new bitmap.
var bmpScreenshot = new Bitmap(
(Screen.PrimaryScreen.Bounds.Width - 100),
(Screen.PrimaryScreen.Bounds.Height - 100),
PixelFormat.Format32bppArgb
);
// other code
}
This will create a Bitmap object which is 100px shorter than the screen.
You can change your screenshots function like this:
public static void screenshots(string filename)
{
//Create a new bitmap.
var bmpScreenshot = new Bitmap(Screen.PrimaryScreen.Bounds.Width,
Screen.PrimaryScreen.Bounds.Height,
PixelFormat.Format32bppArgb);
// Create a graphics object from the bitmap.
var gfxScreenshot = Graphics.FromImage(bmpScreenshot);
// Take the screenshot from the upper left corner to the right bottom corner.
gfxScreenshot.CopyFromScreen(Screen.PrimaryScreen.Bounds.X,
Screen.PrimaryScreen.Bounds.Y,
0,
0,
Screen.PrimaryScreen.Bounds.Size,
CopyPixelOperation.SourceCopy);
// Save the screenshot to the specified path that the user has chosen.
//bmpScreenshot.Save(filename, ImageFormat.Gif);
//bmpScreenshot.Dispose();
var bmpHalfSize = new Bitmap(Screen.PrimaryScreen.Bounds.Width / 2,
Screen.PrimaryScreen.Bounds.Height / 2,
System.Drawing.Imaging.PixelFormat.Format32bppArgb);
var g = Graphics.FromImage(bmpHalfSize);
g.DrawImage(bmpScreenshot, 0, 0, CInt(Screen.PrimaryScreen.Bounds.Width / 2), CInt(Screen.PrimaryScreen.Bounds.Height / 2));
bmpHalfSize.Save(filename, ImageFormat.Gif);
bmpHalfSize.Dispose();
bmpScreenshot.Dispose();
}
Just a quick note: when playing with Graphics is better adopt Using statement in order to provides a convenient syntax that ensures the correct use of IDisposable objects.
For example:
using (Graphics g = Graphics.FromImage(bmpHalfSize)) {
g.DrawImage(bmpScreenshot, 0, 0, CInt(Screen.PrimaryScreen.Bounds.Width / 2), CInt(Screen.PrimaryScreen.Bounds.Height / 2));
}
I am trying to use a picturebox and pick out 2 points(eyes in a photo). I would pick out the two points with g.DrawString where I will draw 2 different 'x'. The problem now is I am stuck as what if the user has placed the 'x' on a wrong position and I would like to adjust it. Is there any codes which will allow the g.DrawString 'x' to be able to be moved?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace Camera
{
public partial class CamDisplay : Form
{
public CamDisplay()
{
InitializeComponent();
this.pictureBox1.ImageLocation = #"C:\center90\center90(1).jpg";
}
bool MousedClicked = true;
bool MouseClicked2 = true;
private void pictureBox1_MouseClick(object sender, MouseEventArgs e)
{
base.OnMouseClick(e);
if (MousedClicked == true)
{
txtXaxis.Text = e.X.ToString();
txtYaxis.Text = e.Y.ToString();
MousedClicked = false;
using (Graphics g = Graphics.FromHwnd(pictureBox1.Handle))
{
using (Font myFont = new Font("Calibri", 8))
{
g.DrawString("X", myFont, Brushes.Red, new PointF(e.X, e.Y));
}
}
}
else if (MouseClicked2 == true)
{
txtRXaxis.Text = e.X.ToString();
txtRYaxis.Text = e.Y.ToString();
MouseClicked2 = false;
using (Graphics g = Graphics.FromHwnd(pictureBox1.Handle))
{
using (Font myFont = new Font("Calibri", 8))
{
g.DrawString("X", myFont, Brushes.Red, new PointF(e.X, e.Y));
}
}
}
else
{
MousedClicked = false;
MouseClicked2 = false;
}
}
private void CamDisplay_MouseEnter(object sender, EventArgs e)
{
pictureBox1.SizeMode = PictureBoxSizeMode.Zoom;
pictureBox1.Cursor = Cursors.Hand;
}
}
}
Your question is unclear. As I understand your problem you have two options:
If you are using your Graphics object to directly manipulate the BMP (ie. you DrawString directly to the bitmap) there is no way to "undo" a previous operation. You could instead keep a local copy of the original bitmap in memory, duplicate it to a second bitmap and perform the operations only on the copy, which is the one you show in your form. When you need to "undo" you just go back to the original copy.
Do not manipulate the bitmap directly, but instead perform your drawing operations in the OnPaint() event of the PictureBox. In that way you only draw to the screen, leaving the original Bmp intact. See example here: http://msdn.microsoft.com/en-us/library/b818z6z6%28v=vs.110%29.aspx
well how do you draw in C# using variables?
ive managed to draw some shapes but only when i hardcode in the lengths. i need to draw shapes using a trackbar to get the lengths.
public abstract class Shape
{
//private String shape;
private int length;
}
public virtual void setLength(int newLength)
{
this.length = newLength;
}
public virtual int getLength()
{
return length;
}
//public String getShape()
//{
// return shape;
//}
//abstract public double getLength(float length);
abstract public float getPerimeter(int length);
abstract public float getArea(int length);
only showing square class but this project also includes triangle and square.
using System;
using System.Drawing;
public class Square : Shape
{
private float perimeter, area;
public override float getPerimeter(int length)
{
perimeter = length*4;
return perimeter;
}
public override float getArea(int length)
{
area = length*length;
return area;
}
}
this is the class with all my event handlers
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace shapes
{
//private System.Windows.Forms.TrackBar trackBar1;
public partial class Form1 : Form
{
private Shape shape;
private int length = 0;
private int shapeL = 0;
public Form1()
{
InitializeComponent();
}
private void panel2_Paint(object sender, PaintEventArgs e)
{
}
private void menuStrip1_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
{
}
private void trackBar1_Scroll(object sender, EventArgs e)
{
label3.Text = "Length Slider: " + trackBar1.Value;
textBox1.Text = shape.getPerimeter(shape.getLength()).ToString("0.00");
textBox2.Text = shape.getArea(shape.getLength()).ToString("0.00");
textBox1.Refresh();
textBox2.Refresh();
length = trackBar1.Value;
shape.setLength(length);
}
private void onCircleClick(object sender, EventArgs e)
{
shape = new Circle();
//length = trackBar1.Value;
length = shape.getLength();
this.Refresh();
using (Graphics g = this.panel1.CreateGraphics())
{
Pen pen = new Pen(Color.Black, 2);
Graphics formGraphics;
formGraphics = this.panel1.CreateGraphics();
formGraphics.DrawEllipse(pen, 50, 50, length, length);
//g.DrawEllipse(pen, 100, 100, length, length);
}
}
private void onSquareClick(object sender, EventArgs e)
{
shape = new Square();
length = trackBar1.Value;
using (Graphics g = this.panel1.CreateGraphics())
{
Pen pen = new Pen(Color.Black, 2);
g.DrawRectangle(pen, 50, 50, length, length);
System.Windows.Forms.MessageBox.Show("lenght is: " + length);
}
}
private void onTriangleClick(object sender, EventArgs e)
{
shape = new Triangle();
length = trackBar1.Value;
using (Graphics g = this.panel1.CreateGraphics())
{
SolidBrush blueBrush = new SolidBrush(Color.Blue);
// Create points that define polygon.
Point point1 = new Point(50, 50);
Point point2 = new Point(50, 100);
Point point3 = new Point(100, 50);
Point[] curvePoints = { point1, point2, point3};
// Draw polygon to screen.
g.FillPolygon(blueBrush, curvePoints);
}
}
private void shapeToolStripMenuItem_Click(object sender, EventArgs e)
{
}
protected override void OnPaint(PaintEventArgs pe)
{
base.OnPaint(pe);
Pen pen = new Pen(Color.Black, 2);
Graphics g = pe.Graphics;
g = this.CreateGraphics();
g.DrawRectangle(pen, 50, 50, length, length);
}
private void OnPaint(object sender, PaintEventArgs e)
{
}
}
}
yes its very messy, as you can see ive tried various things.
whats the difference between the panel1_paint and onPaint?
as you can see im not too sure how to use eventhandlers, the onCircleClick is basically a menu item button but how do i activate a different eveenthandler(panel1_Paint) from another eventhandler(onCircleClick)?
do graphics need to drawn in a *_paint/OnPaint method? ive gotten mine to draw in just the normal panel.
next is whats the best course of action to get the trackbar value to the shape object and back again to the method? yes the data is being saved (i think) when i use displayMessage(shape.getLength) it displays the length and is usually one off.
whats the equilent to repaint() in java for c#? ive tried this.Refresh(); but it doesnt work itll draw the shape then makes it disappear.
am i writing my setters/getters properly? or should i use
public int X
{
get {return x;}
set {x = value;}
}
in java, graphics will draw on any panel, in c# does it need to be in a specific container?
this is very simple, lets say that you want to draw on panel2.
all you have to do is to write this inside your private void panel2_Paint(object sender, PaintEventArgs e) body.
{
e.Graphics.Clear(panel1.BackgroundColor);
int length = trackBar1.Value;
Pen pen = new Pen(Color.Black, 2);
e.Graphics.DrawRectangle(pen, 50, 50, length, length);
}
and whenever you want to refresh the drawing, you can call either panel2.Refresh() or panel2.Invalidate(). both would do the job.
note that if you did this, panel2 won't get cleared after drawing the shape as it happened with you before.
note also that the panel would flicker as you change the trackbar value. i know how to handle this, but i don't want to complicate the solution for now.
I am using a control paint event to draw graphic objects in my application. The sizes of all the object is stored with size unit of millimeters and therefore i use 'millimeter' as PageUnit for the graphic object. For some reason when i draw a shape with a DashStyle other than solid, it gets drawn in a very unexpected scale.
In the code example below I expect to see both lines being drawn one on top of the other, but what i get is the red dashed line being drawn elsewhere in larger scale.
Any idea what I am missing?
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication6
{
public partial class Form1 : Form
{
private Pen solidBlackPen = new Pen(Color.Black, 1);
private Pen dashedRedPen = new Pen(Color.Red, 1) {
DashStyle = DashStyle.Dash
};
private Point point1 = new Point(5, 5);
private Point point2 = new Point(35, 5);
public Form1()
{
InitializeComponent();
this.BackColor = Color.White;
this.Paint += new PaintEventHandler(Form1_Paint);
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.PageUnit = GraphicsUnit.Millimeter;
e.Graphics.DrawLine(solidBlackPen, point1, point2);
e.Graphics.DrawLine(dashedRedPen, point1, point2);
}
}
}
Since I am new i cant upload a screenshot.
After few tests this looks to me like some kind of bug that occures mybe only on specific Os/framework.
What managed to fix me this was adding the following line before drawing the shapes:
e.Graphics.ScaleTransform(1, 1);