1

I'm creating an application on Android using C++ Builder, and I need to print out (not display on screen) a Bitmap already created. To print out, I'm using "Classic Bluetooth Basic App" that Embarcadero offers. To convert I'm using this code:

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

It returns to me the base64 string, so I could pass it in print out function, but it will print the whole string, and I need the bitmap (the image in itself).

How can I do it?

EDITED:

The code that I'm using to interact with the printer:

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

      }

I tried to use TEncoding to encode the bitmap and pass to ToSend, but I couldn't found and doesn't make sense because it will print the String (same case as base64).

techie
  • 463
  • 4
  • 17
  • what do you mean by `print out (not display on screen) ` ? you have a printer and want to print the result on paper? if the case in VCL there is [`TPrinter`](https://stackoverflow.com/a/42384425/2521214) class which has its own Canvas you can (stretch) draw your bitmap on it ... if not clarify what you mean... If you mean pass image by base64 then you need to decode it on the other end (where you receive it) – Spektre Nov 25 '20 at 08:22
  • Yes, I want to print in a thermal printer. I'm not using VCL, I'm using FMX (I put on tags of the question). I included `FMX.Printer` to use, but no success. I'm using bitmaps and `Scanline` to move the info of my bitmap to a `TBitmapSurface` (questions of size of bitmap), and when I put `printer->Begindoc() (printer is an instance of FMX TPrinter)` and `printer->EndDoc()` it gaves me Segmentation Fault. Googled a lot and no answer for it. No documentation too. – techie Nov 25 '20 at 13:07
  • For base64 I said that I "converted" my image to a base64 String, thinking about pass it to the print function, to it "magically" convert to image again. But doesn't matter base64, it was just a case to help if I could follow some idea of this converting. My point is: Get the bitmap and print in a thermal printer. – techie Nov 25 '20 at 13:11
  • 1
    Why are you converting a `TBitmap` to a base64 string to pass it to a printer? That makes no sense at all. What kind of input does the printer API actually expect? Please [edit] your question to include the code you are using to interact with the printer – Remy Lebeau Nov 25 '20 at 15:26
  • I tried to pass it because was the only way that I thank, that's because `TPrinter` only works for Windows and MacOS. Also, if I encode anything using `TEncoding`, in the end will be in Bytes or String (like base64). I couldn't found a class or something that I could pass bitmaps directly to the printer, I want to edit this function to pass bitmaps directly, but due to conversions I can't. I edited my question with the interaction of my printer, it's working and prints String texts. Thank you so far. – techie Nov 25 '20 at 15:49
  • IIRC segmentation fault is line access violation so you most likely wrongly pass the scan lines .. or delete or resize the passed bitmap which invalidates the pointers etc ... From your edit you are connecting to printer as some bluetooth device which I assume is passing raw BYTE data (no base64 !!! its usually 7/8 or 9 bit width) ... if the case you need to encode your image into format your printer accept ... so you need to find the protocol and commands for your printer and then encode ... as encoding of printed data is different among vendors ... – Spektre Nov 25 '20 at 16:57
  • For example see [Epson FX Printer Codes](http://www.lprng.com/RESOURCES/EPSON/epson.htm) so you would need to disect your bitmap to lines (not scan lines more like 8 or 9 pixel height line) position your printer to start of line pass gfx codes to configure for gfx data and then pass the gfx data and repeat for all lines until whole image is passed. As you can see using `TPrinter` is much easier as it does all this using the printers driver however I do not code for android nor FMX so I do not know if it works on your platform and you just have bug in your code or you need to use something else – Spektre Nov 25 '20 at 17:06
  • My bet is that TPrinter works and you just used it wrongly ... – Spektre Nov 25 '20 at 17:07
  • @Spektre Thank you so far. But I will show to you the Embarcadero's documentation that has `TPrinter` working only on Windows and MacOS: [TPrinter](http://docwiki.embarcadero.com/Libraries/Sydney/en/FMX.Printer.TPrinter). I understand that you said about Epson Printer, but I need to use in some printers, and I'm not using ESC/POS in this case to have a standard step, so it will be only "print something", e.g: String (that I'm already doing). I will google more about it and try to find some solution. Thanks. – techie Nov 25 '20 at 18:37
  • @Que44 well you got 2 options 1. find&install lib or component that will work on your platform 2. write the encoding your self ... When you sen raw data to printer (like you do now) the ASCII codes are usually interpreted as text directly (hence base64 will print text) so you need to find specs for your printer (manufactor sites usually have them for download) and then go from there ... The epson was just a example what to look for as you did not specify what printer you interfacing ... However take in mind that this approach will work only for one type of printer ... – Spektre Nov 25 '20 at 20:01
  • @Que44 btw there where utilities to enable old MS-DOS programs printing on new printers under windows like [DOSPRINT](https://www.dosprint.com) (you chose some old printer like StarLC for printing to file (with known codes) and the utility will take the data convert to printer you actually got installed on your system and print) so finding something similar for your platform might help ... Also IIRC some "newer" printers recognize [PostScript *.ps](https://fileinfo.com/extension/ps) so maybe would be enough to convert to *.ps and send that ... – Spektre Nov 25 '20 at 20:12
  • @Que44 Anyway If you want any chance for meaningful answer for the encoding approach you should specify exactly which printer you want to use ... – Spektre Nov 25 '20 at 20:13
  • @Spektre Thanks for the options and your time. As I said, I will use in some printers, it's not in a specific one, or a specific model of printer, it will be in some thermal printers. The example of EPSON that you post here is good, but only works for EPSON, and what I want is encode it and pass to the printer, but with no restrictions of manufacture. That's why I'm using this "generic pattern" to print String text. I found about [ActionList](http://docwiki.embarcadero.com/Libraries/Sydney/en/FMX.MediaLibrary.Actions.TShowShareSheetAction) – techie Nov 25 '20 at 20:24
  • It opens a menu saying if I want to send to bluetooth or something, it's almost there, due to the fact that it doesn't find my thermal printer bluetooth (I don't know why). It could be "something", but it's not what I want yet (I can use this for other buttons), it needs to be directly, as String texts are. I don't know yet if has some `intent` directly to Android that do it to me. I found this code on Android site that if has a way to do this on C++ Builder, it could be the solution: [Printing Bitmap](https://developer.android.com/training/printing/photos) – techie Nov 25 '20 at 20:29
  • Unrelated: In C++ code, do not use `Free` to destroy an object. Use the `delete` keyword, but instead of `TMemoryStream* ms = new TMemoryStream(); ... delete ms;` you could use a `std::unique_ptr ms;` that calls `delete` automatically when it goes out of scope. – Ted Lyngmo Nov 26 '20 at 21:05

0 Answers0