I need to print a PNG file on a paper which its size is 10 cm x 15 cm. I'd like to know what I should customize in my code, the paper size property
pd1.PrinterSettings.PrinterName = printerName;
pd1.DocumentName = filePathS1;
pd1.OriginAtMargins = true;
pd1.DefaultPageSettings.PaperSize = new PaperSize("Etichetta", 394, 591);
or the rectangle during the PrintPage Event Handler?
void pd_PrintPage(object sender, PrintPageEventArgs e, string filePath)
{
Image image = Image.FromFile(filePath);
Rectangle rect = new Rectangle(0, 0, 393, 590);
e.Graphics.DrawImage(image, rect);
}
Related
I entered a number and generated a barcode. However, I can't print out the size I want from the printer. How can I adjust the dimensions of the label? I am using Godex G300 model printer.
Here is the code I tried :
private void GenerateBarcodeButton_Click(object sender, EventArgs e)
{
if (!String.IsNullOrEmpty(textBox1.Text))
{
Zen.Barcode.Code128BarcodeDraw barcodeDraw = Zen.Barcode.BarcodeDrawFactory.Code128WithChecksum;
pictureBox1.Image = barcodeDraw.Draw(textBox1.Text, 50);
}
else
MessageBox.Show("Please enter the barcode number you want to generate.");
}
public void PrintPicture(object sender, PrintPageEventArgs e)
{
Bitmap bmp = new Bitmap(pictureBox1.Width, pictureBox1.Height);
pictureBox1.DrawToBitmap(bmp, new Rectangle(0, 0, pictureBox1.Width, pictureBox1.Height));
e.Graphics.DrawImage(bmp, 0, 0);
bmp.Dispose();
}
private void Print_Click(object sender, EventArgs e)
{
PrintDialog pd = new PrintDialog();
PrintDocument pDoc = new PrintDocument();
pDoc.PrintPage += PrintPicture;
pd.Document = pDoc;
if (pd.ShowDialog() == DialogResult.OK)
{
pDoc.Print();
}
}
So a few things to consider (no short answer I'm sorry):
First (optionally) setting the media size of the paper or label in the printer (this can also be set in the Printer Defaults):
pDoc.DefaultPageSettings.PaperSize = new System.Drawing.Printing.PaperSize("Temp", System.Convert.ToInt32((pageSize.Height / (double)96) * 100), System.Convert.ToInt32((pageSize.Width / (double)96) * 100)); //Convert from 96dpi to 100dpi
Then when rendering your image you need to specify the width and height you want to scale and draw at:
e.Graphics.DrawImage(bmp, 0, 0, New System.Drawing.RectangleF(0, 0, width, height), System.Drawing.GraphicsUnit.Pixel)
HOWEVER
I recommend keeping your images original width to avoid blurring which can affect the quality of your barcode and potentially result in it being rejected if used in a commercial environment.
Instead generate a bigger image to begin with.
e.Graphics.DrawImage(bmp, 0, 0, New System.Drawing.RectangleF(0, 0, bmp.Width, bmp.Height), System.Drawing.GraphicsUnit.Pixel)
Lastly you need to consider the DPI of your printer which is 203 DPI
If you try and print a 96dpi image at 203dpi some pixels in your image will span a non-integer number of dots on the printer. When this happens label printers use a process called dithering which will either round partial pixels up/down or alternate rows of pixels to average out. This will result in the lines of your barcode being narrower/wider than they should be or lines with jagged edges.
To avoid this ensure your image DPI matches the DPI of your printer (or your printer DPI can be divided by your image DPI exactly)
Other solutions:
Communicate with the printer directly using a command language it supports (EZPL: https://www.godexprinters.co.uk/desktop/g300)
Buy label printing software such as CodeSoft or BarTender which you design your labels in and interface with in .NET by passing a label file path and set of variable data.
The following code works for me (Honeywell PM43c 203dpi) (note the use of GraphicsUnit.Pixel)
public Form1()
{
InitializeComponent();
pictureBox1.SizeMode = PictureBoxSizeMode.Normal;
pictureBox1.BackColor = Color.White;
}
private void GenerateBarcodeButton_Click(object sender, EventArgs e)
{
if (!String.IsNullOrEmpty(textBox1.Text))
{
pictureBox1.Image = Zen.Barcode.BarcodeDrawFactory.Code128WithChecksum.Draw(textBox1.Text, 50, 2);
}
else
{
MessageBox.Show("Please enter the barcode number you want to generate.");
}
}
public void PrintPicture(object sender, PrintPageEventArgs e)
{
Bitmap bmp = new Bitmap(pictureBox1.Width, pictureBox1.Height);
pictureBox1.DrawToBitmap(bmp, new Rectangle(0, 0, pictureBox1.Width, pictureBox1.Height));
e.Graphics.DrawImage(bmp, 20, 20, new System.Drawing.RectangleF(0, 0, bmp.Width, bmp.Height), System.Drawing.GraphicsUnit.Pixel);
}
private void PrintButton_Click(object sender, EventArgs e)
{
PrintDialog pd = new PrintDialog();
PrintDocument pDoc = new PrintDocument();
pDoc.PrintPage += PrintPicture;
pd.Document = pDoc;
if (pd.ShowDialog() == DialogResult.OK)
{
pDoc.Print();
}
}
I made a windows service that's runs in background service and listening for web app to order to print.
the web app send a pdf file and width and height of the printer paper with count of copies
I wrote the code this way
convert pdf to image
public Image ConverPdfToImage(IFormFile pdfFile)
{
if (pdfFile == null || pdfFile.Length==0)
{
return null;
}
var documemt = new Spire.Pdf.PdfDocument();
documemt.LoadFromStream(pdfFile.OpenReadStream());
Image image = documemt.SaveAsImage(0,PdfImageType.Bitmap);
return image;
}
then the event handler
private void PrintPage(object sender, PrintPageEventArgs ev,Image img)
{
Rectangle pageBounds = ev.PageBounds;
int x = pageBounds.Left - (int) ev.PageSettings.HardMarginX;
int y = pageBounds.Top - (int) ev.PageSettings.HardMarginY;
int width = pageBounds.Width;
int height = pageBounds.Height;
ev.Graphics.CompositingQuality = CompositingQuality.HighQuality;
ev.Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
ev.Graphics.SmoothingMode = SmoothingMode.HighQuality;
ev.Graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
local = new Rectangle(x, y, width, height);
ev.Graphics.FillRectangle(Brushes.Transparent, local);
ev.Graphics.DrawImage(img, local);
}
and the final function that prints
PrintDocument printDocument = new PrintDocument();
printDocument.PrinterSettings.PrinterName = form.Printer;
printDocument.DefaultPageSettings.Landscape = form.Landscape;
printDocument.DefaultPageSettings.PrinterSettings.Copies = form.Count;
printDocument.DefaultPageSettings.PaperSize =GetPaperSize(form.Width, form.Height);
printDocument.DefaultPageSettings.Margins = new Margins(0, 0, 0, 0);
Image img = ConverPdfToImage(form.PrintFile);
printDocument.PrintPage += (sender, args) => this.PrintPage(sender,args,img);
printDocument.Print();
the printDocument is from System.Drawing
It makes correct size in printer
printer are for lables and they have label papers with custom size
but the printed paper is blur and hard to read
some of it is so messed up and dirty
glad to help me make print sharp and good quality
I'm using WinForms. In my form I have a picturebox I use to display image documents. The problem is when I crop the image and then print the document out the image becomes slightly distorted. If I don't crop the image document and print it regularly the image document does not become distorted.
How do I crop and print the image documents without them being distorted?
Or is there a better way to code this so it can crop and print without the image document being distorted? If so, how can i do it?
Notes:
My picturebox is set to Zoom because the images i work with is big:
Example of image document Dimensions: 2500 x 3100
My picturebox does not have a border
int _cropX, _cropY, _cropWidth, _cropHeight;
public Pen _cropPen;
private State _currentState;
private enum State
{
Crop
}
private void Open_btn_Click(object sender, EventArgs e)
{
// open file dialog
OpenFileDialog open = new OpenFileDialog();
if (open.ShowDialog() == DialogResult.OK)
{
// display image in picture box
pictureBox1.Image = new Bitmap(open.FileName);
}
}
private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
try
{
if (Crop_Checkbox.Checked == true)
{
Cursor = Cursors.Default;
if (_currentState == State.Crop)
{
if (_cropWidth < 1)
{
return;
}
Rectangle rect = new Rectangle(_cropX, _cropY, _cropWidth, _cropHeight);
//First we define a rectangle with the help of already calculated points
Bitmap originalImage = new Bitmap(pictureBox1.Image, pictureBox1.Width, pictureBox1.Height);
//Original image
Bitmap img = new Bitmap(_cropWidth, _cropHeight);
// for cropinf image
Graphics g = Graphics.FromImage(img);
// create graphics
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
//set image attributes
g.DrawImage(originalImage, 0, 0, rect, GraphicsUnit.Pixel);
pictureBox1.Image = img;
pictureBox1.Width = img.Width;
pictureBox1.Height = img.Height;
}
}
else
{
Cursor = Cursors.Default;
}
}
catch (Exception)
{
}
}
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (Crop_Checkbox.Checked == true)
{
if (_currentState == State.Crop)
{
Cursor = Cursors.Cross;
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
//X and Y are the coordinates of Crop
pictureBox1.Refresh();
_cropWidth = e.X - _cropX;
_cropHeight = e.Y - _cropY;
pictureBox1.CreateGraphics().DrawRectangle(_cropPen, _cropX, _cropY, _cropWidth, _cropHeight);
}
}
}
else
{
Cursor = Cursors.Default;
}
}
private void Crop_Checkbox_CheckedChanged(object sender, EventArgs e)
{
if (Crop_Checkbox.Checked == true)
{
this.Cursor = Cursors.Cross;
}
}
private void Print_btn_Click(object sender, EventArgs e)
{
System.Drawing.Printing.PrintDocument myPrintDocument1 = new System.Drawing.Printing.PrintDocument();
PrintDialog myPrinDialog1 = new PrintDialog();
myPrintDocument1.PrintPage += new System.Drawing.Printing.PrintPageEventHandler(printDocument1_PrintPage);
myPrinDialog1.Document = myPrintDocument1;
if (myPrinDialog1.ShowDialog() == DialogResult.OK)
{
myPrintDocument1.Print();
}
}
private void printDocument1_PrintPage(object sender, PrintPageEventArgs e)
{
e.Graphics.DrawImage(pictureBox1.Image, 10, 10); //(Standard paper size is 850 x 1100 or 2550 x 3300 pixels)
}
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
if (Crop_Checkbox.Checked == true)
{
if (_currentState == State.Crop)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
Cursor = Cursors.Cross;
_cropX = e.X;
_cropY = e.Y;
_cropPen = new Pen(Color.FromArgb(153, 180, 209), 3); //2 is Thickness of line
_cropPen.DashStyle = DashStyle.DashDotDot;
pictureBox1.Refresh();
}
}
}
else
{
Cursor = Cursors.Default;
}
}
Test: Slightly Distorted:
Test: Not Distorted:
Test:
The picture above is a test. This is what happened when i took the below code out from pictureBox1_MouseUp:
Bitmap originalImage = new Bitmap(pictureBox1.Image, pictureBox1.Width, pictureBox1.Height);
And edited/replaced (originalImage to pictureBox1.Image):
g.DrawImage(pictureBox1.Image, 0, 0, rect, GraphicsUnit.Pixel);
Bitmap originalImage = new Bitmap(pictureBox1.Image, pictureBox1.Width, pictureBox1.Height);
That is most likely where the problem started. This can cause pictureBox1.Image to be rescaled to force-fit it to the pictureBox1 size. Depends on whether the picturebox has borders and its SizeMode property value. Rescaling causes the image to be resampled, the color of a pixel in the new bitmap is calculated from the values of its neighboring pixels in the original image as directed by the selected InterpolationMode.
This in effect blurs the resulting image. That works well on a photo but this is text that critically depends on anti-aliasing pixels to look decent on a low-resolution monitor. Slight changes to those pixels ruins the effect and they no longer smoothly blend the letter shape against the background anymore. They become more visible, best way to describe it is that the resulting text looks "fat".
I see no obvious reason to do this at all in the posted code. Delete the statement and replace originalImage with pictureBox1.Image.
Also beware that printing this image is likely to be disappointing. Now those anti-aliasing pixels get turned into 6x6 blobs of ink on paper. That only ever looks good when you have long arms. As long as the font size is this small and you have no control over the anti-aliasing choice then there's very little you can do about that. Printed text only ever looks good when you use PrintDocument and Graphics.DrawString().
I have written the below code for printing data from DataGridView in windows c#.
But I want to print one image, text in header and footer.
private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
Bitmap bm = new Bitmap(this.SalesGridView.Width, this.SalesGridView.Height);
SalesGridView.DrawToBitmap(bm, new Rectangle(0, 0, this.SalesGridView.Width, this.SalesGridView.Height));
e.Graphics.DrawImage(bm, 0, 0);
}
private void btnPrint_Click(object sender, EventArgs e)
{
printDocument1.Print();
}
Your code as is currently conversation your DataGridView to a Bitmap, and then prints that Bitmap. To print text headers and footers in addition to your DataGridView, you need the Graphics.DrawString() method:
// Create string to draw.
String drawString = "Sample Text";
// Create font and brush.
Font drawFont = new Font("Arial", 16);
SolidBrush drawBrush = new SolidBrush(Color.Black);
// Create point for upper-left corner of drawing.
PointF drawPoint = new PointF(150.0F, 150.0F);
// Draw string to screen.
e.Graphics.DrawString(drawString, drawFont, drawBrush, drawPoint);
}
You will have to adjust the float values for the positioning of each graphic. E.g. your code e.Graphics.DrawImage(bm, 0, 0); prints the Bitmap bm at position (0, 0). So the placement of your header, footer, and DataGridView object positions will need to be changed depending on their size.
If you want to print on multiple pages, you will need to create a loop and add your header and footer to each page programmatically.
This picture shows the problem
See the full sized picture at http://i.stack.imgur.com/kKqe0.jpg
Every pixel that should show a higher brightness resp. whose r, g or b values come close to 255 turns into pink or green.
The most promising filter I found is the EuclideanColorFiltering by Aforge. But it is inverted, ie it only shows the pink & green.
There is presumably a pattern in the picture that can be translated back into the right color.
The question is: how do I make the picture look the way it should look like, ie blue skyes are blue etc. using Aforge's filters or how do I translate the colors back properly?
This is the code I am currently using:
private void Form1_Load(object sender, EventArgs e)
{
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
string path = openFileDialog1.FileName;
// create video source
videoSource = new VideoFileSource(path);
// set NewFrame event handler
videoSource.NewFrame += new NewFrameEventHandler(video_NewFrame);
// start the video source
videoSource.Start();
}
}
private void video_NewFrame(object sender, NewFrameEventArgs eventArgs)
{
Bitmap bitmap = eventArgs.Frame;
EuclideanColorFiltering filter = new EuclideanColorFiltering();
// set center colol and radius
filter.CenterColor = new RGB(215, 30, 30);
filter.Radius = 100;
// apply the filter
filter.ApplyInPlace(bitmap);
if (pictureBox1.Image != null)
pictureBox1.Image.Dispose();
pictureBox1.Image = bitmap.Clone(new Rectangle(0, 0, bitmap.Width, bitmap.Height), System.Drawing.Imaging.PixelFormat.Format24bppRgb);
//pictureBox1.Image = bitmap;
// process the frame
}