Getting started with manipulating print meta-data - c#

When sending a document, lets say TIFF images to a printer we can send meta-data with the image such as the paper size "Legal, Photo etc". The printer is able to use this information to select a paper tray matching this paper size.
I have a program that generates a tif document and uses PrintDocument to generate a Print job. This process occurs programmatically (no UI). Is it possible to alter the metadata of the tif image programmatically before I send the job to the printer?
E.G. I want to change the paper size of the image to "Legal". This way I can tell the printer which tray to use. I have explored generating an XPS document out of the TIF. Then going back through a XPS API to set the property. However, this solution feels a little heavy. I hope for someone with more experience in this type of programming to point me in the right direction.

The paper size option is available in PrintDocument
private void SetPaperSize()
{
int legalPaperIndex = 5;//See all types: http://msdn.microsoft.com/en-us/library/system.drawing.printing.papersize.rawkind.aspx
for (int i = 0; i < printDocument.PrinterSettings.PaperSizes.Count - 1; i++)
{
if (printDocument.PrinterSettings.PaperSizes[i].RawKind == legalPaperIndex)
{
printDocument.DefaultPageSettings.PaperSize = printDocument.PrinterSettings.PaperSizes[i];
}
}
}

Related

Poor image quality when converting word docs with evo pdf

I use the WordToPdfConverter from evo to convert a Word document to a PDF. The Word document, which is in RTF format, contains images such as a QR code.
Unfortunately, the image quality in the resulting PDF is very poor (hence the QR code won't be readable). Even if I disable image compression or set it to the lowest level (=> best quality), the resulting image has a very poor quality.
Is there any other way to control the image quality? Or is there a way to tell evo's WordToPdfConverter not to use JPG as the resulting image format but to stuck with the source format (e.g. PNG)?
var pdfConverter = new WordToPdfConverter();
// Set Pdf image options
pdfConverter.PdfDocumentOptions.JpegCompressionEnabled = false;
pdfConverter.PdfDocumentOptions.JpegCompressionLevel = 0;
var filename = #"C:\temp\evo\TestWordDoc.rtf";
pdfConverter.ConvertWordFileToFile(filename, Path.Combine(Path.GetDirectoryName(filename), $"{Path.GetFileNameWithoutExtension(filename)}_{DateTime.Now:yyyyMMddHHmmss}.pdf"));
Since RTF is a text format, you should convert it to PDF without having to do any image compression as that will take longer to process and will result in a larger output file + you might have issues with the image quality from embedded images.
I created a sample RTF file (test.rtf) that contains a QR code as you described:
I then took the RTF and ran it through the Document Converter from the Leadtools.Document.sdk Nuget. Just as a disclaimer: I am associated with this library.
This document converter preserves the text and parses the images as-is from the source document, then outputs it to PDF.
You can download the output PDF from here: test.pdf
Here is some sample code:
using (var documentConverter = new DocumentConverter())
{
var filename = #"C:\temp\evo\TestWordDoc.rtf";
var document = DocumentFactory.LoadFromStream(filename, new LoadDocumentOptions());
var jobData = DocumentConverterJobs.CreateJobData(filename, Path.Combine(Path.GetDirectoryName(filename), $"{Path.GetFileNameWithoutExtension(filename)}_{DateTime.Now:yyyyMMddHHmmss}.pdf"), DocumentFormat.Pdf);
var job = documentConverter.Jobs.CreateJob(jobData);
documentConverter.Jobs.RunJob(job);
}
I am failing to see why people have issues with QR codes such as this one which is just a template (I could not download any of the older samples above for comparison.)
 
 
It is a PNG demo template file designed to be scanned from up to 4 feet away (e.g. a poster) but it could be for production, much smaller i.e. lower scale for page scanning.
I drop the RTF on the WordPad print to pdf shortcut and get the pdf shown in the viewer almost instantly.
There is some natural degradation using RTF PNG and an aliased viewer, but the key is maintaining natural scales. Every thing you need is native as supplied with windows.
MSPaint, WordPad, CMD printing I could have sent preview to the PDFium viewer in Edge.

c# iText7 - interate throuh pdf images and change size and dpi

I have a lot of very large PDF files, which contains huge images (scans).
The goal is to open PDF , read all images , change dpi, resolution and compress it.
How to managed it with Itex7?
And generally ho to iterate through all images in PDF?
using (iText.Kernel.Pdf.PdfReader pdfReader = new iText.Kernel.Pdf.PdfReader(inputPdfFile))
{
using (iText.Kernel.Pdf.PdfDocument pdfDocument = new iText.Kernel.Pdf.PdfDocument(pdfReader))
{
//??
//foreach (var image in pdfDocumentImagesList)
//{
// //image.SetNewDPI()
//}
}
}
How to go through all the PDF's images?
https://github.com/itext/i7js-book/blob/develop/src/test/java/com/itextpdf/samples/book/part4/chapter15/Listing_15_30_ExtractImages.java
https://github.com/itext/i7js-book/blob/develop/src/test/java/com/itextpdf/samples/book/part4/chapter15/Listing_15_31_MyImageRenderListener.java
How to change the image's dpi and resolution?
That's not a part of iText functionality, since iText is a PDF- rather than an image-proccessing library. I advise you to process the extracted images with some other tools and then either put them into a new document or replace the image in the PDF. The latter is not very easy. Probably the next SO answer would shed some light on it: http://stackoverflow.com/questions/26580912/pdf-convert-to-black-and-white-pngs
(its code, but in iText7: https://github.com/itext/i7js-examples/blob/develop/src/test/java/com/itextpdf/samples/sandbox/images/ReplaceImage.java)
How to compress an image?
https://github.com/itext/i7js-book/blob/develop/src/test/java/com/itextpdf/samples/book/part3/chapter10/Listing_10_12_CompressImage.java
Hope that would be useful!

Magnetic stripe printing: Where to start?

This is a WPF desktop app related to ID Card printing. One of the new features we're trying to add is magstripe encoding. After having spent several days, I'm still not sure where to start. New questions keep popping up the more I google. I'll summarize them here. I'll be glad to hear from experts (even if someone can answer one/some of the questions):
Do magstripe printers work as normal printers too (means can they print text and graphics too, or is that we print the cards on other, regular printers in the first pass and then insert them into magstripe printer for encoding magnetic data onto them, in the 2nd pass)?
If answer to Q1 is yes, how do I send magstripe data to the printer during regular printing job (done through WPF, using PrintDialog, FixedDocument etc).
I downloaded and examined Zebra printers SDK. It looks like these printers DO support text/graphics printing in addition to magstripe encoding, but their SDK requires me to call their native printing functions, which doesn't fit in WPF's standard printing model. How to overcome this?
In another place I read that magstripe printers require simple ASCII text in specific format to get them encoded onto the card, and that I can do this even from Notepad. If this is true, the answer to Q1 might be negative. But then again, how does this method work in conjunction with regular WPF printing?
Edit
I also learnt that there are magstripe fonts that when placed in a document, end up being encoded to the magnetic stripe instead of regular printing. If this is true, it would very nicely fit in WPF printing model. But googling hasn't returned too many promising results for magstripe fonts. Maybe this is a brand-specific feature.
I am currently working on a similar WPF project that requires magnetic encoding as well as image printing on ID cards. I have found that magnetic encoding is very simple as long as the drivers for the printer with magnetic coding are installed on the host. One vital piece to watch out for is the delimiter being used by the driver. This could be NULL, ZERO, or Space. This comes into play when encoding a specific track (i.e. Track 2 but not Track 1 as we are). I use the NULL setting which allows only the Track 2 data to be sent in the job. This setting is found in the Printer Preferences for the Fargo printers (Control Panel -> Hardware and Sound -> Devices and Printers -> Right-Click Printer -> Printer Preferences). Here is an example of these Preferences (note the ASCII Offset field):
I do not believe that you MUST use the SDK for the printer you are using. I am using a Fargo printer but wrote my own Print functionality using PrintDocument and PrintPage for both magnetic encoding and images.
An example and quick test is to send Track 2 data to the printer using Notepad++ (or similar). Copy and paste this into the first line of the editor and print (using the card printer).
~2;000099990000?
The driver should pick up the fact that it is Track data and handle it accordingly without any more input from you. You may need to play with the printer preferences as stated.
The ~2; denotes Track 2 followed by a 12-character data string followed by the end sentinel (?). There is plenty of documentation pertaining to Track data and layouts online. This is assuming a NULL delimiter value (between Track 1 and Track 2).
Printing on both sides of the card can be cumbersome, but that does not appear to be within the scope of this question. I recommend using Windows native PrintDocument and PrintPage methods within your WPF application; the SDK you have downloaded is likely using these methods in the background, anyhow.
An example of PrintDocument/PrintPage:
private int PageCount { get; set; }
public void Print()
{
PageCount = 0;
PrintDocument pd = new PrintDocument
{
// Define your settings
PrinterSettings = {
Duplex = Duplex.Horizontal,
PrinterName = ConfigurationManager.AppSettings["PrinterName"]
}
};
Margins margins = new Margins(0, 0, 0, 0);
pd.OriginAtMargins = true;
pd.DefaultPageSettings.Margins = margins;
pd.PrintPage += new PrintPageEventHandler(this.PrintPage);
PrintPreviewDialog ppd = new PrintPreviewDialog();
ppd.Document = pd;
// Uncomment to show a Print Dialog box
//if (ppd.ShowDialog() == DialogResult.OK)
pd.Print();
pd.Dispose();
}
private void PrintPage(object o, PrintPageEventArgs e)
{
PrintDocument p = (PrintDocument)o;
p.DefaultPageSettings.Landscape = true;
p.DefaultPageSettings.Margins = new Margins(0, 0, 0, 0);
p.DefaultPageSettings.PaperSize = new PaperSize("YourPaperSizeName", 340, 215);
p.OriginAtMargins = true;
o = p;
e.PageSettings.PrinterSettings.DefaultPageSettings.Landscape = true;
e.PageSettings.Landscape = true;
// Do Print First Side (MAG ENCODE)
if (PageCount == 0)
{
// Do Side 1 Stuff
// If Two-Sided Printing: true
e.HasMorePages = true;
//If no more, set above to false and PageCount = 0, else...
PageCount++;
}
else
{
// Do Print on Other Side
// STUFF
// STUFF
// Since only two sides/card printing: false
e.HasMorePages = false;
PageCount = 0;
}
}
Again, magnetic encoding should not be brand-specific and you should not have to rely solely on their SDK to perform print jobs.
I hope this helps!

How to convert a png file to .GRF file used for zebra printer

I use Zebraprinter for printing the labels. My printer is 203dpi. For last couple of days i was searching in internet and i found there are Zebraprint utilities.. to convert to DFR format.. which sucks.. they are not fully explaining how to do this.. They just says convert to ~DG format. any print it, which is not happening!!
Rather I would like to convert a png file to a .GRF file and send to the printer for printing.. IS there any deadly available free software in internet which does my needs,
Also, i tired to develop a software which does the job for printing the letters.. which is wiring fine. i don't know how to print pictures using this printer.
I need to convert this image https://imageshack.com/i/pb0BArbep to .GRF format. How can i do all this under a single button press.. Any helps..
Thanks a lot.
Code snippet:-
private void button2_Click(object sender, EventArgs e)
{
string s = Print();
PrintFactory.sendTextToLPT1(s);
}
private string Print()
{
string s = "";
s += "^XA^LH"+ text.textbox + ".GRF,1,1^FS";
s += "^FO250,294^FD^FS";
s += "^XZ";
return s;
}
It's been a month since this was asked, so I don't know if an answer is still needed or not, but I'll have a go at it. I've actually been doing a lot of research on ZPL lately, (one of the reasons I came across this question), and I had to do something similar. With a 203 dpi printer as well, actually. I'm not sure how to convert a PNG to GRF, but I was able to print out a graphic using just a PNG:
^XA
^MNY
^LL203
~DYE:{name},P,P,{file size},,{data}
^XZ
The ^MN has to do with Media Tracking, and you may have to change it a bit to suit your needs, depending on the label. Same thing with ^LL, which specifies the label length. For an 8 dots/mm (203 dpi), the value you use as an argument is calculated by 203.2 * length of label in inches. After that, there's a few values to plug into ~DY (Download graphics, page 112 on the manual), the first of which is the name you want to use to reference the file. I didn't add a file extension, as the printer seemed to do that for me, since I specified it was a PNG in the arguments. The second is the size, in bytes, of the PNG file. And lastly, the actual data from the file in the form of ASCII hex. Now with the file being saved on the printer, I was then able to print the graphic in a script using:
^IME:{name}.PNG
^FS
Note: After uploading the file to the printer, I was able to confirm it did save as a PNG file by connecting to the printer VIA IP in a browser and going to "Directory Listing". I'm not sure if all those printers have this feature, but the one I used did. If it does, you can use this to confirm that the file properly uploaded. (It should be in Onboard Flash)
Hope this helps!
The manual I used is here.
I also came across numerous other StackOverflow questions that helped out a bit, and a few threads on other forums. One question that was also in C# that helped me quite a bit can be found here.

Can a PDF be converted to a vector image format that can be printed from .NET?

We have a .NET app which prints to both real printers and PDF, currently using PDFsharp, although that part can be changed if there's a better option. Most of the output is generated text or images, but there can be one or more pages that get appended to the end. That page(s) are provided by the end-user in PDF format.
When printing to paper, our users use pre-printed paper, but in the case of an exported PDF, we concatenate those pages to the end, since they're already in PDF format.
We want to be able to embed those PDFs directly into the print stream so they don't need pre-printed paper. However, there aren't really any good options for rendering a PDF to a GDI page (System.Drawing.Graphics).
Is there a vector format the PDF could be converted to by some external program, that could rendered to a GDI+ page without being degraded by conversion to a bitmap first?
In an article titled "How To Convert PDF to EMF In .NET," I have shown how to do this using our PDFOne .NET product. EMFs are vector graphics and you can render them on the printer canvas.
A simpler alternative for you is PDF overlay explained in another article titled "PDF Overlay - Stitching PDF Pages Together in .NET." PDFOne allows x-y offsets in overlays that allows you stitch pages on the edges. In the article cited here, I have overlaid the pages one over another by setting the offsets to zero. You will have set it to page width and height.
DISCLAIMER: I work for Gnostice.
Ghostscript can output PostScript (which is a vector file) which can be directly sent to some types of printers. For example, if you're using an LPR capable printer, the PS file can be directly set to that printer using something like this project: http://www.codeproject.com/KB/printing/lpr.aspx
There are also some commercial options which can print a PDF (although I'm not sure if the internal mechanism is vector or bitmap based), for example http://www.tallcomponents.com/pdfcontrols2-features.aspx or http://www.tallcomponents.com/pdfrasterizer3.aspx
I finally figured out that there is an option that addresses my general requirement of embedding a vector format into a print job, but it doesn't work with GDI based printing.
The XPS file format created by Microsoft XPS Writer print driver can be printed from WPF, using the ReachFramework.dll included in .NET. By using WPF for printing instead of GDI, it's possible to embed an XPS document page into a larger print document.
The downside is, WPF printing works quite a bit different, so all the support code that directly uses stuff in the Sytem.Drawing namespace has to be re-written.
Here's the basic outline of how to embed the XPS document:
Open the document:
XpsDocument xpsDoc = new XpsDocument(filename, System.IO.FileAccess.Read);
var document = xpsDoc.GetFixedDocumentSequence().DocumentPaginator;
// pass the document into a custom DocumentPaginator that will decide
// what order to print the pages:
var mypaginator = new myDocumentPaginator(new DocumentPaginator[] { document });
// pass the paginator into PrintDialog.PrintDocument() to do the actual printing:
new PrintDialog().PrintDocument(mypaginator, "printjobname");
Then create a descendant of DocumentPaginator, that will do your actual printing. Override the abstract methods, in particular the GetPage should return DocumentPages in the correct order. Here's my proof of concept code that demonstrates how to append custom content to a list of Xps documents:
public override DocumentPage GetPage(int pageNumber)
{
for (int i = 0; i < children.Count; i++)
{
if (pageNumber >= pageCounts[i])
pageNumber -= pageCounts[i];
else
return FixFixedPage(children[i].GetPage(pageNumber));
}
if (pageNumber < PageCount)
{
DrawingVisual dv = new DrawingVisual();
var dc = dv.Drawing.Append();
dc = dv.RenderOpen();
DoRender(pageNumber, dc); // some method to render stuff to the DrawingContext
dc.Close();
return new DocumentPage(dv);
}
return null;
}
When trying to print to another XPS document, it gives an exception "FixedPage cannot contain another FixedPage", and a post by H.Alipourian demonstrates how to fix it: http://social.msdn.microsoft.com/Forums/da/wpf/thread/841e804b-9130-4476-8709-0d2854c11582
private DocumentPage FixFixedPage(DocumentPage page)
{
if (!(page.Visual is FixedPage))
return page;
// Create a new ContainerVisual as a new parent for page children
var cv = new ContainerVisual();
foreach (var child in ((FixedPage)page.Visual).Children)
{
// Make a shallow clone of the child using reflection
var childClone = (UIElement)child.GetType().GetMethod(
"MemberwiseClone", BindingFlags.Instance | BindingFlags.NonPublic
).Invoke(child, null);
// Setting the parent of the cloned child to the created ContainerVisual
// by using Reflection.
// WARNING: If we use Add and Remove methods on the FixedPage.Children,
// for some reason it will throw an exception concerning event handlers
// after the printing job has finished.
var parentField = childClone.GetType().GetField(
"_parent", BindingFlags.Instance | BindingFlags.NonPublic);
if (parentField != null)
{
parentField.SetValue(childClone, null);
cv.Children.Add(childClone);
}
}
return new DocumentPage(cv, page.Size, page.BleedBox, page.ContentBox);
}
Sorry that it's not exactly compiling code, I just wanted to provide an overview of the pieces of code necessary to make it work to give other people a head start on all the disparate pieces that need to come together to make it work. Trying to create a more generalized solution would be much more complex than the scope of this answer.
While not open source and not .NET native (Delphi based I believe, but offers a precompiled .NET library), Quick PDF can render a PDF to an EMF file which you could load into your Graphics object.

Categories