WPF Печать на принтере с кодировкой Magstrip - PullRequest
2 голосов
/ 11 января 2011

Я пишу новое приложение WPF, которое создает некоторые визуальные элементы, а затем пытаюсь распечатать их на принтере Poloroid.Я успешно печатаю, используя классы System.Printing в WPF следующим образом:

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

Проблема состоит в том, что у полороидного принтера есть SDK, который можно использовать для записи в Magstrip на обратной стороне карты.У меня есть рабочий пример использования PrintPageEventArgs в System.Drawing.Printing, но я не могу найти каких-либо близких совпадений для мира 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

Итак, мой вопрос:

Как мне распечатать существующую разметку (XAML), используя System.Drawing.Printing

ИЛИ

Есть ли в 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);
 ...
}

Но печать не была четкой и безупречной.

Ответы [ 2 ]

0 голосов
/ 14 апреля 2017

Я недавно ответил на похожий вопрос, который можно найти здесь: https://stackoverflow.com/a/43373398/3393832. Этот вопрос и ответ больше относятся к магнитному кодированию (на идентификационных картах), чем к печати изображений, но я попытаюсь дать некоторое представление об этом здесь., а также.

Для изображений карт я фактически настроил две таблицы в моем 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.Просто вызовите DrawString до DrawImage, и ваш драйвер принтера должен выбрать кодирование перед изображением в методе PrintPage (опять же, пожалуйста, обратитесь к ссылке выше для получения более подробной информации о методе Print, который я использую. Этот метод также не привязан кпроизводитель или модель принтера и не зависит от какого-либо SDK).

Несмотря на то, что он универсален и нуждается в подробностях вашей реализации, я надеюсь, что этот пост поможет вам найти решение, соответствующее вашим конкретным потребностям.Пожалуйста, не стесняйтесь спрашивать, есть ли у вас какие-либо дополнительные вопросы или вам нужна более подробная информация о конкретных элементах самого задания на печать.

0 голосов
/ 25 января 2011

Попробуйте это

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

      }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...