如何在不使用PrinterSettings的情况下更改打印机的纸张尺寸?

Art*_*ous 3 c# printing size wpf

我正在尝试对将在特殊介质上打印的自定义标签打印机进行编码。

使用600的DPI,打印介质大小约为2.00“ x 0.244”。下面是printLabel函数,带有传入的位图标签值。

您会看到我当前正在尝试自定义页面大小,但是打印机会打印出12个标签,只有1个具有我需要的信息。

我一次只需要打印1个标签。如果您需要更多信息或有疑问,请随时发表评论,但是我迷失了要做的事情。

我无法想象从Windows的打印机设置页面中获得了页面大小的枚举集合。任何帮助将不胜感激。

PrintServer ps = null;

        if (Properties.Settings.Default.ShrinkLabelPrinter.Contains(@"\\serverloc1") || Properties.Settings.Default.ShrinkLabelPrinter.Contains(@"\\SERVERLOC1"))
            ps = new PrintServer(@"\\serverloc1");
        else if (Properties.Settings.Default.ShrinkLabelPrinter.Contains(@"\\serverloc2") || Properties.Settings.Default.ShrinkLabelPrinter.Contains(@"\\SERVERLOC2"))
            ps = new PrintServer(@"\\serverloc2");
        else
            ps = new PrintServer();

        System.Windows.Controls.PrintDialog pd = new System.Windows.Controls.PrintDialog();

        PrintQueue queue = ps.GetPrintQueue(@"\\serverloc2\bbp33 (Copy 1)");

        List<string> lstPaperSizes = new List<string>();

        queue.CurrentJobSettings.CurrentPrintTicket.PageMediaSize = new PageMediaSize(PageMediaSizeName.Unknown, 150, 141);

        //queue.CurrentJobSettings.CurrentPrintTicket.PageMediaSize = ;

        pd.PrintQueue = queue;

        System.Drawing.Image img = label;

        //REMOVE IF LABELS ARE PORTRAIT FORMAT
        //img.RotateFlip(RotateFlipType.Rotate90FlipNone); 

        var ms = new MemoryStream();

        img.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
        ms.Position = 0;

        var bi = new BitmapImage();
        bi.BeginInit();
        bi.CacheOption = BitmapCacheOption.OnLoad;
        bi.StreamSource = ms;
        RenderOptions.SetBitmapScalingMode(bi, BitmapScalingMode.HighQuality);
        bi.EndInit();

        var vis = new DrawingVisual();
        var dc = vis.RenderOpen();

        Rect angle = new Rect
        {
            Width = Convert.ToInt32(Math.Round(bi.Width, 0)),
            Height = Convert.ToInt32(Math.Round(bi.Height, 0))
        };

        dc.DrawImage(bi, angle);
        dc.Close();
        img.Save(@"\temp\Label Creator\Resources\cable_label.png");
        pd.PrintVisual(vis, "Cable Label");
Run Code Online (Sandbox Code Playgroud)

Kcv*_*vin 5

我建议您做更多的调试,检查图像的高度,检查页面大小是否正确,等等。总之,这可能是很多事情。以下是引起我注意的一些内容:

  1. PageMediaSize你打印到是1.5625" (150像素/ 96DPI)宽,1.46875" (141px / 96DPI)高
  2. 而不是改变queue.CurrentJobSettings...PageMediaSize尝试去做pd.PrintTicket.PageMediaSize.PageMediaSize = new ...
  3. 也许PrintQueue.Commit()对您有用
  4. 设置一个断点并查看您的PrintQueue属性,如果我建议您没有任何作用,那么我很想了解您的值PrintQueue.UserPrintTicket(但是您可能不想更改UserPrintTicket)。
  5. 确保您了解打印机本身及其硬件功能。它会风景和肖像吗?是否有SDK?
  6. 查看/研究PrintQueue.PrintCapabilities然后断点并至少调试目标打印机的功能一次。那里有很多信息(例如兼容的介质尺寸)。
  7. 注意您img的尺寸。new PageMediaSize(PageMediaSizeName.Unknown, 192, 23.424);如果要2“ x 0.244”,则您的介质尺寸应为。您的图片应具有相似的尺寸,并且不应超出这些尺寸。pd.PrintableAreaHeight|Width打印前请先检查一下。
    • Windows显示是默认的96DPI。当您将视觉效果发送到打印机时,这是假定的。因此,您可以通过执行以下操作找到尺寸(size in inches / 96) = # of pixels you want to use with PageMediaSize。转到标准打印机,然后通过PrintCapabilities看到的大小,PageMediaSizeName.NorthAmericanLetter您将看到高度为816像素x 1056像素。816/96 = 8.5,1056/96 = 11-8.5 x 11个介质。
  8. 您还可以使用XML下载打印机的功能。在XML中,您可能会找到打印机可以处理的其他功能(例如介质尺寸),并且可能需要您在打印之前进行设置。

我非常有信心地研究和尝试大胆的项目中指出的事情,可以在某种程度上为您提供解决方案。在System.Printing困扰命名空间的很多很多小时中,我发现每台打印机的行为都可能不同,而小的更改可能会带来最明显的效果!

我将为您提供帮助,只需发表评论即可!祝好运。

编辑1

不幸的是,我没有任何自定义/专业打印机可以测试,但是我将尝试几种获取预定义尺寸的方法。

使用PrintQueue.PrintCapabilities

这将打印出打印机报告的可用尺寸。由于B33-126是自定义尺寸,您可能会看到一堆PageMediaSizeName.Unknown带有尺寸的,您必须在其中确定适合您的尺寸,然后PrintTicket在应用程序中使用相同的尺寸。

PrintQueue pq = GetYourPrintQueue();
PrintCapabilities pc = pq.GetPrintCapabilities();
ReadOnlyCollection<PageMediaSize> capableSizes = pc.PageMediaSizeCapability;
foreach(var pm in capableSizes) 
{ 
    Console.WriteLine(pm);
}
//Identify what PageMediaSize you need, and set your print ticket to use the exact same dimensions
Run Code Online (Sandbox Code Playgroud)

使用PrintQueue.GetPrintCapabilitiesAsXml()

PrintQueue pq = GetYourPrintQueue();
MemoryStream pcXml = pq.GetPrintCapabilitiesAsXml();
Console.WriteLine(pcXml.ToString())
//At this point, set a breakpoint on Console.WriteLine and inspect the `pcXml` object to see if the XML contains custom print capabilities.  If so you'll have to identify which sizes/properties you need to make use of.
Run Code Online (Sandbox Code Playgroud)

使用PrintQueue.UserPrintTicket

UserPrintTicket是当前用户的默认打印机设置。因此,您可以使用控制面板进入打印设备,右键单击目标打印机,然后转到“打印首选项”,然后将页面/纸张尺寸更改为B33-126尺寸,然后单击“应用/确定”。关闭窗口。

现在执行:

PrintQueue pq = GetYourPrintQueue();
var upt = pq.UserPrintTicket;
Console.WriteLine(upt);
Run Code Online (Sandbox Code Playgroud)

并设置您的断点Console.WriteLine并检查upt。这将显示与我们在上述步骤中设置/应用的设置相匹配的PrintTicket中的当前设置。您应该可以pd.PrintTicket = upt在那时进行打印。

使用PrintDialog:

您可以PrintDialog.ShowDialog()用来设置打印机设置,然后添加一个断点以查看它们是什么并将相同的设置应用于您的解决方案。

PrintDialog pd = new PrintDialog();
pd.ShowDialog();
//Set a breakpoint on the code show below this comment.  At this point your print dialog is shown and you can select a printer.  Select the target printer and click "Preferences." When shown, set whatever settings you might normally use to print labels.  Then click "Apply," then click "OK."  
Console.WriteLine(pd.PrintTicket);
Run Code Online (Sandbox Code Playgroud)

当调试器点击最后一行代码时,您刚刚通过首选项页面应用于打印机的设置将显示在中pd.PrintTicket。您可以采用这些设置,并PrintTicket在应用程序中使用相同的设置。

最后要注意的是PrintDialog关闭后的属性。它在那里有您的高度和宽度(可以找到边距)。您要确保要打印的图像适合这些尺寸。请记住,您可以使用来打印倍数PrintDialog.CopyCount