FarOoOosa
FarOoOosa

Reputation: 311

Print Arabic characters in android Thermal Printer

Printer is GoojPRT portable printer PT-210 (thermal printer)

the same code is work on another thermal printer POS but not work on this printer for Arabic characters the English characters is good but the Arabic characters is shown as chinses characters

try to add encoded as charset " UTF-8 " and not working for Arabic characters the code for print :

Button btnPrint=(Button)findViewById(R.id.btnPrint);
        btnPrint.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                Thread t = new Thread() {
                    public void run() {
                        try {
                            OutputStream os = mBluetoothSocket
                                    .getOutputStream();
                            BILL = "ENGLISH" + "\n";
                            BILL =  BILL + "العربية" + "\n";
                            BILL = BILL + "---------------" + "\n";
                            
                            os.write(BILL.getBytes( ));
                        } catch (Exception e) {

                        }
                    }
                };
                t.start();
            }
        });

scan for printer:

Button btnScan = (Button) findViewById(R.id.btnScan);
        btnScan.setOnClickListener(new View.OnClickListener() {
            public void onClick(View mView) {
                mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
                if (mBluetoothAdapter == null) {
                    Toast.makeText(ActivityTest.this, "Error", Toast.LENGTH_SHORT).show();
                } else {
                    if (!mBluetoothAdapter.isEnabled()) {
                        Intent enableBtIntent = new Intent(
                                BluetoothAdapter.ACTION_REQUEST_ENABLE);
                        startActivityForResult(enableBtIntent,
                                REQUEST_ENABLE_BT);
                    } else {
                        ListPairedDevices();
                        Intent connectIntent = new Intent(ActivityTest.this,
                                DeviceListActivity.class);
                        startActivityForResult(connectIntent,
                                REQUEST_CONNECT_DEVICE);
                    }
                }
            }
        });

sample of printing

sample of printing

I need to print text not bitmap or image

Upvotes: 2

Views: 3615

Answers (3)

Laith Bzour
Laith Bzour

Reputation: 111

first you need to convert text to bitmap image then split image to chunk and send it to printer like below :

1- use this useful lib for print : https://github.com/DantSu/ESCPOS-ThermalPrinter-Android

2- func below for split image :

private static  void splitImage(Bitmap bitmap,SplitBitmapImage spliter)  {
    Bitmap bmpScale = Bitmap.createScaledBitmap(bitmap, bitmap.getWidth(), bitmap.getHeight(), false);
    int rows = bmpScale.getHeight() /  70 + 1;
    int cols = 1;
    try {
        int chunkHeight = bitmap.getHeight() / rows + 1;
        int chunkWidth = bitmap.getWidth() / cols;
        Bitmap scaledBitmap = Bitmap.createScaledBitmap(bitmap, bitmap.getWidth(), bitmap.getHeight(), false);
        int yCoord = 0;
        int var8 = 0;

        for(int var9 = rows; var8 < var9; ++var8) {
            int xCoord = 0;
            int var11 = 0;

            for(int var12 = cols; var11 < var12; ++var11) {
                Bitmap bmp = Bitmap.createBitmap(scaledBitmap, xCoord, yCoord, chunkWidth, chunkHeight);

                if (bmp != null && spliter != null) {
                    Thread.sleep(20);
                    spliter.bitmpaSpliter(bmp);
                }

                xCoord += chunkWidth;
            }

            yCoord += chunkHeight;
        }
    } catch (Exception var14) {
        var14.printStackTrace();
    }

}

3- print func

new Thread(() -> {

        try {
            EscPosPrinter printer = new EscPosPrinter(MyBluetoothPrintersConnections.selectFirstPairedOne(), 203, 48f, 32);
            Bitmap newbit2 = BitmapUtils.toGrayscale(bytes);
            StringBuilder textToPrint = new StringBuilder();
            splitImage(newbit2, text->{

                    textToPrint.append("[C]<img>" + PrinterTextParserImg.bitmapToHexadecimalString(printer, text) + "</img>\n"+
                            "[L]\n");
            });

            printer.printFormattedTextAndCut(textToPrint.toString());


        } catch (EscPosConnectionException e) {
            e.printStackTrace();
        } catch (EscPosEncodingException e) {
            e.printStackTrace();
        } catch (EscPosBarcodeException e) {
            e.printStackTrace();
        } catch (EscPosParserException e) {
            e.printStackTrace();
        }

}).start();

Upvotes: 0

Yagoub GRINE
Yagoub GRINE

Reputation: 65

I had the same problem, after two days of searching, I found out that, the simple way to print a multilingual text like Arabic is to draw it on a canvas and print it as a normal image, as shown here :

    public Bitmap getMultiLangTextAsImage(String text, Paint.Align align, float textSize, Typeface typeface)  {


    Paint paint = new Paint();

    paint.setAntiAlias(true);
    paint.setColor(Color.BLACK);
    paint.setTextSize(textSize);
    if (typeface != null) paint.setTypeface(typeface);

    // A real printlabel width (pixel)
    float xWidth = 385;

    // A height per text line (pixel)
    float xHeight = textSize + 5;

    // it can be changed if the align's value is CENTER or RIGHT
    float xPos = 0f;

    // If the original string data's length is over the width of print label,
    // or '\n' character included,
    // it will be increased per line gerneating.
    float yPos = 27f;

    // If the original string data's length is over the width of print label,
    // or '\n' character included,
    // each lines splitted from the original string are added in this list
    // 'PrintData' class has 3 members, x, y, and splitted string data.
    List<PrintData> printDataList = new ArrayList<PrintData>();

    // if '\n' character included in the original string
    String[] tmpSplitList = text.split("\\n");
    for (int i = 0; i <= tmpSplitList.length - 1; i++) {
        String tmpString = tmpSplitList[i];

        // calculate a width in each split string item.
        float widthOfString = paint.measureText(tmpString);

        // If the each split string item's length is over the width of print label,
        if (widthOfString > xWidth) {
            String lastString = tmpString;
            while (!lastString.isEmpty()) {

                String tmpSubString = "";

                // retrieve repeatedly until each split string item's length is
                // under the width of print label
                while (widthOfString > xWidth) {
                    if (tmpSubString.isEmpty())
                        tmpSubString = lastString.substring(0, lastString.length() - 1);
                    else
                        tmpSubString = tmpSubString.substring(0, tmpSubString.length() - 1);

                    widthOfString = paint.measureText(tmpSubString);
                }

                // this each split string item is finally done.
                if (tmpSubString.isEmpty()) {
                    // this last string to print is need to adjust align
                    if (align == Paint.Align.CENTER) {
                        if (widthOfString < xWidth) {
                            xPos = ((xWidth - widthOfString) / 2);
                        }
                    } else if (align == Paint.Align.RIGHT) {
                        if (widthOfString < xWidth) {
                            xPos = xWidth - widthOfString;
                        }
                    }
                    printDataList.add(new PrintData(xPos, yPos, lastString));
                    lastString = "";
                } else {
                    // When this logic is reached out here, it means,
                    // it's not necessary to calculate the x position
                    // 'cause this string line's width is almost the same
                    // with the width of print label
                    printDataList.add(new PrintData(0f, yPos, tmpSubString));

                    // It means line is needed to increase
                    yPos += 27;
                    xHeight += 30;

                    lastString = lastString.replaceFirst(tmpSubString, "");
                    widthOfString = paint.measureText(lastString);
                }
            }
        } else {
            // This split string item's length is
            // under the width of print label already at first.
            if (align == Paint.Align.CENTER) {
                if (widthOfString < xWidth) {
                    xPos = ((xWidth - widthOfString) / 2);
                }
            } else if (align == Paint.Align.RIGHT) {
                if (widthOfString < xWidth) {
                    xPos = xWidth - widthOfString;
                }
            }
            printDataList.add(new PrintData(xPos, yPos, tmpString));
        }

        if (i != tmpSplitList.length - 1) {
            // It means the line is needed to increase
            yPos += 27;
            xHeight += 30;
        }
    }

    // If you want to print the text bold
    //paint.setTypeface(Typeface.create(null as String?, Typeface.BOLD))

    // create bitmap by calculated width and height as upper.
    Bitmap bm = Bitmap.createBitmap((int) xWidth, (int) xHeight, Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(bm);
    canvas.drawColor(Color.WHITE);

    for (PrintData tmpItem : printDataList)
        canvas.drawText(tmpItem.text, tmpItem.xPos, tmpItem.yPos, paint);


    return bm;
}

static class PrintData {
    float xPos;
    float yPos;
    String text;

    public PrintData(float xPos, float yPos, String text) {
        this.xPos = xPos;
        this.yPos = yPos;
        this.text = text;
    }

    public float getxPos() {
        return xPos;
    }

    public void setxPos(float xPos) {
        this.xPos = xPos;
    }

    public float getyPos() {
        return yPos;
    }

    public void setyPos(float yPos) {
        this.yPos = yPos;
    }

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }
}

If you want more details, check this

Upvotes: 2

Yegorf
Yegorf

Reputation: 400

Try to add ISO-8859-6 encode for arabic text.

Upvotes: -1

Related Questions