Print out All images from bitmap Array in C# - c#

I've been trying to print Bitmap Array image in C# (each index image should print separate page)
The length of the array is defined while running the program
Bitmap creating code:
Bitmap[] bitm = new Bitmap[dataGridView1.RowCount]
This code I used to call print page event:
bitm[j].Save(#"Image/" + dataGridView2.Rows[j].Cells[0].Value.ToString() + "Term Report.jpg", ImageFormat.Jpeg);
pictureBox2.Image = bitm[j];
pictureBox2.Width = bitm[j].Width;
pictureBox2.Height = bitm[j].Height;
myPrintDocument2.PrintPage += new System.Drawing.Printing.PrintPageEventHandler(printDocument1_PrintPage);
myPrinDialog2.Document = myPrintDocument2;
if (myPrinDialog2.ShowDialog() == DialogResult.OK)
{
myPrintDocument2.Print();
}
Print document's print page event:
private void printDocument1_PrintPage(object sender, PrintPageEventArgs e)
{
pictureBox2.DrawToBitmap(myBitmap2, new Rectangle(0, 0, pictureBox2.Width, pictureBox2.Height));
e.Graphics.DrawImage(myBitmap2, new Rectangle(0, 0, pictureBox2.Width, pictureBox2.Height));
}
But it is displaying printdialog for each and every page. But I need all pages should print one printdialog!

Related

How to correctly print the created label?

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();
}
}

c# system.drawing how to print pdf to whole page size without blurr and losing quality

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

Printing PNG file on custom paper size

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);
}

How to print using multiple screenshots captured with copyfromscreen

I'm pretty new to C# but I finally have my first program up and running and I need to make it print. Its a window form with information and calculations on different tab controls, somewhat like Excel. The page that is currently being looked at prints fine with the copyfromscreen method, but I cannot get additional pages to print correctly. I have about 20 tabs I would like to be able to print at one time. I found a way to print the contents of controls into a textfile, but I would much prefer to be able to print what the form looks like. Thanks.
Bitmap memoryImage;
Bitmap memoryImage2;
private void CaptureScreen()
{
Graphics myGraphics = this.CreateGraphics();
Size s = tabControlMain.Size;
s.Width = s.Width + 20;
memoryImage = new Bitmap(s.Width, s.Height, myGraphics);
Graphics memoryGraphics = Graphics.FromImage(memoryImage);
memoryGraphics.CopyFromScreen(this.Location.X+15, this.Location.Y+80, 0, 0, s);
tabControlMain.SelectedIndex = 1;
memoryImage2 = new Bitmap(s.Width, s.Height, myGraphics);
Graphics memoryGraphics2 = Graphics.FromImage(memoryImage2);
memoryGraphics2.CopyFromScreen(this.Location.X + 15, this.Location.Y + 80, 0, 0, s);
}
private void printDocumentReal_PrintPage(System.Object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
e.Graphics.DrawImage(memoryImage, 0, 0);
e.Graphics.DrawImage(memoryImage2, 0, 550);
}
private void printToolStripButton_Click(object sender, EventArgs e)
{
CaptureScreen();
printDocumentReal.Print();
}
First, you should use PrintDocument and PrintPreviewDialog objects for print related tasks and an event handler for printing.
Second, you need to preform some optimization for your code, here's the solution:
private void printToolStripButton_Click(object sender, EventArgs e)
{
PrintDocument document = new PrintDocument();
document.PrintPage += new PrintPageEventHandler(document_PrintPage);
PrintPreviewDialog preview = new PrintPreviewDialog() { Document = document };
// you will be able to preview all pages before print it ;)
try
{
preview.ShowDialog();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message + "\nYou need to install a printer to preform print-related tasks!", "Print Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
Boolean firstPage = true;
private void document_PrintPage(object sender, PrintPageEventArgs e)
{
if (firstPage)
{
tabControlMain.SelectTab(0);
firstPage = false;
}
Graphics g = e.Graphics;
TabPage tab = tabControlMain.SelectedTab;
using (Bitmap img = new Bitmap(tab.Width, tab.Height))
{
tab.DrawToBitmap(img, tab.ClientRectangle);
g.DrawImage(img, new Point(e.MarginBounds.X, e.MarginBounds.Y)); // MarginBounds means the margins of the page
}
if (tabControlMain.SelectedIndex + 1 < tabControlMain.TabCount)
{
tabControlMain.SelectedIndex++;
e.HasMorePages = true;//If you set e.HasMorePages to true, the Document object will call this event handler again to print the next page.
}
else
{
e.HasMorePages = false;
firstPage = true;
}
}
I hope it's working fine with you And here's an additional one if you need to save all tabs as set of images on your hard disk:
public void RenderAllTabs()
{
foreach (TabPage tab in tabControlMain.TabPages)
{
tabControlMain.SelectTab(tab);
using (Bitmap img = new Bitmap(tab.Width, tab.Height))
{
tab.DrawToBitmap(img, tab.ClientRectangle);
img.Save(string.Format(#"C:\Tabs\{0}.png", tab.Text));
}
}
}
Try using DrawToBitmap method of TabPage instead:
private void CaptureScreen()
{
memoryImage = new Bitmap(tabControlMain.SelectedTab.Width, tabControlMain.SelectedTab.Height);
tabControlMain.SelectedTab.DrawToBitmap(memoryImage, tabControlMain.SelectedTab.ClientRectangle);
tabControlMain.SelectedIndex = 1;
memoryImage2 = new Bitmap(tabControlMain.SelectedTab.Width, tabControlMain.SelectedTab.Height);
tabControlMain.SelectedTab.DrawToBitmap(memoryImage2, tabControlMain.SelectedTab.ClientRectangle);
}
To get all the images of your TabPages, you can make a loop like this:
List<Bitmap> images = new List<Bitmap>();
private void CaptureScreen(){
foreach(TabPage page in tabControlMain.TabPages){
Bitmap bm = new Bitmap(page.Width, page.Height);
tabControlMain.SelectedTab = page;
page.DrawToBitmap(bm, page.ClientRectangle);
images.Add(bm);
}
}
//Then you can access the images of your TabPages in the list images
//the index of TabPage is corresponding to its image index in the list images

When I print bitmap, it eats up some of it

In my application i have a chart which is surrounded inside a panel. I added a printdocument component from the toolbox and when i want to print the chart, i am creating a bitmap and i get the panel inside the bitmap (and as a result the chart which is inside the panel). My problem is that when i create the bitmap, when i send it to the printer to print it, it eats up some of the chart from the bottom and from the right side. Below is my code to execute this
private void button1_Click(object sender, EventArgs e)
{
PrintDialog printDialog = new PrintDialog();
printDialog.Document = printDocument1;
printDialog.UseEXDialog = true;
//Get the document
if (DialogResult.OK == printDialog.ShowDialog())
{
printDocument1.DocumentName = "Test Page Print";
printPreviewDialog1.Document = printDocument1;
if (DialogResult.OK == printPreviewDialog1.ShowDialog())
printDocument1.Print();
}
}
This is the button to initialize the print_document. (I added a print preview so that i don't have to print it every time and spent paper and ink)
private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
Bitmap bm = new Bitmap(this.panel1.Width, this.panel1.Height);
this.panel1.DrawToBitmap(bm, new Rectangle(50, 50, this.panel1.Width + 50, this.panel1.Height + 50));
e.Graphics.DrawImage(bm, 0, 0);
}
I was thinking that maybe the chart is too big and it doesn't fit in the page but if i save the bitmap. it fits OK inside the page actually there is too much free space on the bottom and right side. (After the draw to bitmap function add
bm.Save(#"c:\LOAN_GRAPH.png");
instead of the draw image and the image is save in c:)
Anybody who can help me i would be truly thankful.
Its working.
I removed the panel and instead, i am creating the rectangle according to my chart.
Bitmap bm = new Bitmap(this.chart1.Width, this.chart1.Height);
this.chart1.DrawToBitmap(bm, new Rectangle(50, 50, this.chart1.Width + 50, this.chart1.Height + 50));
e.Graphics.DrawImage(bm, 0, 0);

Categories

Resources