Comment puis-je imprimer une image sur une imprimante Bluetooth sous Android?

je dois imprimer quelques données sur l'Imprimante Thermique bluetooth, je fais avec ceci:

String message="abcdef any message 12345";
byte[] send;
send = message.getBytes();
mService.write(send);

cela fonctionne bien pour le texte, mais pas pour les images. Je pense que j'ai besoin du byte[] des données image. J'ai essayé d'obtenir les données de l'image de cette façon:

Bitmap bitmap=BitmapFactory.decodeResource(getResources(), R.drawable.qrcode);
ByteArrayOutputStream stream=new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 90, stream);
byte[] image=stream.toByteArray();

malheureusement l'imprimante imprime beaucoup de caractères étranges (env. 50 cm de papier). Je ne sais pas comment imprimer l'image.

je voudrais essayer obtenir les pixels du bitmap et le convertir ensuite en un byte[] et l'envoyer, mais je ne sais pas comment le faire.

Merci

mise à jour:

après tant de temps, je fais ceci: j'ai une méthode appelée print_image( fichier String), qui obtient le chemin de l'image que je veux imprimer:

private void print_image(String file) {
    File fl = new File(file);
    if (fl.exists()) {
        Bitmap bmp = BitmapFactory.decodeFile(file);
        convertBitmap(bmp);
        mService.write(PrinterCommands.SET_LINE_SPACING_24);

        int offset = 0;
        while (offset < bmp.getHeight()) {
            mService.write(PrinterCommands.SELECT_BIT_IMAGE_MODE);
            for (int x = 0; x < bmp.getWidth(); ++x) {

                for (int k = 0; k < 3; ++k) {

                    byte slice = 0;
                    for (int b = 0; b < 8; ++b) {
                        int y = (((offset / 8) + k) * 8) + b;
                        int i = (y * bmp.getWidth()) + x;
                        boolean v = false;
                        if (i < dots.length()) {
                            v = dots.get(i);
                        }
                        slice |= (byte) ((v ? 1 : 0) << (7 - b));
                    }
                    mService.write(slice);
                }
            }
            offset += 24;
            mService.write(PrinterCommands.FEED_LINE);
            mService.write(PrinterCommands.FEED_LINE);          
            mService.write(PrinterCommands.FEED_LINE);
            mService.write(PrinterCommands.FEED_LINE);
            mService.write(PrinterCommands.FEED_LINE);
            mService.write(PrinterCommands.FEED_LINE);
        }
        mService.write(PrinterCommands.SET_LINE_SPACING_30);


    } else {
        Toast.makeText(this, "file doesn't exists", Toast.LENGTH_SHORT)
                .show();
    }
}

Je l'ai fait basé sur ce post

C'est la classe PrinterCommands:

public class PrinterCommands {
public static final byte[] INIT = {27, 64};
public static byte[] FEED_LINE = {10};

public static byte[] SELECT_FONT_A = {27, 33, 0};

public static byte[] SET_BAR_CODE_HEIGHT = {29, 104, 100};
public static byte[] PRINT_BAR_CODE_1 = {29, 107, 2};
public static byte[] SEND_NULL_BYTE = {0x00};

public static byte[] SELECT_PRINT_SHEET = {0x1B, 0x63, 0x30, 0x02};
public static byte[] FEED_PAPER_AND_CUT = {0x1D, 0x56, 66, 0x00};

public static byte[] SELECT_CYRILLIC_CHARACTER_CODE_TABLE = {0x1B, 0x74, 0x11};

public static byte[] SELECT_BIT_IMAGE_MODE = {0x1B, 0x2A, 33, -128, 0};
public static byte[] SET_LINE_SPACING_24 = {0x1B, 0x33, 24};
public static byte[] SET_LINE_SPACING_30 = {0x1B, 0x33, 30};

public static byte[] TRANSMIT_DLE_PRINTER_STATUS = {0x10, 0x04, 0x01};
public static byte[] TRANSMIT_DLE_OFFLINE_PRINTER_STATUS = {0x10, 0x04, 0x02};
public static byte[] TRANSMIT_DLE_ERROR_STATUS = {0x10, 0x04, 0x03};
public static byte[] TRANSMIT_DLE_ROLL_PAPER_SENSOR_STATUS = {0x10, 0x04, 0x04};
}

comme on le voit dans la méthode print_image j'appelle une méthode, appelée convertBitmap, et j'envoie un bitmap, c'est le code:

   public String convertBitmap(Bitmap inputBitmap) {

    mWidth = inputBitmap.getWidth();
    mHeight = inputBitmap.getHeight();

    convertArgbToGrayscale(inputBitmap, mWidth, mHeight);
    mStatus = "ok";
    return mStatus;

}

private void convertArgbToGrayscale(Bitmap bmpOriginal, int width,
        int height) {
    int pixel;
    int k = 0;
    int B = 0, G = 0, R = 0;
    dots = new BitSet();
    try {

        for (int x = 0; x < height; x++) {
            for (int y = 0; y < width; y++) {
                // get one pixel color
                pixel = bmpOriginal.getPixel(y, x);

                // retrieve color of all channels
                R = Color.red(pixel);
                G = Color.green(pixel);
                B = Color.blue(pixel);
                // take conversion up to one single value by calculating
                // pixel intensity.
                R = G = B = (int) (0.299 * R + 0.587 * G + 0.114 * B);
                // set bit into bitset, by calculating the pixel's luma
                if (R < 55) {                       
                    dots.set(k);//this is the bitset that i'm printing
                }
                k++;

            }


        }


    } catch (Exception e) {
        // TODO: handle exception
        Log.e(TAG, e.toString());
    }
}

C'est le imprimante que j'utilise, résolution: 8 points/mm, 576 points/ligne

Et c'est ce que j'aime faire (je l'ai fait avec la même imprimante, mais avec une application téléchargée à partir de jeux stocker) Image that I want to print

C'est ce que je reçois maintenant My printing trying

plus proche: A closer part

Closer2: enter image description here

Une petite partie de l'image peut être vu, donc je pense que je suis plus proche permet d'imprimer l'image...

l'image que j'utilise est celle-ci (576x95): enter image description here

Et voici l'image convertie (je la convertis avec le code supérieur): converted image

Inverted

alors, la réponse est: qu'est-ce que je fais de mal? Je pense que l'erreur est dans cette commande:

  public static byte[] SELECT_BIT_IMAGE_MODE = {0x1B, 0x2A, 33, -128, 0};

Mais, comment puis-je calculer les valeurs correctes pour mon image?, merci

39
demandé sur Leonardo Sapuy 2013-01-26 00:43:10

7 réponses

je le résous en convertissant Bitmap en byte array. Rappelez-vous que votre image doit être en noir et blanc.

pour le code source complet: https://github.com/imrankst1221/Thermal-Printer-in-Android

enter image description here

 public void printPhoto() {
        try {
            Bitmap bmp = BitmapFactory.decodeResource(getResources(),
                    R.drawable.img);
            if(bmp!=null){
                byte[] command = Utils.decodeBitmap(bmp);
                printText(command);
            }else{
                Log.e("Print Photo error", "the file isn't exists");
            }
        } catch (Exception e) {
            e.printStackTrace();
            Log.e("PrintTools", "the file isn't exists");
        }
    }
10
répondu Md Imran Choudhury 2017-02-07 09:22:05

résolu!, Je faisais une mauvaise initialisation de l'imprimante... Le chemin de corect est:

 public static byte[] SELECT_BIT_IMAGE_MODE = {0x1B, 0x2A, 33, 255, 3};

ainsi, de cette façon l'image est imprimée complètement fine

8
répondu Leonardo Sapuy 2013-06-04 16:35:49

EDIT : mise à jour basée sur la lecture de votre question: https://stackoverflow.com/questions/16597789/print-bitmap-on-esc-pos-printer-java

je supposerai que l'imprimante sur laquelle vous imprimez est la même que ci-dessus, c.-à-d. L'Imprimante Thermique Rego. Cela, comme vous le constatez, supporte le ESC/POS Page Description Language .


les imprimantes interprètent les données streamed pour eux soit comme un document balisé (d'une manière similaire à la façon dont le navigateur interprète HTML). Dans certains cas, L'imprimante exécute littéralement le document sous forme de programme (par exemple PostScript). Lien: Description De La Page Languages .

les langues communes sont:

vous devez lire les spécifications de votre imprimante pour déterminer quelle langue utiliser - si vous avez besoin de prendre en charge n'importe quelle imprimante, alors vous avez un très gros travail devant vous: (

dans ESC/POS, vous devrez utiliser la commande GS v 0 (documentée sur p33). Vous faites cela en envoyant les caractères 0x1D7630 à travers le lien série, suivi d'un ensemble d'arguments:

ASCII:       Gs   v  0 
Decimal:     29 118 48 m xL xH yL yH [d]k 
Hexadecimal: 1D  76 30 m xL xH yL yH [d]k 

définitions des paramètres:

  • m:
    • 0,48: mode normal (échelle 1: 1)
    • 1,49: double-largeur
    • 2,50: double hauteur
    • 3,51: double largeur + double hauteur
  • xL, XH spécifie (xL + xH × 256) octets en horizontal direction pour l'image bit.
  • yL, yH spécifie des points (yL + yH × 256) en direction verticale pour l'image bit.
  • [D] K spécifie les données d'image bit (format raster).
  • k indique le nombre de données d'image bit. k étant un paramètre d'explication, il n'est pas nécessaire de le transmettre.

Notes:

  • lorsque la donnée [D]k est 1 spécifie un bit imprimé à 1 et non imprimé à 0.
  • si une image matricielle dépasse une ligne de surface d'impression, les données excédentaires ne sont pas imprimées.
  • cette commande exécute l'alimentation en papier pour la quantité nécessaire à l'impression de l'image bit indépendamment des réglages de L'ESC 2 ou de L'ESC 3.
  • après l'impression de l'image bit, cette commande définit la position d'impression au début de la ligne, et nettoie le tampon.
  • lorsque ce la commande est exécutée, les données sont transmises et imprimé de façon synchrone. Aucune autre commande d'impression n'est donc nécessaire.

il y a plusieurs expositions plus étendues:


malheureusement, il n'y a pas D'API d'imprimante sous Android. Si vous vous sentez fortement à ce sujet, ne suivez ces questions:

7
répondu Andrew Alcock 2017-05-23 12:34:36

j'ai aussi essayé et j'ai ma propre solution et je pense que j'ai compris comment le SELECT_BIT_IMAGE_MODE commande fonctionne.

la commande public static byte[] SELECT_BIT_IMAGE_MODE = {0x1B, 0x2A, 33, 255, 3}; dans la classe PrinterCommands est la commande POS pour l'impression d'image.

Les deux premiers sont assez standard, les trois prochaines déterminer le mode et les dimensions de l'image à imprimer. Pour le bien de cette solution, supposons que le deuxième élément (33, Nous sommes indexés Zéro) est toujours 33.

les deux derniers éléments de cet octet[] font référence à la propriété largeur (en pixels) de l'image que vous voulez imprimer, l'élément 3 est parfois appelé nL et l'élément 4 est parfois appelé nH . Ils se réfèrent en fait tous les deux à la largeur, nL est le Low Byte tandis que nH est le High Byte . Cela signifie que l'on peut avoir au plus une image avec une largeur de 1111 1111 1111 1111b (binaire) qui est 65535d (décimal), bien que je ne l'ai pas encore essayé. Si nL ou nH ne sont pas paramétrés aux valeurs appropriées, alors il y aura des caractères trash imprimés avec l'image.

D'une certaine manière, Android docs nous dit que les limites de la valeur d'un octet dans un tableau octet est -128 et +127, quand j'ai essayé de mettre dans 255, Eclipse m'a demandé de le jeter à Byte.

de toute façon, en revenant à nL et nW, pour votre cas, vous avez une image avec la largeur 576, si nous convertissons 576 en binaire, nous obtenons deux octets qui vont comme:

0000 0010 0100 0000

dans ce cas, le Byte inférieur est 0100 0000 tandis que le Byte supérieur est 0000 0010 . Convertir décimal et nous obtenons nL = 64 et nH = 2 .

dans mon cas, j'ai imprimé une image qui a une largeur de 330px, en convertissant 330 en binaire nous obtenons:

0000 0001 0100 1010

dans ce cas maintenant, le Byte Bas est 0100 1010 et le Byte haut est 0000 0001 . En convertissant en décimal, on obtient nL = 74 et nH = 1 .

pour plus d'informations, consultez ces documents / tutoriels:

Star Asia Mobile Printer Documentation

ECS-POS-guide de programmation - vraiment vaste

Autre Documentation

La version étendue du code ci-dessus, avec plus d'explications

explication du code au-dessus de

espérons que ça aide.

4
répondu Razgriz 2013-07-22 09:00:47

je sais pour les imprimantes evolute et AMDL bluetooth.Lisez d'abord le document de définition du protocole de l'imprimante qui vous dit quels octets spécifiques vous avez besoin pour le périphérique -

public void connect() throws Exception 
{

    BluetoothDevice printer = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(connParams);

    Method m = printer.getClass().getMethod("createInsecureRfcommSocket",new Class[] { int.class });
    sock = (BluetoothSocket)m.invoke(printer, Integer.valueOf(1));
    sock.connect();
    os=sock.getOutputStream();
    in=sock.getInputStream();

}

après la connexion par le code ci-dessus vous obtenez le flux de sortie de la prise.Puis convertissez votre image en byte correspondant à travers l'outil fourni avec l'imprimante vous obtenez quelque chose comme

public byte[] Packet1={
        (byte)0X8A,(byte)0XC6,(byte)0X94,(byte)0XF4,(byte)0X0B,(byte)0X5E,(byte)0X30,(byte)0X25,(byte)
        0X01,(byte)0X5E,(byte)0X04,(byte)0X24,(byte)0X01,(byte)0X0C,(byte)0X5E,(byte)0X03,(byte)0X24,(byte)0X01,(byte)0X08,(byte)0X5E,(byte)0X27,(byte)0X25,(byte)
        0X01,(byte)0X5E,(byte)0X04,(byte)0X24,(byte)0X05,(byte)0X0C,(byte)0X00,(byte)0X60,(byte)0X00,(byte)0X18,(byte)0X5E,(byte)0X27,(byte)0X25,(byte)
        0X01,(byte)0X5E,(byte)0X03,(byte)0X24,(byte)0X06,(byte)0X30,(byte)0X1E,(byte)0X10,(byte)0X60,(byte)0X00,(byte)0X18,(byte)0X5E,(byte)0X27,(byte)0X25,(byte)
        0X01,(byte)0X5E,(byte)0X03,(byte)0X24,(byte)0X06,(byte)0X70,(byte)0X3F,(byte)0X18,(byte)0XF0,(byte)0X00,(byte)0X3E,(byte)0X5E,(byte)0X27,(byte)0X25,(byte)
        0X01,(byte)0X5E,(byte)0X03,(byte)0X24,(byte)0X06,(byte)0X70,(byte)0X3C,(byte)0X39,(byte)0XF1,(byte)0X80,(byte)0X3E,(byte)0X5E,(byte)0X27,(byte)0X25,(byte)
        0X01,(byte)0X5E,(byte)0X03,(byte)0X24,(byte)0X06,(byte)0XF8,(byte)0X7C,(byte)0X9F,(byte)0XF1,(byte)0X80,(byte)0X7F,(byte)0X5E,(byte)0X27,(byte)0X25,(byte)
        0X01,(byte)0X5E,(byte)0X03,(byte)0X24,(byte)0X06,(byte)0XF9,(byte)0X9E,(byte)0X1C,(byte)0XFF,(byte)0XC2,(byte)0X7E,(byte)0X5E,(byte)0X27,(byte)0X25,(byte)
        0X01,(byte)0X5E,(byte)0X03,(byte)0X24,(byte)0X06,(byte)0XF9,(byte)0X9E,(byte)0X1C,(byte)0XE7,(byte)0XE2,(byte)0X7E,(byte)0X5E,(byte)0X27,(byte)0X25,(byte)
        0X01,(byte)0X5E,(byte)0X03,(byte)0X24,(byte)0X06,(byte)0XFB,(byte)0X1E,(byte)0X1C,(byte)0XFF,(byte)0XE7,(byte)0XBE,(byte)0X5E,(byte)0X27,(byte)0X25,(byte)
        0X01,(byte)0X5E,(byte)0X03,(byte)0X24,(byte)0X06,(byte)0X7B,(byte)0X16,(byte)0X1C,(byte)0XFF,(byte)0XDF,(byte)0X3E,(byte)0X5E,(byte)0X27,(byte)0X25,(byte)
        0X01,(byte)0X5E,(byte)0X03,(byte)0X24,(byte)0X06,(byte)0X71,(byte)0X12,(byte)0X1C,(byte)0XE7,(byte)0XF7,(byte)0X34,(byte)0X5E,(byte)0X27,(byte)0X25,(byte)
        0X01,(byte)0X5E,(byte)0X03,(byte)0X24,(byte)0X06,(byte)0X51,(byte)0X12,(byte)0X1C,(byte)0XF7,(byte)0XF7,(byte)0X24,(byte)0X5E,(byte)0X27,(byte)0X25,(byte)
        0X01,(byte)0X5E,(byte)0X03,(byte)0X24,(byte)0X06,(byte)0X49,(byte)0X12,(byte)0X1C,(byte)0XFF,(byte)0XF3,(byte)0X24,(byte)0X5E,(byte)0X27,(byte)0X25,(byte)
        0X01,(byte)0X5E,(byte)0X03,(byte)0X24,(byte)0X06,(byte)0X49,(byte)0X12,(byte)0X3F,(byte)0XFD,(byte)0XF3,(byte)0X24,(byte)0X5E,(byte)0X27,(byte)0X25,(byte)
        0X01,(byte)0X5E,(byte)0X03,(byte)0X24,(byte)0X06,(byte)0X49,(byte)0X96,(byte)0X3F,(byte)0XFC,(byte)0XF3,(byte)0X24,(byte)0X5E,(byte)0X27,(byte)0X25,(byte)
        0X01,(byte)0X5E,(byte)0X03,(byte)0X24,(byte)0X05,(byte)0X49,(byte)0X80,(byte)0X00,(byte)0X08,(byte)0X10,(byte)0X5E,(byte)0X28,(byte)0X25,(byte)
        0X01,(byte)0X5E,(byte)0X30,(byte)0X25,(byte)
        0X01,(byte)0X5E,(byte)0X03,(byte)0X24,(byte)0X06,(byte)0XE0,(byte)0X74,(byte)0XA9,(byte)0X33,(byte)0X23,(byte)0X26,(byte)0X5E,(byte)0X27,(byte)0X25,(byte)0X04
        };

où 8A commence par C6 est mode octet (différent de la carte à puce , carte et empreintes digitales) , 94 est de la police de l'octet et le dernier octet 04 est la fin de l'octet dire le matériel que c'est la fin du paquet.Selon la taille de l'image, vous obtenez plusieurs de ces paquets de longueur 256 octets (imprimante most).Écrire à l'outputStream.

os.write(Packet1)
2
répondu mjosh 2013-05-26 19:53:57

je suis nouveau à l'ESC/POS et je suis aux prises avec elle. Je suis tombé sur cette page qui semble avoir quelques fonctions utiles: http://code.taobao.org/p/printer/src/trunk/prtest/src/com/enjar/plugins/PrintTools_58mm.java C'est en Chinois, mais peut-être la peine d'aller à travers. Si quelqu'un a des chiffres, je voudrais être éclairé...

2
répondu just some guy 2013-11-14 11:53:33

utilisez ce code:

public static void print(Context context) {

    String examplePath = "file:///sdcard/dcim/Camera/20111210_181524.jpg";

    Intent sendIntent = new Intent(Intent.ACTION_SEND);
    sendIntent.setType("image/jpeg");
    sendIntent.putExtra(Intent.EXTRA_SUBJECT, "Photo");
    sendIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse(examplePath));
    sendIntent.putExtra(Intent.EXTRA_TEXT, "Enjoy the photo");
    context.startActivity(Intent.createChooser(sendIntent, "Email:"));
}
-4
répondu TalDroid 2013-05-29 12:36:03