【问题标题】:WPF Printing to printer with Magstrip encodingWPF 使用 Magstrip 编码打印到打印机
【发布时间】:2011-01-11 12:07:34
【问题描述】:

我正在编写一个新的 WPF 应用程序,它会创建一些视觉元素,然后尝试在 Poloroid 打印机上打印它们。我使用 WPF 中的 System.Printing 类成功打印如下:

Dim Pd As PrintDialog = New PrintDialog()
Dim Ps = New LocalPrintServer()
Dim PrintQueue = New PrintQueue(Ps, "Poloroid Printer")
Pd.PrintQueue = PrintQueue
Pd.PrintVisual(Me.Grid1, "Print Job 1")  'this prints out perfectly

问题在于 poloroid 打印机有一个 SDK,您可以使用它来写入卡背面的磁条。我有一个使用 System.Drawing.Printing 中的 PrintPageEventArgs 的工作示例,但我找不到任何与 WPF 世界相近的匹配项。这是代码:

Private Sub PrintPage(ByVal sender as Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs)
  '...

  ' Obtain the device context for this printer
  deviceContext = e.Graphics.GetHdc().ToInt32()

  '... device context is used in SDK to write to magstrip

  e.Graphics.ReleaseHdc(New IntPtr(deviceContext))
End Sub

所以,我的问题是:

如何使用 System.Drawing.Printing 打印我现有的标记 (XAML)

System.Printing 中是否有与 SDK 对话并获取 Int32 deviceContext 的事件?

我尝试通过RenderTargetBitmap 类将 WPF 中的视觉呈现为位图并将位图转换为 System.Drawing.Bitmap

RenderTargetBitmap bitmapSource;
...
bitmapSource.Render(visual);
...
using(MemoryStream outStream = new MemoryStream())
{
 BitmapEncoder enc = new BmpBitmapEncoder();
 enc.Frames.Add(BitmapFrame.Create(bitmapSource));
 enc.Save(outStream);
 System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(outStream);
 ...
}

但是印刷不够清晰和完美。

【问题讨论】:

标签: c# wpf printing image-processing


【解决方案1】:

试试这个

      Rect bounds = VisualTreeHelper.GetDescendantBounds(FrontCanvas);
      double dpiX =e.Graphics.DpiX  , dpiY=e.Graphics.DpiY ;
      RenderTargetBitmap rtb = new RenderTargetBitmap((int)(bounds.Width * dpiX  / 96.0),
                                                      (int)(bounds.Height * dpiY   / 96.0),
                                                      dpiX,
                                                      dpiY,
                                                      PixelFormats.Pbgra32);

      DrawingVisual dv = new DrawingVisual();
      using (DrawingContext ctx = dv.RenderOpen())
      {
          VisualBrush vb = new VisualBrush(FrontCanvas);
          ctx.DrawRectangle(vb, null, new Rect(new Point(), bounds.Size));
      }

      rtb.Render(dv);

      //System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(rtb);
      //e.Graphics.DrawImage(rtb, 0, 0);

      using (MemoryStream outStream = new MemoryStream())
      {
          // Use png encoder for  data
          BitmapEncoder encoder = new PngBitmapEncoder();

          // push the rendered bitmap to it
          encoder.Frames.Add(BitmapFrame.Create(rtb));
          encoder.Save(outStream);
          System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(outStream);
          e.Graphics.DrawImage(bitmap, 0, 0);

      }

【讨论】:

    【解决方案2】:

    我最近回答了一个类似的问题,可以在这里找到:https://stackoverflow.com/a/43373398/3393832。这个问题和答案更多地与磁编码(在 ID 卡上)有关,而不是图像打印,但我也会在这里尝试提供一些见解。

    对于卡片图像,我实际上在我的 XAML 中设置了两个网格:一个包含所有内容(按钮、标签、组合框、内部网格)的外部网格和一个本质上是我想要应用的图像的内部网格,完整的,在卡本身上。在代码中,我在添加/更新所有元素后拍摄内部网格的“快照”,然后将该图像简单地发送到打印作业中。

    为了继续我之前的帖子(上面的链接),我在卡片第一面 (PageCount == 0) 的磁编码步骤之后添加了图像打印。

    以下是我用来获取网格/完整图像的位图“快照”的一些代码,而不会损失任何清晰度/分辨率或任何像素化:

    RenderTargetBitmap rtb = new RenderTargetBitmap(gridWidth, gridHeight, 210, 210, PixelFormats.Pbgra32);
    
    rtb.Render(YourGrid);
    
    // If you need to Crop Anything Out
    CroppedBitmap crop = new CroppedBitmap();
    
    crop = new CroppedBitmap(rtb, new Int32Rect(0, 0, gridWidth, gridHeight));
    
    Bitmap bmpToPrint = BitmapSourceToBitmap(crop);
    
    // Helper Method
    public Bitmap BitmapSourceToBitmap(BitmapSource bs)
    {
        Bitmap bitmap;
    
        using (MemoryStream ms = new MemoryStream())
        {
            BitmapEncoder enc = new BmpBitmapEncoder();
            enc.Frames.Add(BitmapFrame.Create(bs));
            enc.Save(ms);
            bitmap = new Bitmap(ms);
        }
    
        return bitmap;
    }
    

    对于磁性编码,我使用 e.Graphics.DrawString 和图像(你猜对了)e.Graphics.DrawImage。只需在 DrawImage 之前调用 DrawString ,您的打印机驱动程序应该在 PrintPage 方法中的图像之前获取编码(再次,请参阅上面的链接以获取有关我正在使用的 Print 方法的更多详细信息。此方法也不绑定到打印机品牌或型号,不依赖于任何 SDK)。

    虽然通用且需要您的特定实施细节,但我希望这篇文章能帮助您找到适合您特定需求的解决方案。如果您有任何后续问题或需要有关打印作业本身特定元素的更多详细信息,请随时询问。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-05
      • 2011-04-12
      • 2020-06-10
      相关资源
      最近更新 更多