2 Stimmen

WPF Drucken auf Drucker mit Magstrip-Kodierung

Ich schreibe eine neue WPF-Anwendung, die einige visuelle Elemente erstellt und dann versucht, sie auf einem Poloroid-Drucker zu drucken. Ich drucke erfolgreich mit den System.Printing-Klassen in WPF wie folgt:

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

Das Problem ist, dass der Poloroid-Drucker ein SDK hat, mit dem man den Magstrip auf der Rückseite der Karte beschreiben kann. Ich habe ein funktionierendes Beispiel mit dem PrintPageEventArgs in System.Drawing.Printing, aber ich kann keine enge Übereinstimmungen für die WPF-Welt finden. Hier ist der Code:

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

Meine Frage ist also:

Wie kann ich mein bestehendes Markup (XAML) drucken, indem ich System.Drawing.Printing

オア

Gibt es Ereignisse in der System.Printing um mit dem SDK zu sprechen und die Int32 deviceContext?

und ich habe versucht RenderTargetBitmap Klasse, um das Bildmaterial in WPF in eine Bitmap zu rendern und die Bitmap in System.Drawing.Bitmap zu konvertieren

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

Aber der Druck war nicht klar und perfekt.

0voto

Dhanya Ullas Punkte 149

Versuchen Sie dies

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

      }

0voto

CodeBreaker Punkte 167

Kürzlich habe ich eine ähnliche Frage beantwortet, die Sie hier finden können: https://stackoverflow.com/a/43373398/3393832 . Diese Frage und die Antwort beziehen sich eher auf die magnetische Kodierung (auf ID-Karten) als auf den Bilddruck, aber ich werde versuchen, auch hier einige Einblicke zu geben.

Für die Kartenbilder richte ich in meiner XAML zwei Raster ein: ein äußeres Raster, in dem alles untergebracht ist (Schaltflächen, Beschriftungen, Kombinationsfelder, das innere Raster), und ein inneres Raster, das im Wesentlichen das Bild darstellt, das ich vollständig auf die Karte selbst anwenden möchte. Im Code mache ich einen "Schnappschuss" des inneren Rasters, nachdem alle Elemente hinzugefügt/aktualisiert wurden, und sende dieses Bild einfach in den Druckauftrag.

Um mit meinem vorherigen Beitrag (Link oben) fortzufahren, füge ich den Bilddruck NACH dem Schritt der Magnetkodierung für die erste Seite der Karte hinzu (PageCount == 0).

Nachfolgend finden Sie einige Codes, die ich verwende, um den Bitmap-"Schnappschuss" des Rasters/Vollbilds ohne Verlust an Klarheit/Auflösung oder Pixelierung zu erhalten:

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

Für die magnetische Kodierung verwende ich e.Graphics.DrawString und für das Bild (Sie haben es erraten) e.Graphics.DrawImage. Rufen Sie einfach DrawString vor DrawImage auf, und Ihr Druckertreiber sollte die Kodierung vor dem Bild in der PrintPage-Methode abholen (weitere Details zu der von mir verwendeten Print-Methode finden Sie im Link oben). Diese Methode ist auch nicht an eine Druckermarke oder ein Druckermodell gebunden und ist nicht auf ein SDK angewiesen).

Ich hoffe, dass dieser Beitrag Ihnen hilft, eine Lösung zu finden, die Ihren speziellen Anforderungen entspricht, auch wenn er allgemein gehalten ist und Ihre speziellen Implementierungsdetails berücksichtigt werden müssen. Bitte zögern Sie nicht, mich zu fragen, wenn Sie weitere Fragen haben oder mehr Details zu den einzelnen Elementen des Druckauftrags selbst benötigen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X