C++ Builder: преобразование и распечатка растрового изображения

Я создаю приложение на Android с помощью C++ Builder, и мне нужно распечатать (не отображать на экране) уже созданное растровое изображение. Для распечатки я использую приложение Classic Bluetooth Basic, которое предлагает Embarcadero. Для преобразования я использую этот код:

#include "System.NetEncoding.hpp"

TMemoryStream *ms;
TStringStream *ss;
String s;
UnicodeString result;

ms = new TMemoryStream();
ss = new TStringStream();
bmpResult->SaveToStream(ms);
ms->Position = 0;
EncodeStream(ms, ss);
s = ss->DataString;
ms->Free();
ss->Free();
result = s;
return result;

Он возвращает мне строку base64, поэтому я могу передать ее в функцию вывода, но она напечатает всю строку, и мне нужно растровое изображение (изображение само по себе).

Как мне это сделать?

ОТРЕДАКТИРОВАНО:

Код, который я использую для взаимодействия с принтером:

  TBytes ToSend;
  if((FSocket == NULL) || (ItemIndex != ComboBoxPaired->ItemIndex)) {
      if(ComboBoxPaired->ItemIndex > -1) {
          TBluetoothDevice * LDevice = FPairedDevices->Items[ComboBoxPaired->ItemIndex];
          FSocket = LDevice->CreateClientSocket(StringToGUID(ServiceGUI), false);
          if(FSocket != NULL) {
              ItemIndex = ComboBoxPaired->ItemIndex;
              FSocket->Connect();
              //func is AnsiString and passed as a parameter in this function
              ToSend = TEncoding::UTF8->GetBytes(func);
              FSocket->SendData(ToSend);

              delete FSocket;
              FSocket = NULL;
          }
          else {
              ShowMessage("Error 1");
          }
      }
      else {
              ShowMessage("Error 2");
      }
  }
      else {
          ShowMessage("Error 4");

      }

Я пытался использовать TEncoding для кодирования растрового изображения и перехода к ToSend, но я не смог найти и не имеет смысла, потому что он будет печатать строку (тот же случай, что и base64).


person Que44    schedule 24.11.2020    source источник
comment
что ты имеешь в виду под print out (not display on screen) ? у вас есть принтер и вы хотите распечатать результат на бумаге? если в VCL есть класс TPrinter, у которого есть собственный Canvas, вы можете (растянуть) нарисовать на нем растровое изображение. , если не уточнить, что вы имеете в виду... Если вы имеете в виду передачу изображения по base64, вам нужно декодировать его на другом конце (где вы его получаете)   -  person Spektre    schedule 25.11.2020
comment
Да, я хочу печатать на термопринтере. Я не использую VCL, я использую FMX (ставлю теги вопроса). Я включил FMX.Printer для использования, но безуспешно. Я использую растровые изображения и Scanline для перемещения информации о моем растровом изображении в TBitmapSurface (вопросы размера растрового изображения), и когда я помещаю printer->Begindoc() (printer is an instance of FMX TPrinter) и printer->EndDoc(), это дает мне ошибку сегментации. Много гуглил, а ответа нет. Документации тоже нет.   -  person Que44    schedule 25.11.2020
comment
Для base64 я сказал, что преобразовал свое изображение в строку base64, думая о том, чтобы передать его функции печати, чтобы она снова волшебным образом преобразовалась в изображение. Но не имеет значения base64, это был просто случай, чтобы помочь, если бы я мог следовать какой-то идее этого преобразования. Моя точка зрения такова: возьмите растровое изображение и распечатайте его на термопринтере.   -  person Que44    schedule 25.11.2020
comment
Почему вы конвертируете TBitmap в строку base64, чтобы передать ее на принтер? В этом нет никакого смысла. Какие входные данные на самом деле ожидает API принтера? Пожалуйста, отредактируйте свой вопрос, чтобы включить код, который вы используете для взаимодействия с принтером.   -  person Remy Lebeau    schedule 25.11.2020
comment
Я пытался пройти его, потому что это был единственный способ, за который я благодарю, потому что TPrinter работает только для Windows и MacOS. Кроме того, если я что-либо закодирую с помощью TEncoding, в конце концов это будет в байтах или строке (например, base64). Я не смог найти класс или что-то, что я мог бы передавать растровые изображения непосредственно на принтер, я хочу отредактировать эту функцию для прямой передачи растровых изображений, но из-за преобразований я не могу. Я отредактировал свой вопрос при взаимодействии с моим принтером, он работает и печатает тексты String. Спасибо.   -  person Que44    schedule 25.11.2020
comment
Ошибка сегментации IIRC - это нарушение доступа к строке, поэтому вы, скорее всего, неправильно передаете строки сканирования ... или удаляете или изменяете размер переданного растрового изображения, что делает недействительными указатели и т. Д. Из вашего редактирования вы подключаетесь к принтеру как какое-то устройство Bluetooth, которое, как я предполагаю, проходит необработанные данные BYTE (без base64 !!! обычно это ширина 7/8 или 9 бит) ... если вам нужно закодировать изображение в формат, который принимает ваш принтер ... поэтому вам нужно найти протокол и команды для вашего принтер, а затем закодировать ... поскольку кодировка печатных данных отличается у разных поставщиков ...   -  person Spektre    schedule 25.11.2020
comment
Например, см. Коды принтеров Epson FX. линии (не линии сканирования, а линия высотой 8 или 9 пикселей) расположите принтер в начале строки, передайте коды gfx для настройки данных gfx, а затем передайте данные gfx и повторите для всех строк, пока не будет передано все изображение. Как вы можете видеть, использовать TPrinter намного проще, так как все это делается с помощью драйвера принтера, однако я не пишу код для Android и FMX, поэтому я не знаю, работает ли он на вашей платформе, и у вас просто есть ошибка в вашем коде или вам нужно использовать что-то еще   -  person Spektre    schedule 25.11.2020
comment
Бьюсь об заклад, что TPrinter работает, и вы просто использовали его неправильно ...   -  person Spektre    schedule 25.11.2020
comment
@Spektre Спасибо. Но я покажу вам документацию Embarcadero, в которой TPrinter работает только на Windows и MacOS: TPrinter. Я понимаю, что вы сказали об Epson Printer, но мне нужно использовать его в некоторых принтерах, и я не использую ESC/POS в этом случае, чтобы иметь стандартный шаг, поэтому я буду печатать только что-то, например: String (что я уже делаю). Я буду гуглить больше об этом и попытаюсь найти какое-то решение. Спасибо.   -  person Que44    schedule 25.11.2020
comment
@ Que44 ну, у вас есть 2 варианта: 1. найти и установить библиотеку или компонент, который будет работать на вашей платформе 2. написать кодировку самостоятельно ... Когда вы отправляете необработанные данные на принтер (как вы делаете сейчас), коды ASCII обычно интерпретируются как текст напрямую (следовательно, base64 будет печатать текст), поэтому вам нужно найти спецификации для вашего принтера (на сайтах производителей они обычно есть для загрузки), а затем перейти оттуда ... Epson был просто примером того, что искать, поскольку вы не указали, что принтер, с которым вы взаимодействуете ... Однако имейте в виду, что этот подход будет работать только для одного типа принтера ...   -  person Spektre    schedule 25.11.2020
comment
@ Que44, кстати, там, где есть утилиты, позволяющие старым программам MS-DOS печатать на новых принтерах под окнами, такими как DOSPRINT (вы выбрали какой-нибудь старый принтер, такой как StarLC, для печати в файл (с известными кодами), и утилита возьмет данные, преобразованные в принтер, который вы действительно установили в своей системе, и распечатает), поэтому может помочь найти что-то похожее для вашей платформы ... Также IIRC некоторые более новые принтеры распознают PostScript *.ps, поэтому, возможно, будет достаточно преобразовать в *.ps и отправить это .. .   -  person Spektre    schedule 25.11.2020
comment
@ Que44 В любом случае, если вы хотите получить осмысленный ответ о подходе к кодированию, вы должны точно указать, какой принтер вы хотите использовать ...   -  person Spektre    schedule 25.11.2020
comment
@Spektre Спасибо за варианты и ваше время. Как я уже сказал, я буду использовать его в некоторых принтерах, а не в конкретном или конкретной модели принтера, это будет в некоторых термопринтерах. Пример EPSON, который вы публикуете здесь, хорош, но работает только для EPSON, и я хочу закодировать его и передать на принтер, но без ограничений производителя. Вот почему я использую этот общий шаблон для печати текста String. Я нашел о ActionList   -  person Que44    schedule 25.11.2020
comment
Он открывает меню, в котором говорится, что если я хочу отправить на блютуз или что-то в этом роде, его почти нет, из-за того, что он не находит блютуз моего термопринтера (не знаю, почему). Это может быть что-то, но это пока не то, что я хочу (я могу использовать это для других кнопок), это должно быть напрямую, как тексты String. Я еще не знаю, есть ли какие-то intent непосредственно для Android, которые делают это для меня. Я нашел этот код на сайте Android, и если есть способ сделать это в C++ Builder, это может быть решением: Печать растрового изображения   -  person Que44    schedule 25.11.2020
comment
Не связано: в коде C++ не используйте Free для уничтожения объекта. Используйте ключевое слово delete, но вместо TMemoryStream* ms = new TMemoryStream(); ... delete ms; вы можете использовать std::unique_ptr<TMemoryStream> ms;, которое автоматически вызывает delete, когда оно выходит за рамки.   -  person Ted Lyngmo    schedule 27.11.2020