Magnetic stripe printing: Where to start?

2019-06-12 15:17发布

问题:

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):

  1. 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)?
  2. 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).
  3. 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?
  4. 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

  1. 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.

回答1:

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!