5

How to convert /assets/image.png to byte[] ?

I've tried like that (based on solution found on SO):

public void printimage(View view) {
    AssetManager assetManager = getAssets();
    InputStream inputStream = null;

    try {
        inputStream = assetManager.open("logo_print.png");
        byte[] bytesLogo = IOUtils.toByteArray(inputStream);

        int ret = printer.printImage(bytesLogo);

        if (ret < 0) {
            Toast(context, "printimage fail");
        }
        Toast(context, "image printed :)");

    }
    catch (IOException e){
        Log.e("message: ", e.getMessage());
        Toast(context, "printimage: convert image to Bytes fail");
    }
}

printImage — is declared in package like this:

public class Cprinter {
    public native int printImage(byte[] bytes);
}

But application crashes on print printimage(), error is "Native method not found: android.pt.Cprinter.printImage:([B)I"

I've converted byte to string (bytesLogo.toString()), every execution of this command returns different results: "[B@40d7c798", "[B@40d848e0", "[B@40d59ff0", & etc.

Purpose: I have an android device with internal printer of receipts. Vendor has provided library (libfile.so) and sample source for developing own software for device. Printing Simple text is OK, but i have a troubles with printing of an Image (logo).

Here is the vendors` tiny documentation.

p.s:I'm newbie in Java.

deeplay
  • 376
  • 3
  • 20

4 Answers4

8

Try this

   InputStream inputStream = getAssets().open("logo_print.png");

    byte[] buffer = new byte[8192];
    int bytesRead;
    ByteArrayOutputStream output = new ByteArrayOutputStream();
    while ((bytesRead = inputStream.read(buffer)) != -1) {
        output.write(buffer, 0, bytesRead);
    }
    byte file[] = output.toByteArray();

the byte array contains

1B 2A n ml mh converted data 1B 4A 00

1B 2A -- begin the block

n - printing mode
  a) Q110 support 4 kinds of printing modes,as follow:

    n=0x21: 24-point double-density;

    n=0x20: 24-point single-density;

    n=0x01: 8-point double-density;

    n=0x00: 8-point single-density;

  b) NXP only support n=0x21: 24-point double-density;

converted data

1B 4A 00 end the block and execute print (print start)

like wise

byte[0] = 0x1B;
byte[1] = 0x2A;
byte[2] = 0x21; // 24-point double-density;

and so on...
arun
  • 1,728
  • 15
  • 15
  • On executing printimage() same error occurs: _Caused by: java.lang.UnsatisfiedLinkError: Native method not found: android.pt.Cprinter.printImage:([B)I_ – deeplay Mar 24 '16 at 11:51
  • 1
    in the document cant directly print entire image must be divided multiple units. so u need to divide the image – arun Mar 24 '16 at 12:14
  • thx for reading doc. any ideas how to do that? if it's means, that printing of a small image will give a positive result, i can test it right now. – deeplay Mar 24 '16 at 12:17
  • i've just tested with 4x3px jpg, same error on executing printimage(). – deeplay Mar 24 '16 at 12:22
  • to be honest, Arun, it's difficult to understand for me, can you please share some example for work with your solution? – deeplay Mar 24 '16 at 13:24
  • as your document you need to print 1B 2A n ml mh converted data 1B 4A 00 like wise. you can print full width and height of 24 point. ex if your image has 240x240 then print first 240x24 and next 240x24 and so on – arun Mar 24 '16 at 13:28
  • you mean, that every variable for printing must be with structure like this: "0x1B", "0x2A", "0x21" , "bytes of image (max 24 px height in 24-point double-density)", "0x1B", "0x4A", "0x00" Right? And what means "ml mh" in your answer? – deeplay Mar 24 '16 at 13:45
  • yes. but not the bytes of image and you miss the ml and mh ( mh = width/256, ml = width%256). – arun Mar 24 '16 at 13:53
  • can i use your first method for converting to byte array, and then add to beginning ("0x1B", "0x2A", "0x21", mL mH) and end ("0x1B", "0x4A", "0x00") values ? – deeplay Mar 24 '16 at 14:04
  • Also please explain me (if possible) this example from documentation: "image’s width is 169 points, 169=mL+mH*256=169+0*256=A9+0*256,so the mL mH are A9,00;" mL is 169 (width) - ok, but why mh is 0 ? – deeplay Mar 24 '16 at 14:06
  • yeah already I said mh = width/256; ml = width%256; so if width = 169 then mh = 169/256 = 0 and ml = 169 % 256 = 169 hence mh =0 and ml = 169, also 169 is convert to hexadecimal A9 – arun Mar 25 '16 at 04:58
  • @deeplay is that the printer is b/w. – arun Mar 25 '16 at 05:09
  • yes, it's black/white thermal printer for printing receipts, bar-codes etc. – deeplay Mar 25 '16 at 06:13
  • What i understand from the doc. 24 points to 3*8 bits = 24. so each bit is a point. so you need to get the first point whether white or black if white then 0 else black 1 (may be 0 black 1 white) 24 points from left to bottom. and arrange as 3 byte. you need do this step for entire width and print. and continue unit. – arun Mar 25 '16 at 06:25
  • 1
    and don't forget if the height is less than 24 points you need to add empty byte 0. (a column must be 3 byte). – arun Mar 25 '16 at 06:28
4

Copy your image into drawable folder. Then follow the steps:

  Drawable drawable= getResources().getDrawable(R.drawable.image);

Type cast into BitmapDrawable,

  Bitmap bitmap = ((BitmapDrawable)drawable).getBitmap();
  ByteArrayOutputStream out = new ByteArrayOutputStream();
  bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
  byte[] buffer= stream.toByteArray();

You can also try below code for asset folder image:

  InputStream stream= null;
    try {
        stream = getAssets().open("fileName.extension");
        byte[] fileBytes=new byte[stream.available()];
        stream.read(fileBytes);
        stream.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
Saritha G
  • 2,588
  • 1
  • 15
  • 27
  • I tried your second solution, but same error occurs: _Caused by: java.lang.UnsatisfiedLinkError: Native method not found: android.pt.Cprinter.printImage:([B)I_ – deeplay Mar 24 '16 at 12:00
  • How your r specifying the parameter in native..? – Saritha G Mar 24 '16 at 12:01
  • in error message looks like code has been breaked off and bracket not closed - printImage:([B)I – deeplay Mar 24 '16 at 12:02
  • This issue may be there is in your in native method. – Saritha G Mar 24 '16 at 12:04
  • `package android.pt; import android.util.Log; public class Cprinter { public native int printImage(byte[] bytes); static { try { Log.i("ed", "load cprinter lib"); System.loadLibrary("cprinter"); } catch (Exception e) { Log.e("ed", "can not load cprinter lib"); e.printStackTrace(); } } }` – deeplay Mar 24 '16 at 12:05
  • you can declare the native method is same class once..and call it without using class object. – Saritha G Mar 24 '16 at 12:08
  • there is a lot of methods in this class (printImage(byte[] bytes)), I've only posted related one. for example there is method printString(String string) and it's works excellent. – deeplay Mar 24 '16 at 12:11
  • android.pt.Cprinter.printImage() this is clearly specifying that your native method which u declared or defined is wrong. This is not prblm with converting image into byte[]. Once comment the native method calling code, then check. – Saritha G Mar 24 '16 at 12:32
  • Can your show me your native method implementation..? – Saritha G Mar 24 '16 at 12:38
  • As i understand, you want to see implementation of printImage(byte[] bytes). If yes — i unable to do that, because it's a compiled library (i haven't source code): `System.loadLibrary("cprinter")` – deeplay Mar 24 '16 at 12:43
  • Who has implemented native code. And jus check the code weather the native printImage() method has jbyteArray parameter r not.. – Saritha G Mar 24 '16 at 12:45
  • compiled library provided by device manufacturer (they are from China). and this library not specially developed for me, it's serial production, and other customers (according to the manufacturer) are happy with this device & library. – deeplay Mar 24 '16 at 12:53
  • Then what is the problm? – Saritha G Mar 24 '16 at 12:55
  • Problem - i can't use this feature of device (printing of image on receipt). As for your question _"check the code weather the native printImage() method has jbyteArray parameter r not"_ — i tried to send a string to see error message changing or not: _Native method not found: android.pt.Cprinter.printImage:(Ljava/lang/String;)I_ – deeplay Mar 24 '16 at 13:07
  • I think package or parameter of the native method is wrong. printImage() with string parameter is not found, means that method is not there in native. Mean while printImage() with byteArray is also not there. – Saritha G Mar 24 '16 at 13:10
  • Can you check the return type of the native method..is it int or smthng else? – Saritha G Mar 24 '16 at 13:13
  • Without knowing native method implementation, how could you declare it...This exception you may get b'coz of package name or smthng else. – Saritha G Mar 24 '16 at 13:24
4

This works for any type of file in the asset folder

InputStream is = getAssets().open("image.png");
byte[] fileBytes=new byte[is.available()];
is.read( fileBytes);
is.close();
Hai Hw
  • 1,397
  • 1
  • 16
  • 24
0

Try this:

String filePath="file:///android_asset/logo_print.png";
Drawable d = Drawable.createFromPath(filePath);

And this.

Community
  • 1
  • 1
Volodymyr Kulyk
  • 6,455
  • 3
  • 36
  • 63
  • Thx for your answer, but i'm not sure, that you correctly understood my question. As you can see printImage(byte[] bytes) is "waiting" for byte[] – deeplay Mar 24 '16 at 11:10