anastaciocintra / escpos-coffee

Java library for ESC/POS printer
https://anastaciocintra.github.io/escpos-coffee
MIT License
280 stars 74 forks source link

ESc/POS arabic printing not working #44

Closed rajesh-shanthi closed 4 years ago

rajesh-shanthi commented 4 years ago

Hi,

I am trying to print arabic language and i get ????? as printed for the arabic text. The following is my code in java. public void Sample(String printerName) {

    // get the printer service by name passed on command line...
    // this call is slow, try to use it only once and reuse the PrintService
    // variable.
    PrintService printService = PrinterOutputStream.getPrintServiceByName(printerName);
    EscPos escpos;
    try {
        System.setProperty("file.encoding", "UTF-8");
        escpos = new EscPos(new PrinterOutputStream(printService));

        Style title = new Style().setFontSize(Style.FontSize._2, Style.FontSize._4)

                .setJustification(EscPosConst.Justification.Center);

        escpos.setCharacterCodeTable(CharacterCodeTable.WCP1256_Arabic);
        System.out.println(escpos.getDefaultCharsetName());
        String rawString = "الصفحة الرئيسية";
        escpos.write(rawString.getBytes("UTF-8"), 0, rawString.length());

        escpos.feed(5);
        // escpos.cut(EscPos.CutMode.FULL);

        escpos.close();

    } catch (IOException ex) {
        ex.printStackTrace();
    }

}

Can you please help me, what is the problem for junk characters getting printed. I just opened a texpad and pasted some arabic content and saved file in utf-8 encoding and fired printout to my pos printer , it is prining the arabic characters

Regards, Rajesh.

anastaciocintra commented 4 years ago

Hi @rajesh-shanthi , first, we need to clarify about "printing correctly on word or textpad...". In mine printer it happens too. You can make it with java, more information on docs oracle. This kind of printing is the regular printing, for normal printers. You can print everything, images, special characters, etc... It's like create one bitmap and print and can be convenient in some cases. In other hand, I doesn't know if it works on all termal printers.... Another option, and more simple way is to create one bitmap, and print it on escpos printer.

Ok, then the another subject matter.... the escpos arabic character In mine printer, it works well with some adjusts:

public class Arabic implements Exec {
    @Override
    public void exec(EscPos escpos) throws IOException {
//        System.setProperty("file.encoding", "UTF-8");

        Style title = new Style().setFontSize(Style.FontSize._2, Style.FontSize._4)

                .setJustification(EscPosConst.Justification.Center);

//        escpos.setCharacterCodeTable(EscPos.CharacterCodeTable.CP864_Arabic);
//        escpos.setCharacterCodeTable(EscPos.CharacterCodeTable.PC720_Arabic);
        escpos.setCharacterCodeTable(EscPos.CharacterCodeTable.WCP1256_Arabic);
//        escpos.setCharacterCodeTable(EscPos.CharacterCodeTable.);
        System.out.println(escpos.getDefaultCharsetName());
        String rawString = "الصفحة الرئيسية";
        escpos.writeLF("ة");
        escpos.writeLF("ي");
        escpos.writeLF("س");
        escpos.writeLF("ا");
        escpos.writeLF("ل");
        escpos.writeLF("ص");
        escpos.writeLF(rawString);
//        escpos.write(rawString);
//        escpos.write(rawString);

        escpos.feed(5);
         escpos.cut(EscPos.CutMode.FULL);

        escpos.close();
    }
}

At last, but not least important, for help to understood what is happening, you can read the escpos-coffee wiki page about this subject on this link

If you have any question, count on me.

rajesh-shanthi commented 4 years ago

Hi , Thanks for the support. I am using Epson TM 81 model printer and i checked the manual . The below setting is perfect escpos.setCharacterCodeTable(CharacterCodeTable.WCP1256_Arabic); , but when i print it pints characters which is junk / unrecognizable. The printer is a network printer connected to a router and i fire the printout from my laptop(windows 10 ) using eclipse from a java application. Is anything do with printer settings /encoding ? I am clueless at this point. Please throw me if you have any ideas on this.

anastaciocintra commented 4 years ago

Ok, I'll try to help. We need to certificate that all environment is working for WCP1256. I made one sequence for the test, please run and send here the results, (take pictures of the printted output paper) and text copy of the terminal output , send here the TM-T81 printer's programming manual.

till later,

please, run this code:

import com.github.anastaciocintra.escpos.EscPos;
import com.github.anastaciocintra.escpos.EscPosConst;
import com.github.anastaciocintra.escpos.Style;

import java.io.IOException;
import java.io.UnsupportedEncodingException;

public class Arabic implements Exec {
    @Override
    public void exec(EscPos escpos) throws IOException {
//        System.setProperty("file.encoding", "UTF-8");

        Style title = new Style().setFontSize(Style.FontSize._2, Style.FontSize._4)

                .setJustification(EscPosConst.Justification.Center);

//        escpos.setCharacterCodeTable(EscPos.CharacterCodeTable.CP864_Arabic);
//        escpos.setCharacterCodeTable(EscPos.CharacterCodeTable.PC720_Arabic);
        escpos.setCharacterCodeTable(EscPos.CharacterCodeTable.WCP1256_Arabic);
//        escpos.setCharacterCodeTable(EscPos.CharacterCodeTable.);
        System.out.println(escpos.getDefaultCharsetName());
        escpos.writeLF("ة");
        escpos.writeLF("ي");
        escpos.writeLF("س");
        escpos.writeLF("ا");
        escpos.writeLF("ل");
        escpos.writeLF("ص");
        String rawString = "الصفحة الرئيسية";
        escpos.writeLF("printing natural order");
        escpos.writeLF(rawString);
        escpos.writeLF("printing reverse order");
        escpos.writeLF(reverse(rawString));
        escpos.feed(5);
        escpos.cut(EscPos.CutMode.FULL);

        // printing all the character table for arabic WCP1256
        printCodeTable(escpos, EscPos.CharacterCodeTable.WCP1256_Arabic.value,128,255);
        terminalPrintJavaCharSet(EscPos.CharacterCodeTable.WCP1256_Arabic.charsetName,128,255);

    }
    String reverse(String str){
        return new StringBuffer(str).reverse().toString();
    }
    void printCodeTable(EscPos escpos, int codeTable, int codMin, int codMax) throws IOException {
        escpos.setCharacterCodeTable(EscPos.CharacterCodeTable.CP437_USA_Standard_Europe);
        escpos.writeLF(String.format("character code table for code [%d], " +
                "\nbetween %d and %d", codeTable,codMin, codMax));
        escpos.setPrinterCharacterTable(codeTable);
        for(int code = codMin; code <= codMax; code++){
            escpos.write(code);
            escpos.write("  ");

        }
        escpos.writeLF("");
        escpos.feed(5).cut(EscPos.CutMode.FULL);

    }

    void terminalPrintJavaCharSet(String charSetName, int codMin, int codMax) throws UnsupportedEncodingException {
        System.out.println(String.format("List of Java CharSet for charsetName = \"%s\", " +
                "between %d and %d", charSetName, codMin, codMax));
        byte[] bytes = new byte[1];
        for (int code = codMin; code <= codMax; code++) {
            bytes[0] = (byte) code;
            System.out.println(String.format("code = [%d] = char [%s]", code, new String(bytes, charSetName)));

        }
    }
}
anastaciocintra commented 4 years ago

The printer is a network printer connected to a router and i fire the printout from my laptop(windows 10 ) using eclipse from a java application. Is anything do with printer settings /encoding

network error is less problable, but can you print the escpos-samples?, barcodes, images etc?

rajesh-shanthi commented 4 years ago

Hi, The Printer TM - T81 model technical documentation online link is below

Code Page support https://www.epson-biz.com/modules/ref_charcode_en/index.php?content_id=117

https://www.epson-biz.com/modules/ref_charcode_en/index.php?content_id=60

The above link has all the My printer model image

tm-t81

Will send you the the printout shortlyl

anastaciocintra commented 4 years ago

I've read the docs that you sended, and I concur with you, the TM-T81 have the capabilities to print Arabic cp1256. Then the output probably will be similar of the same tests on mine printer.

My questions are "The cp1256 character table is enough for you?" or "you have all characters that you need to write in your Arabic region?" and "have the Arabic characters output on the printer good quality?, is this shaped good drawed?"000

For comparison purposes, I'm sending here the output of my tests on my printer (TM-T20)

Analising my results For me, the output of the printer is similar but not totaly equal of the terminal output, but only one arabian men can answer if printed characters is good or not good for read, or if natural order or reverser order of the printed text make sense.

Below, my results:

Terminal output

List of Java CharSet for charsetName = "cp1256", between 128 and 255
code = [128] = char [€]
code = [129] = char [پ]
code = [130] = char [‚]
code = [131] = char [ƒ]
code = [132] = char [„]
code = [133] = char […]
code = [134] = char [†]
code = [135] = char [‡]
code = [136] = char [ˆ]
code = [137] = char [‰]
code = [138] = char [ٹ]
code = [139] = char [‹]
code = [140] = char [Œ]
code = [141] = char [چ]
code = [142] = char [ژ]
code = [143] = char [ڈ]
code = [144] = char [گ]
code = [145] = char [‘]
code = [146] = char [’]
code = [147] = char [“]
code = [148] = char [”]
code = [149] = char [•]
code = [150] = char [–]
code = [151] = char [—]
code = [152] = char [ک]
code = [153] = char [™]
code = [154] = char [ڑ]
code = [155] = char [›]
code = [156] = char [œ]
code = [157] = char [‌]
code = [158] = char [‍]
code = [159] = char [ں]
code = [160] = char [ ]
code = [161] = char [،]
code = [162] = char [¢]
code = [163] = char [£]
code = [164] = char [¤]
code = [165] = char [¥]
code = [166] = char [¦]
code = [167] = char [§]
code = [168] = char [¨]
code = [169] = char [©]
code = [170] = char [ھ]
code = [171] = char [«]
code = [172] = char [¬]
code = [173] = char [­]
code = [174] = char [®]
code = [175] = char [¯]
code = [176] = char [°]
code = [177] = char [±]
code = [178] = char [²]
code = [179] = char [³]
code = [180] = char [´]
code = [181] = char [µ]
code = [182] = char [¶]
code = [183] = char [·]
code = [184] = char [¸]
code = [185] = char [¹]
code = [186] = char [؛]
code = [187] = char [»]
code = [188] = char [¼]
code = [189] = char [½]
code = [190] = char [¾]
code = [191] = char [؟]
code = [192] = char [ہ]
code = [193] = char [ء]
code = [194] = char [آ]
code = [195] = char [أ]
code = [196] = char [ؤ]
code = [197] = char [إ]
code = [198] = char [ئ]
code = [199] = char [ا]
code = [200] = char [ب]
code = [201] = char [ة]
code = [202] = char [ت]
code = [203] = char [ث]
code = [204] = char [ج]
code = [205] = char [ح]
code = [206] = char [خ]
code = [207] = char [د]
code = [208] = char [ذ]
code = [209] = char [ر]
code = [210] = char [ز]
code = [211] = char [س]
code = [212] = char [ش]
code = [213] = char [ص]
code = [214] = char [ض]
code = [215] = char [×]
code = [216] = char [ط]
code = [217] = char [ظ]
code = [218] = char [ع]
code = [219] = char [غ]
code = [220] = char [ـ]
code = [221] = char [ف]
code = [222] = char [ق]
code = [223] = char [ك]
code = [224] = char [à]
code = [225] = char [ل]
code = [226] = char [â]
code = [227] = char [م]
code = [228] = char [ن]
code = [229] = char [ه]
code = [230] = char [و]
code = [231] = char [ç]
code = [232] = char [è]
code = [233] = char [é]
code = [234] = char [ê]
code = [235] = char [ë]
code = [236] = char [ى]
code = [237] = char [ي]
code = [238] = char [î]
code = [239] = char [ï]
code = [240] = char [ً]
code = [241] = char [ٌ]
code = [242] = char [ٍ]
code = [243] = char [َ]
code = [244] = char [ô]
code = [245] = char [ُ]
code = [246] = char [ِ]
code = [247] = char [÷]
code = [248] = char [ّ]
code = [249] = char [ù]
code = [250] = char [ْ]
code = [251] = char [û]
code = [252] = char [ü]
code = [253] = char [‎]
code = [254] = char [‏]
code = [255] = char [ے]

and the printed result: As you can see, the characters printed are similar with your documentation epson doc

20200905_082752

rajesh-shanthi commented 4 years ago

Hi , I really appreciate your support and help. I ran out off printer paper, tomorrow will upload the printout. In which OS you are running your application. I am running from a windows 10 OS.

anastaciocintra commented 4 years ago

My printer is one usb TM-T20 epson, with regular epson driver(nothing extra, no special configuration)

My Operating system is windows 10 too, java 8, maven 3.6 For me, to configure the arabic character on terminal, I've used chcp comand

Configuration direct on terminal:

>chcp 1256
>mvn -v
Apache Maven 3.6.0 (97c98ec64a1fdfee7767ce5ffb20918da4f719f3; 2018-10-24T15:41:47-03:00)
Maven home: C:\desenv\apache-maven-3.6.0\bin\..
Java version: 1.8.0_202, vendor: Oracle Corporation, runtime: C:\desenv\Java\jdk1.8.0_202\jre
Default locale: pt_BR, platform encoding: Cp1252
OS name: "windows 10", version: "10.0", arch: "amd64", family: "windows"

It can run direct on intellij too - Mine intelij configuration:

My IDE:

IntelliJ IDEA 2019.3.2 (Community Edition)
Build #IC-193.6015.39, built on January 21, 2020
Runtime version: 11.0.5+10-b520.30 amd64
VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o
Windows 10 10.0
GC: ParNew, ConcurrentMarkSweep
Memory: 1475M
Cores: 8
Registry: ide.balloon.shadow.size=0
Non-Bundled Plugins: Dart, org.jetbrains.kotlin, com.chrisrm.idea.MaterialThemeUI, com.jetbrains.edu, io.flutter, org.exbin.deltahex.intellij
rajesh-shanthi commented 4 years ago

Hi, The terminal output cp1256 List of Java CharSet for charsetName = "cp1256", between 128 and 255 code = [128] = char [€] code = [129] = char [پ] code = [130] = char [‚] code = [131] = char [ƒ] code = [132] = char [„] code = [133] = char […] code = [134] = char [†] code = [135] = char [‡] code = [136] = char [ˆ] code = [137] = char [‰] code = [138] = char [ٹ] code = [139] = char [‹] code = [140] = char [Œ] code = [141] = char [چ] code = [142] = char [ژ] code = [143] = char [ڈ] code = [144] = char [گ] code = [145] = char [‘] code = [146] = char [’] code = [147] = char [“] code = [148] = char [”] code = [149] = char [•] code = [150] = char [–] code = [151] = char [—] code = [152] = char [ک] code = [153] = char [™] code = [154] = char [ڑ] code = [155] = char [›] code = [156] = char [œ] code = [157] = char [‌] code = [158] = char [‍] code = [159] = char [ں] code = [160] = char [ ] code = [161] = char [،] code = [162] = char [¢] code = [163] = char [£] code = [164] = char [¤] code = [165] = char [¥] code = [166] = char [¦] code = [167] = char [§] code = [168] = char [¨] code = [169] = char [©] code = [170] = char [ھ] code = [171] = char [«] code = [172] = char [¬] code = [173] = char [­] code = [174] = char [®] code = [175] = char [¯] code = [176] = char [°] code = [177] = char [±] code = [178] = char [²] code = [179] = char [³] code = [180] = char [´] code = [181] = char [µ] code = [182] = char [¶] code = [183] = char [·] code = [184] = char [¸] code = [185] = char [¹] code = [186] = char [؛] code = [187] = char [»] code = [188] = char [¼] code = [189] = char [½] code = [190] = char [¾] code = [191] = char [؟] code = [192] = char [ہ] code = [193] = char [ء] code = [194] = char [آ] code = [195] = char [أ] code = [196] = char [ؤ] code = [197] = char [إ] code = [198] = char [ئ] code = [199] = char [ا] code = [200] = char [ب] code = [201] = char [ة] code = [202] = char [ت] code = [203] = char [ث] code = [204] = char [ج] code = [205] = char [ح] code = [206] = char [خ] code = [207] = char [د] code = [208] = char [ذ] code = [209] = char [ر] code = [210] = char [ز] code = [211] = char [س] code = [212] = char [ش] code = [213] = char [ص] code = [214] = char [ض] code = [215] = char [×] code = [216] = char [ط] code = [217] = char [ظ] code = [218] = char [ع] code = [219] = char [غ] code = [220] = char [ـ] code = [221] = char [ف] code = [222] = char [ق] code = [223] = char [ك] code = [224] = char [à] code = [225] = char [ل] code = [226] = char [â] code = [227] = char [م] code = [228] = char [ن] code = [229] = char [ه] code = [230] = char [و] code = [231] = char [ç] code = [232] = char [è] code = [233] = char [é] code = [234] = char [ê] code = [235] = char [ë] code = [236] = char [ى] code = [237] = char [ي] code = [238] = char [î] code = [239] = char [ï] code = [240] = char [ً] code = [241] = char [ٌ] code = [242] = char [ٍ] code = [243] = char [َ] code = [244] = char [ô] code = [245] = char [ُ] code = [246] = char [ِ] code = [247] = char [÷] code = [248] = char [ّ] code = [249] = char [ù] code = [250] = char [ْ] code = [251] = char [û] code = [252] = char [ü] code = [253] = char [‎] code = [254] = char [‏] code = [255] = char [ے]

1

3

Attached the screent shot, I am using eclipse and it is a network printer. Epson TM - T82 II model.

rajesh-shanthi commented 4 years ago

Sorry, typo error Attached the screen shot, I am using eclipse 2020 and it is a network printer. Epson TM - T81 II model.

anastaciocintra commented 4 years ago

Hi @rajesh-shanthi, The terminal output of yours test is equivalent, your java environment (SO + JRE) is ok with charset cp1256 configuration.

In other hand, the printed output of page 50 is not equivalent with epson documentation (page 50).

your printer output of page 50 is similar with page 0.

diagnosis of this test for arabic cp1256: Java environment is ok.

printer response: not ok.

Unfortunetly, your printer (in actual configuration) does not have suport for page 50.

you can discover wich pages your printer can recognize doing the samething with other pagecodes or if you find some good for Arabic language:

printCodeTable(escpos,0,128,255); and compare with page 0

printCodeTable(escpos,1,128,255); and compare with page 1

printCodeTable(escpos,2,128,255); and compare with page 2

and so on... 3,4,5

imho, you can focus on your printers driver, configuration or firmware, etc.

other possibility is to print bitmaps with arabic text as described above.

rajesh-shanthi commented 4 years ago

Hi,

Even though the Arabic printing did not work in my local Epson TM-T81 printer, in the client printer (Tyssso) it worked printing Arabic by setting the codepage table to 22 manually as suggested by you. I would like thank you very much for the invaluable support provided by you. Thanks a lot.

One last question i have regarding the below

other possibility is to print bitmaps with arabic text as described above.

Do we need to create a bitmap image of string text and then using library to print or

Does the library itself has inbuilt support to for a text string to create as image and then print it as image .

If you have any examples please let me know.

Regards,

Rajesh.

anastaciocintra commented 4 years ago

Hi @rajesh-shanthi good news.

It was my pleasure to help you.

So... about bitmap, the idea is to work with pdf or html or xyz technology and set one bitmap image with this content and then print on escpos.

I made one example, using java Graphics2D you can draw, transform, rotate etc.., read more on java Doc Graphics 2D

follow one kickoff code, I hope it helps Soon, I'll put this code on sample code

till later

/*
MIT License

Copyright (c) 2020 Marco Antonio Anastacio Cintra <anastaciocintra@gmail.com>

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
 */
import com.github.anastaciocintra.escpos.EscPos;
import com.github.anastaciocintra.escpos.EscPosConst;
import com.github.anastaciocintra.escpos.image.*;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.CharConversionException;
import java.io.File;
import java.io.IOException;

import static java.awt.image.BufferedImage.TYPE_INT_RGB;

public class CoffeeBitmap implements Exec{
    @Override
    public void exec(EscPos escpos) throws IOException {
        final int FontSize = 30;
        final String arabicText = "الصفحة الرئيسية";
        // 1 - create one buffered image with width and height
        BufferedImage image = new BufferedImage(576, 150, TYPE_INT_RGB);
        Graphics2D g = image.createGraphics();

        // change background and foregroud colors
        g.setColor(Color.white);
        g.fillRect(0, 0, g.getDeviceConfiguration().getBounds().width, g.getDeviceConfiguration().getBounds().height);
        g.setColor(Color.BLACK);

        // choose your font
        //OBS: not all fonts work well with Arabic language
        // read more on https://docs.oracle.com/javase/tutorial/2d/text/advanced.html
        //
        // choose the font... below you have some combinations
        Font fontMonoSpacePlan = new Font (Font.MONOSPACED, Font.PLAIN, FontSize);
        Font fontMonoSpaceBold = new Font (Font.MONOSPACED, Font.BOLD, FontSize);
        Font fontMonoSpaceBoldItalic = new Font (Font.MONOSPACED, Font.ITALIC|Font.BOLD, FontSize);
        Font fontSerifPlan = new Font (Font.SERIF, Font.PLAIN, FontSize);
        Font fontSerifBold = new Font (Font.SERIF, Font.BOLD, FontSize);
        Font fontSansSerif = new Font (Font.SANS_SERIF, Font.PLAIN, FontSize);
        Font fontSansSerifBold = new Font (Font.SANS_SERIF, Font.BOLD, FontSize);
        // doc about canDisplayUpTo
        /**
         * Indicates whether or not this <code>Font</code> can display a
         * specified <code>String</code>.  For strings with Unicode encoding,
         * it is important to know if a particular font can display the
         * string. This method returns an offset into the <code>String</code>
         * <code>str</code> which is the first character this
         * <code>Font</code> cannot display without using the missing glyph
         * code. If the <code>Font</code> can display all characters, -1 is
         * returned.
         * @param str a <code>String</code> object
         * @return an offset into <code>str</code> that points
         *          to the first character in <code>str</code> that this
         *          <code>Font</code> cannot display; or <code>-1</code> if
         *          this <code>Font</code> can display all characters in
         *          <code>str</code>.
         * @since 1.2
         */

        // ..
        // you can test the font
        if(fontMonoSpaceBold.canDisplayUpTo(arabicText) != -1){
            throw new CharConversionException("the font doesn't work with these glyphs");
        }

        // set the font to be used
        g.setFont(fontMonoSpaceBold);

        // write your text
        g.drawString("hello Arabian Character", 1, 90);

        // other line ...
        g.drawString("الصفحة الرئيسية", 1, 140);

        // send the graphic to the escpos printer...
        escpos.write(new GraphicsImageWrapper(),new EscPosImage(new CoffeeImageImpl(image),new BitonalThreshold()));
        escpos.feed(5).cut(EscPos.CutMode.FULL);

        // for debug purposes, you can save the graphic
        /* DEBUG
        File output = new File("C:\\Users\\macin\\desenv\\arabic.png");
        ImageIO.write(image, "png", output);
        DEBUG */

    }
}

20200911_083211

ralmarri12 commented 4 years ago

Hello @anastaciocintra , I had same problem with #47 it still shows question marks, however, I tried to convert it to image it shows me like that attachment.

image

I also saved the image generated from java and it was correct but the printing result is not what it should be.

My printer called EVELON, .. EV - C50,

computer recognise it as POS-80

I really don't know how to solve this issue, please help.

anastaciocintra commented 4 years ago

Hi @ralmarri12

did your problem happened exactly with this code?

Hi @rajesh-shanthi good news.

It was my pleasure to help you.

So... about bitmap, the idea is to work with pdf or html or xyz technology and set one bitmap image with this content and then print on escpos.

I made one example, using java Graphics2D you can draw, transform, rotate etc.., read more on java Doc Graphics 2D

follow one kickoff code, I hope it helps Soon, I'll put this code on sample code

till later

/*
MIT License

Copyright (c) 2020 Marco Antonio Anastacio Cintra <anastaciocintra@gmail.com>

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
 */
import com.github.anastaciocintra.escpos.EscPos;
import com.github.anastaciocintra.escpos.EscPosConst;
import com.github.anastaciocintra.escpos.image.*;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.CharConversionException;
import java.io.File;
import java.io.IOException;

import static java.awt.image.BufferedImage.TYPE_INT_RGB;

public class CoffeeBitmap implements Exec{
    @Override
    public void exec(EscPos escpos) throws IOException {
        final int FontSize = 30;
        final String arabicText = "الصفحة الرئيسية";
        // 1 - create one buffered image with width and height
        BufferedImage image = new BufferedImage(576, 150, TYPE_INT_RGB);
        Graphics2D g = image.createGraphics();

        // change background and foregroud colors
        g.setColor(Color.white);
        g.fillRect(0, 0, g.getDeviceConfiguration().getBounds().width, g.getDeviceConfiguration().getBounds().height);
        g.setColor(Color.BLACK);

        // choose your font
        //OBS: not all fonts work well with Arabic language
        // read more on https://docs.oracle.com/javase/tutorial/2d/text/advanced.html
        //
        // choose the font... below you have some combinations
        Font fontMonoSpacePlan = new Font (Font.MONOSPACED, Font.PLAIN, FontSize);
        Font fontMonoSpaceBold = new Font (Font.MONOSPACED, Font.BOLD, FontSize);
        Font fontMonoSpaceBoldItalic = new Font (Font.MONOSPACED, Font.ITALIC|Font.BOLD, FontSize);
        Font fontSerifPlan = new Font (Font.SERIF, Font.PLAIN, FontSize);
        Font fontSerifBold = new Font (Font.SERIF, Font.BOLD, FontSize);
        Font fontSansSerif = new Font (Font.SANS_SERIF, Font.PLAIN, FontSize);
        Font fontSansSerifBold = new Font (Font.SANS_SERIF, Font.BOLD, FontSize);
        // doc about canDisplayUpTo
        /**
         * Indicates whether or not this <code>Font</code> can display a
         * specified <code>String</code>.  For strings with Unicode encoding,
         * it is important to know if a particular font can display the
         * string. This method returns an offset into the <code>String</code>
         * <code>str</code> which is the first character this
         * <code>Font</code> cannot display without using the missing glyph
         * code. If the <code>Font</code> can display all characters, -1 is
         * returned.
         * @param str a <code>String</code> object
         * @return an offset into <code>str</code> that points
         *          to the first character in <code>str</code> that this
         *          <code>Font</code> cannot display; or <code>-1</code> if
         *          this <code>Font</code> can display all characters in
         *          <code>str</code>.
         * @since 1.2
         */

        // ..
        // you can test the font
        if(fontMonoSpaceBold.canDisplayUpTo(arabicText) != -1){
            throw new CharConversionException("the font doesn't work with these glyphs");
        }

        // set the font to be used
        g.setFont(fontMonoSpaceBold);

        // write your text
        g.drawString("hello Arabian Character", 1, 90);

        // other line ...
        g.drawString("الصفحة الرئيسية", 1, 140);

        // send the graphic to the escpos printer...
        escpos.write(new GraphicsImageWrapper(),new EscPosImage(new CoffeeImageImpl(image),new BitonalThreshold()));
        escpos.feed(5).cut(EscPos.CutMode.FULL);

        // for debug purposes, you can save the graphic
        /* DEBUG
        File output = new File("C:\\Users\\macin\\desenv\\arabic.png");
        ImageIO.write(image, "png", output);
        DEBUG */

    }
}
anastaciocintra commented 4 years ago

hi @ralmarri12 if you are generating big image for the printer, you can run in trouble. It's because buffer of the printer can overflow. maybe you need to slice the image in small pieces.

take a look on https://github.com/anastaciocintra/escpos-coffee-samples/tree/master/miscellaneous/sliceimage

get the ImageHelper.java

you can test by changing this

        // send the graphic to the escpos printer...
        escpos.write(new GraphicsImageWrapper(),new EscPosImage(new CoffeeImageImpl(image),new BitonalThreshold()));
        escpos.feed(5).cut(EscPos.CutMode.FULL);

by this

        // send the graphic to the escpos printer...
        ImageHelper helper = new ImageHelper();
        Bitonal algorithm = new BitonalThreshold();
        GraphicsImageWrapper imageWrapper = new GraphicsImageWrapper();
        helper.write(escPos, new CoffeeImageImpl(image),imageWrapper,algorithm);

        escPos.feed(5).cut(EscPos.CutMode.FULL);
        escPos.close();

I hope that it works, see you

ralmarri12 commented 4 years ago

Hello @anastaciocintra

I'm very thankful for your fast response, however, I still get the same result.

Let me give you an overview of everything here I believe you will understand what might be the problem better than my understanding.

All I need is typing Arabic in the bill, so I got a printer that no any related reference found in the Internet. It called Evelon EV-C50.

When I install the driver, I could see that it called POS-80, so I'm optimistic that this library will fit in. it works fine when I use English, therefore, when I use Arabic, depend on the codepage, sometimes it shows me weird looking characters and sometimes just question marks.

so I have tried this code you have provided,

void printCodeTable(EscPos escpos, int codeTable, int codMin, int codMax) throws IOException {
        escpos.setCharacterCodeTable(EscPos.CharacterCodeTable.CP437_USA_Standard_Europe);
        escpos.writeLF(String.format("character code table for code [%d], " +
                "\nbetween %d and %d", codeTable,codMin, codMax));
        escpos.setPrinterCharacterTable(codeTable);
        for(int code = codMin; code <= codMax; code++){
            escpos.write(code);
            escpos.write("  ");

        }
        escpos.writeLF("");
        escpos.feed(5).cut(EscPos.CutMode.FULL);

    }

and I tried (code table 22) which printed very nice results as below,

image

I felt optimistic because first time I see Arabic characters appeared from the printer.

but when I use this code

        escpos.setPrinterCharacterTable(22);        
        escpos.writeLF("مرحبا بالعالم");

The result shows question marks image

I cannot understand the issue, and ways to solve it.

so I tried the (image solution) and I got the result that you have seen in previous comment

even when I use class ImageHelper.

Thank you for your responses and help @anastaciocintra

ralmarri12 commented 4 years ago

This is the selftest result from my printer if it might help,

image

image

ralmarri12 commented 4 years ago

this is my code

Main.java

package printingRecipt;
import com.github.anastaciocintra.escpos.EscPos;
import com.github.anastaciocintra.output.PrinterOutputStream;
import java.io.CharConversionException;
import java.io.IOException;
import javax.print.PrintService;

/**
 *
 * @author rashid
 */
public class Main {

    public static void main(String[] args) throws CharConversionException, IOException {
        PrintService printService = PrinterOutputStream.getPrintServiceByName("Printer POS-80");
        PrinterOutputStream printerOutputStream = new PrinterOutputStream(printService);
        try (EscPos escpos = new EscPos(printerOutputStream)) {

            CoffeeBitmap map = new CoffeeBitmap();
            map.exec(escpos);

        }    
    }

}

CoffeeBitmap.java

package printingRecipt;

import com.github.anastaciocintra.escpos.EscPos;
import com.github.anastaciocintra.escpos.image.Bitonal;
import com.github.anastaciocintra.escpos.image.BitonalThreshold;
import com.github.anastaciocintra.escpos.image.CoffeeImageImpl;
import com.github.anastaciocintra.escpos.image.GraphicsImageWrapper;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import static java.awt.image.BufferedImage.TYPE_INT_RGB;
import java.io.CharConversionException;
import java.io.IOException;

public class CoffeeBitmap {

    public void exec(EscPos escpos) throws IOException {

        final int FontSize = 30;
        final String arabicText = "الصفحة الرئيسية";
        // 1 - create one buffered image with width and height
        BufferedImage image = new BufferedImage(576, 150, TYPE_INT_RGB);
        Graphics2D g = image.createGraphics();

        // change background and foregroud colors
        g.setColor(Color.white);
        g.fillRect(0, 0, g.getDeviceConfiguration().getBounds().width, g.getDeviceConfiguration().getBounds().height);
        g.setColor(Color.BLACK);

        // choose your font
        //OBS: not all fonts work well with Arabic language
        // read more on https://docs.oracle.com/javase/tutorial/2d/text/advanced.html
        //
        // choose the font... below you have some combinations
        Font fontMonoSpacePlan = new Font (Font.MONOSPACED, Font.PLAIN, FontSize);
        Font fontMonoSpaceBold = new Font (Font.MONOSPACED, Font.BOLD, FontSize);
        Font fontMonoSpaceBoldItalic = new Font (Font.MONOSPACED, Font.ITALIC|Font.BOLD, FontSize);
        Font fontSerifPlan = new Font (Font.SERIF, Font.PLAIN, FontSize);
        Font fontSerifBold = new Font (Font.SERIF, Font.BOLD, FontSize);
        Font fontSansSerif = new Font (Font.SANS_SERIF, Font.PLAIN, FontSize);
        Font fontSansSerifBold = new Font (Font.SANS_SERIF, Font.BOLD, FontSize);
        // doc about canDisplayUpTo
        /**
         * Indicates whether or not this <code>Font</code> can display a
         * specified <code>String</code>.  For strings with Unicode encoding,
         * it is important to know if a particular font can display the
         * string. This method returns an offset into the <code>String</code>
         * <code>str</code> which is the first character this
         * <code>Font</code> cannot display without using the missing glyph
         * code. If the <code>Font</code> can display all characters, -1 is
         * returned.
         * @param str a <code>String</code> object
         * @return an offset into <code>str</code> that points
         *          to the first character in <code>str</code> that this
         *          <code>Font</code> cannot display; or <code>-1</code> if
         *          this <code>Font</code> can display all characters in
         *          <code>str</code>.
         * @since 1.2
         */

        // ..
        // you can test the font
        if(fontMonoSpaceBold.canDisplayUpTo(arabicText) != -1){
            throw new CharConversionException("the font doesn't work with these glyphs");
        }

        // set the font to be used
        g.setFont(fontMonoSpaceBold);

        // write your text
        g.drawString("hello Arabian Character", 1, 90);

        // other line ...
//        g.drawString("الصفحة الرئيسية", 1, 140);

        // send the graphic to the escpos printer...
        ImageHelper helper = new ImageHelper();
        Bitonal algorithm = new BitonalThreshold();
        GraphicsImageWrapper imageWrapper = new GraphicsImageWrapper();
        helper.write(escpos, new CoffeeImageImpl(image),imageWrapper,algorithm);

        escpos.feed(5).cut(EscPos.CutMode.FULL);
        escpos.close();

    }

    public void printCodeTable(EscPos escpos, int codeTable, int codMin, int codMax) throws IOException {
        escpos.setCharacterCodeTable(EscPos.CharacterCodeTable.CP437_USA_Standard_Europe);
        escpos.writeLF(String.format("character code table for code [%d], " +
                "\nbetween %d and %d", codeTable,codMin, codMax));
        escpos.setPrinterCharacterTable(codeTable);
        for(int code = codMin; code <= codMax; code++){
            escpos.write(code);
            escpos.write("  ");

        }
        escpos.writeLF("");
        escpos.feed(5).cut(EscPos.CutMode.FULL);

    }
}
anastaciocintra commented 4 years ago

I got it.

you have on page 22 the charset cp864

try this configuration:

        escpos.setCharsetName("cp864");
        escpos.setPrinterCharacterTable(22);
anastaciocintra commented 4 years ago

compare your printer 22 output with cp864 that you will find similarities.

ralmarri12 commented 4 years ago

Hello @anastaciocintra

this code still prints ????? ????? question marks

        escpos.setCharsetName("cp864");
        escpos.setPrinterCharacterTable(22);

        escpos.writeLF("تجربة تجربة");
        escpos.feed(5);
        escpos.cut(EscPos.CutMode.FULL);
        escpos.close();
anastaciocintra commented 4 years ago

can you print this?

        escpos.writeLF("ﻱﻙﻝﻶﻵﻕﻐﻥ");
ralmarri12 commented 4 years ago

@anastaciocintra yes, it shows up same string reversed from left to right

image
anastaciocintra commented 4 years ago

Ok, try other combination escpos.setCharsetName("cp864"); escpos.setPrinterCharacterTable(63);

ralmarri12 commented 4 years ago
image

this is what I got. however I found something

I tried this code

        Integer a = new Integer('ت');

        System.out.println(a.byteValue());

the result was 42

is that some related to the error? it might be encoding format or something>

anastaciocintra commented 4 years ago

I'm reading your printer dump information to try some combinations

one more

        escpos.setCharsetName("cp1256");
        escpos.setPrinterCharacterTable(33);
ralmarri12 commented 4 years ago

Still question marks

anastaciocintra commented 4 years ago

do you can write some phrases with this table ? 864

anastaciocintra commented 4 years ago

have your printer capability to print image?

ralmarri12 commented 4 years ago

have your printer capability to print image?

yes, but as maintained before when I create image in java it shows me

in fact, I don't care if it is image or text as it printed the arabic text.

anastaciocintra commented 4 years ago

Ok, focus on image problem...

can you throw your generated image file here then I ll try to print this same image on mine printer ... or if you preffer, send me in particular on anastaciocintra@gmail.com

ralmarri12 commented 4 years ago

I didn't make any image, just trying to generate any image to see that works then I will design the receipt looking. as I see it worked with you

it just the same code I copy but .. I got,

image
anastaciocintra commented 4 years ago

ok Im trying to do some code to test it,

in parallel, can you test the printed output of this

and this prepare a lot of paper ... 1 meter

ralmarri12 commented 4 years ago

it's ok, I have 2 rolls for testing, let me try to append these codes in my project and will show u the result

ralmarri12 commented 4 years ago

can you tell me from where I get (SamplesCommon) class? and SliceImage class as well

anastaciocintra commented 4 years ago

do you have maven command line?

ralmarri12 commented 4 years ago

Nope, but I'm using NetBeans, so I can add dependences in the project. btw, I'm not that professional in Java

anastaciocintra commented 4 years ago

ok the samples common is here https://github.com/anastaciocintra/escpos-coffee-samples/tree/master/usual/samples-common

anastaciocintra commented 4 years ago

I made the jar just run ... java -jar graphics-image-4.0.1-jar-with-dependencies.jar tm-t20-usb

graphics-image-4.0.1-jar-with-dependencies.jar.zip

anastaciocintra commented 4 years ago

it should print some "github" images

ralmarri12 commented 4 years ago

yeah that's

I made the jar just run ... java -jar graphics-image-4.0.1-jar-with-dependencies.jar tm-t20-usb

graphics-image-4.0.1-jar-with-dependencies.jar.zip

yeah thank you what helps me run the code,

the result

image

no image at all :(

anastaciocintra commented 4 years ago

uhhh it is bad

other two ... run that... if it is printing other than images try to cancel turning off your printer to save paper...

raster-image-4.0.1-jar-with-dependencies.jar.zip bitimage-4.0.1-jar-with-dependencies.jar.zip

this are other two algorithms to pritnt images.....

ralmarri12 commented 4 years ago

good news, Raster-image worked fine

image

anastaciocintra commented 4 years ago

good try this:

import com.github.anastaciocintra.escpos.EscPos;
import com.github.anastaciocintra.escpos.image.*;
import image.ImageHelper;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.CharConversionException;
import java.io.IOException;

import static java.awt.image.BufferedImage.TYPE_INT_RGB;

public class CoffeeBitmap2 {

    public void exec(EscPos escpos) throws IOException {

        final int FontSize = 30;
//        final String arabicText = "الصفحة الرئيسية";
        final String arabicText = "تجربة تجربة";
        // 1 - create one buffered image with width and height
        BufferedImage image = new BufferedImage(576, 150, TYPE_INT_RGB);
        Graphics2D g = image.createGraphics();

        // change background and foregroud colors
        g.setColor(Color.white);
        g.fillRect(0, 0, g.getDeviceConfiguration().getBounds().width, g.getDeviceConfiguration().getBounds().height);
        g.setColor(Color.BLACK);

        // choose your font
        //OBS: not all fonts work well with Arabic language
        // read more on https://docs.oracle.com/javase/tutorial/2d/text/advanced.html
        //
        // choose the font... below you have some combinations
        Font fontMonoSpacePlan = new Font (Font.MONOSPACED, Font.PLAIN, FontSize);
        Font fontMonoSpaceBold = new Font (Font.MONOSPACED, Font.BOLD, FontSize);
        Font fontMonoSpaceBoldItalic = new Font (Font.MONOSPACED, Font.ITALIC|Font.BOLD, FontSize);
        Font fontSerifPlan = new Font (Font.SERIF, Font.PLAIN, FontSize);
        Font fontSerifBold = new Font (Font.SERIF, Font.BOLD, FontSize);
        Font fontSansSerif = new Font (Font.SANS_SERIF, Font.PLAIN, FontSize);
        Font fontSansSerifBold = new Font (Font.SANS_SERIF, Font.BOLD, FontSize);
        // doc about canDisplayUpTo
        /**
         * Indicates whether or not this <code>Font</code> can display a
         * specified <code>String</code>.  For strings with Unicode encoding,
         * it is important to know if a particular font can display the
         * string. This method returns an offset into the <code>String</code>
         * <code>str</code> which is the first character this
         * <code>Font</code> cannot display without using the missing glyph
         * code. If the <code>Font</code> can display all characters, -1 is
         * returned.
         * @param str a <code>String</code> object
         * @return an offset into <code>str</code> that points
         *          to the first character in <code>str</code> that this
         *          <code>Font</code> cannot display; or <code>-1</code> if
         *          this <code>Font</code> can display all characters in
         *          <code>str</code>.
         * @since 1.2
         */

        // ..
        // you can test the font
        if(fontMonoSpaceBold.canDisplayUpTo(arabicText) != -1){
            throw new CharConversionException("the font doesn't work with these glyphs");
        }

        // set the font to be used
        g.setFont(fontMonoSpaceBold);

        // write your text
        g.drawString("hello Arabian Character", 1, 90);

        // other line ...
        g.drawString(arabicText, 1, 140);

        // send the graphic to the escpos printer...
        ImageHelper helper = new ImageHelper();
        Bitonal algorithm = new BitonalThreshold();
//        GraphicsImageWrapper imageWrapper = new GraphicsImageWrapper();
        RasterBitImageWrapper imageWrapper = new RasterBitImageWrapper();
        helper.write(escpos, new CoffeeImageImpl(image),imageWrapper,algorithm);

        escpos.feed(5).cut(EscPos.CutMode.FULL);
        escpos.close();

    }

    public void printCodeTable(EscPos escpos, int codeTable, int codMin, int codMax) throws IOException {
        escpos.setCharacterCodeTable(EscPos.CharacterCodeTable.CP437_USA_Standard_Europe);
        escpos.writeLF(String.format("character code table for code [%d], " +
                "\nbetween %d and %d", codeTable,codMin, codMax));
        escpos.setPrinterCharacterTable(codeTable);
        for(int code = codMin; code <= codMax; code++){
            escpos.write(code);
            escpos.write("  ");

        }
        escpos.writeLF("");
        escpos.feed(5).cut(EscPos.CutMode.FULL);

    }
}
ralmarri12 commented 4 years ago

both worked fine image

anastaciocintra commented 4 years ago

yeap, good I changed on yor code this part

//        GraphicsImageWrapper imageWrapper = new GraphicsImageWrapper(); // changed this 
        RasterBitImageWrapper imageWrapper = new RasterBitImageWrapper();  // by this
ralmarri12 commented 4 years ago

yesssssssssssssssssss it worrrrked

image

thank you very very very very much you've saved my job

anastaciocintra commented 4 years ago

uhhhuuuu

really nice

intercontinental team !!! good luck on your job my friend

see you bye

anastaciocintra commented 4 years ago

Hey @ralmarri12 take a look at new sample of bitmap builder... it is a lot of easier https://github.com/anastaciocintra/escpos-coffee-samples/tree/master/miscellaneous/CoffeeBitmap