When i try to write the code like this error occurs:
doInBackground(String...)' in 'com.....QrGenerator' clashes with 'doInBackground(Params...)' in 'android.os.AsyncTask'; overridden method does not throw 'com.google.zxing.WriterException'
Here is the code:
private class QrGenerator extends AsyncTask<String,Integer,Bitmap>{
#Override
protected Bitmap doInBackground(String... strings) throws WriterException {
StringBuilder strBuilder = new StringBuilder();
for (int i = 0; i < strings.length; i++) {
strBuilder.append(strings[i]);
}
String value = strBuilder.toString();
BitMatrix bitMatrix;
try {
bitMatrix = new MultiFormatWriter().encode(
value,
BarcodeFormat.DATA_MATRIX.QR_CODE,
QRcodeWidth, QRcodeWidth, null
);
} catch (IllegalArgumentException Illegalargumentexception) {
return null;
}
int bitMatrixWidth = bitMatrix.getWidth();
int bitMatrixHeight = bitMatrix.getHeight();
int[] pixels = new int[bitMatrixWidth * bitMatrixHeight];
for (int y = 0; y < bitMatrixHeight; y++) {
int offset = y * bitMatrixWidth;
for (int x = 0; x < bitMatrixWidth; x++) {
pixels[offset + x] = bitMatrix.get(x, y) ?
getResources().getColor(R.color.QRCodeBlackColor) : getResources().getColor(R.color.QRCodeWhiteColor);
}
}
Bitmap bitmap = Bitmap.createBitmap(bitMatrixWidth, bitMatrixHeight, Bitmap.Config.ARGB_4444);
bitmap.setPixels(pixels, 0, 500, 0, 0, bitMatrixWidth, bitMatrixHeight);
return bitmap;
}
#Override
protected void onPostExecute(Bitmap bitmap) {
super.onPostExecute(bitmap);
imageView.setImageBitmap(bitmap);
}
}
You cannot throw additional exceptions in overriden methods, like doInBackground(...). See this link. You have to catch the exception within your method. I modified your method to also catch the WriterException.
try {
bitMatrix = new MultiFormatWriter().encode(
value,
BarcodeFormat.DATA_MATRIX.QR_CODE,
33, 33, null
);
} catch (IllegalArgumentException | WriterException e1) {
e1.printStackTrace();
return null;
}
Related
I'm reading the data from a serial port using InputStream.
One part of the stream I need to convert to String, and the other one to binary data.
I already have two methods, and each one does what is needed, but I need to send the data from the serial port twice for both methods to work
My question is if I can somehow split the stream so I can get all of the data to two methods in one send from the serial port?
private static void readingBytesSN(SerialPort comPort) {
comPort.addDataListener(new SerialPortDataListener() {
#Override
public int getListeningEvents() {
return SerialPort.LISTENING_EVENT_DATA_AVAILABLE;
}
#Override
public void serialEvent(SerialPortEvent serialPortEvent) {
InputStream in;
String startSn2 = "110000010011010001101100100011011000100011010000111000010001010";
String newLine2 = "01100000110110010001101100010001101000011100001000101";
String startSn = "27434877273598525669";
String newLine = "12273598525669";
String endOfSn = "12694954545053565052661310";
String endOfData = "1227513232131032131032131032131032131027109275132";
String s1 = "";
String s2 = "";
if (serialPortEvent.getEventType() != SerialPort.LISTENING_EVENT_DATA_AVAILABLE) {
return;
}
int x = 0;
try {
in = comPort.getInputStream();
Scanner sc = new Scanner(in);
List<String> line = new ArrayList<>();
while (sc.hasNextLine()) {
line.add(sc.next());
if (line.contains("\u001Bm\u001B3")) {
break;
}
}
while (((x = in.read()) != 109)) {
s1 += String.format("%8s", Integer.toBinaryString(x & 0xFF)).replace(' ', '0');
}
} catch (IOException e1) {
e1.printStackTrace();
}
String[] snArray = s1.split(startSn2);
for (int i = 1; i < snArray.length; i++) {
BufferedImage img = new BufferedImage(1, 1, BufferedImage.TYPE_BYTE_BINARY);
Graphics2D g2d = img.createGraphics();
Font font = new Font("Arial", Font.PLAIN, 2);
g2d.setFont(font);
int height = g2d.getFontMetrics().getHeight();
g2d.dispose();
img = new BufferedImage(384, 40, BufferedImage.TYPE_INT_RGB);
g2d = img.createGraphics();
g2d.setFont(font);
g2d.setColor(Color.WHITE);
int fontSize = 1;
for (String line : snArray[i].split(newLine2)) {
g2d.drawString(line, 0, height);
height += fontSize;
//System.out.println("Serial number: " + line);
}
//g2d.dispose();
try {
ImageIO.write(img, "png", new File("images\\Text" + i + ".png"));
} catch (IOException ex) {
ex.printStackTrace();
}
g2d.dispose();
String result = null;
try {
result = SerialOcr("images\\Text" + i + ".png");
} catch (TesseractException e) {
e.printStackTrace();
}
System.out.println(result);
}
}
});
}
I repeated the input stream using this code.
InputStream bufferdInputStream = new BufferedInputStream(myInputStream);
bufferdInputStream.mark(some_value);
//do the first method
bufferdInputStream.reset();
//do the second method
This question already has answers here:
How to combine multiple PNGs into one big PNG file?
(10 answers)
Closed 2 years ago.
My case is what I need to add several barcodes (png) which I generated using Barcode4j library in one png file. I couldn't find any examples, also couldn't make up my mind to solve it. So any help will be appreciated.
Well, I generate barcodes in usual way (throug for) and collecte them in a list of bufferedImages (List). Now I need to glue this images in one.
My code:
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
BitmapCanvasProvider canvas = new BitmapCanvasProvider(baos, "image/x-png", 300, BufferedImage.TYPE_BYTE_BINARY, false, 0);
List<BufferedImage> bufferedImageList = new ArrayList<>(); // list for bufferedImages
for (int i = 0; i < barcodesList.size(); i++) {
try {
Code128Bean code128 = new Code128Bean();
code128.setHeight(15f);
code128.setModuleWidth(0.3);
code128.setQuietZone(10);
code128.doQuietZone(true);
code128.generateBarcode(canvas, (String) barcodesList.get(i));
bufferedImageList.add(canvas.getBufferedImage()); // collect images of barcode in cicle
canvas.finish();
} catch (Exception e) {
e.printStackTrace();
}
}
FileOutputStream fos = new FileOutputStream(barcodePath.toString());
// to do smth to make one png from collected images
fos.write(baos.toByteArray());
fos.flush();
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
Well, my code which combine several barcodes looks like this
ByteArrayOutputStream baos = new ByteArrayOutputStream();
BitmapCanvasProvider canvas = new BitmapCanvasProvider(baos, "image/x-png", 300, BufferedImage.TYPE_BYTE_BINARY, false, 0);
List<BufferedImage> bufferedImageList = new ArrayList<>(); // list for bufferedImages
int sumHeight = 0;
int sumWhide = 0;
int columns = 2;
int rows = 0;
for (int i = 0; i < barcodesList.size(); i++) {
try {
Code128Bean code128 = new Code128Bean();
code128.setHeight(15f);
code128.setModuleWidth(0.3);
code128.setQuietZone(10);
code128.doQuietZone(true);
code128.generateBarcode(canvas, (String) barcodesList.get(i));
sumHeight = sumHeight + canvas.getBufferedImage().getHeight();
sumWhide = sumWhide + canvas.getBufferedImage().getWidth();
bufferedImageList.add(canvas.getBufferedImage()); // collect images of barcode in cycle
canvas.finish();
} catch (Exception e) {
e.printStackTrace();
}
}
double dbl = barcodesList.size() / (double) columns;
rows = (int)Math.ceil(dbl);
int oneWhide = sumWhide / barcodesList.size();
int imgWhide = oneWhide * columns;
int oneHeight = sumHeight / barcodesList.size();
int imgHeight = oneHeight * rows;
BufferedImage bigImage = new BufferedImage(imgWhide, imgHeight, BufferedImage.TYPE_BYTE_BINARY);
Graphics g = bigImage.getGraphics();
int x = 0;
int y = 0;
for (BufferedImage bufferedImage : bufferedImageList) {
g.drawImage(bufferedImage, x, y, null);
x += oneWhide;
if(x >= bigImage.getWidth()){
x = 0;
y += bufferedImage.getHeight();
}
}
ImageIO.write(bigImage,"png",new File(barcodePath.toString()));
} catch (Exception e) {
e.printStackTrace();
}
}
I currently am writing a program which communicates to a server hosted on a separate device via TCP packets. Writing to the server works fine, but I never seem to be able to read the response. I am positive there is a response because when sniffing network packets, I see the incoming packet from the device, though the program never detects it.
public class SocketTest
{
private Socket socket;
private int currentSequence = 0;
public static void main(String[] args)
{
new SocketTest();
}
public SocketTest()
{
try
{
System.out.println("Connecting");
socket = new Socket("192.168.1.8", 8000);
System.out.println("Connected!");
System.out.println("Pinging...");
sendPacket(0, 3, null, 0);
System.out.println("Pinged!");
System.out.println("Reading..");
while (socket.isConnected())
{
byte[] res = new byte[84];
socket.getInputStream().read(res);
System.out.println("Read!");
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
public void sendPacket(int type, int command, int[] args, int length)
{
int t = 0;
currentSequence += 1000;
byte[] resultBuffer = new byte[84];
byte[] payload1 = getBytes(0x12345678);
System.arraycopy(payload1, 0, resultBuffer, t, payload1.length);
t += 4;
byte[] payload2 = getBytes(currentSequence);
System.arraycopy(payload2, 0, resultBuffer, t, payload2.length);
t += 4;
byte[] payload3 = getBytes(type);
System.arraycopy(payload3, 0, resultBuffer, t, payload3.length);
t += 4;
byte[] payload4 = getBytes(command);
System.arraycopy(payload4, 0, resultBuffer, t, payload4.length);
for (int i = 0; i < 16; i++)
{
t += 4;
int arg = 0;
if (args != null)
{
arg = args[i];
}
byte[] payloadArg = getBytes(arg);
System.arraycopy(payloadArg, 0, resultBuffer, t, payloadArg.length);
}
t += 4;
byte[] payload5 = getBytes(length);
System.arraycopy(payload5, 0, resultBuffer, t, payload5.length);
write(resultBuffer, 0, resultBuffer.length);
}
private void write(byte[] buffer, int startOffset, int length)
{
DataOutputStream out;
try
{
out = new DataOutputStream(socket.getOutputStream());
out.write(buffer, startOffset, length);
out.flush();
}
catch (IOException e)
{
e.printStackTrace();
}
}
private byte[] getBytes(int value)
{
ByteBuffer buffer = ByteBuffer.allocate(4).order(ByteOrder.nativeOrder());
buffer.putInt(value);
return buffer.array();
}
}
I've tried a bunch of different methods of reading.. Multithreading, heartbeat, etc.. But everytime I use InputStream's read() method, it blocks because there is no data to be read, and the socket is definitely open because the result isn't -1.
This is the actual read method i'm using in my program (The above code is an shortened xample)
private int read(byte[] buffer, int offset, int length)
{
int res = 0;
DataInputStream bis;
try
{
bis = new DataInputStream(socket.getInputStream());
if (bis.available() > 0)
{
System.out.println("Waiting bytes: " + bis.available());
System.out.println("buffer = [" + Arrays.toString(buffer) + "], offset = [" + offset + "], length = [" + length + "]");
res = bis.read(buffer, offset, length);
}
else
{
NTR.getLogger().debug("Available: " + bis.available());
}
}
catch (IOException e)
{
e.printStackTrace();
}
return res;
}
Interestingly, the C# version of the code works just fine.
namespace ntrclient
{
public class NtrClient
{
public delegate void LogHandler(string msg);
private readonly object _syncLock = new object();
private uint _currentSeq;
private int _heartbeatSendable;
public string Host;
private string _lastReadMemFileName;
private uint _lastReadMemSeq;
public NetworkStream NetStream;
public Thread PacketRecvThread;
public int Port;
public volatile int progress = -1;
public TcpClient Tcp;
public event LogHandler OnLogArrival;
private int ReadNetworkStream(Stream stream, byte [] buf, int length)
{
var index = 0;
var useProgress = length > 100000;
do
{
if (useProgress)
{
progress = (int) ((double) index / length * 100);
}
var len = stream.Read(buf, index, length - index);
if (len == 0)
{
Console.WriteLine("No data to be read");
return 0;
}
Console.WriteLine("Read " + len + " datas");
index += len;
} while (index < length);
progress = -1;
Console.WriteLine("Length: " + length + ", Buffer: " + buf);
return length;
}
private void PacketRecvThreadStart()
{
var buf = new byte [84];
var args = new uint [16];
var stream = NetStream;
while (true)
{
try
{
var ret = ReadNetworkStream(stream, buf, buf.Length);
if (ret == 0)
{
break;
}
var t = 0;
var magic = BitConverter.ToUInt32(buf, t);
t += 4;
var seq = BitConverter.ToUInt32(buf, t);
t += 4;
var type = BitConverter.ToUInt32(buf, t);
t += 4;
var cmd = BitConverter.ToUInt32(buf, t);
for (var i = 0; i < args.Length; i++)
{
t += 4;
args [i] = BitConverter.ToUInt32(buf, t);
}
t += 4;
var dataLen = BitConverter.ToUInt32(buf, t);
if (cmd != 0)
{
Log($"packet: cmd = {cmd}, dataLen = {dataLen}");
}
if (magic != 0x12345678)
{
Log($"broken protocol: magic = {magic}, seq = {seq}");
break;
}
if (cmd == 0)
{
if (dataLen != 0)
{
var dataBuf = new byte [dataLen];
ReadNetworkStream(stream, dataBuf, dataBuf.Length);
var logMsg = Encoding.UTF8.GetString(dataBuf);
Log(logMsg);
}
lock (_syncLock)
{
_heartbeatSendable = 1;
}
continue;
}
if (dataLen != 0)
{
var dataBuf = new byte [dataLen];
ReadNetworkStream(stream, dataBuf, dataBuf.Length);
HandlePacket(cmd, seq, dataBuf);
}
}
catch (Exception e)
{
Log(e.Message);
break;
}
}
Log("Server disconnected.");
Disconnect(false);
}
public void ConnectToServer()
{
if (Tcp != null)
{
Disconnect();
Log("Disconnected from previous server, connecting to new one");
}
new Thread(() =>
{
//Thread.CurrentThread.IsBackground = true;
Tcp = new TcpClient { NoDelay = true };
Tcp.Connect(Host, Port);
_currentSeq = 0;
NetStream = Tcp.GetStream();
_heartbeatSendable = 1;
PacketRecvThread = new Thread(PacketRecvThreadStart);
PacketRecvThread.Start();
Program.getMain().Connected = true;
Log("Server connected.");
}).Start();
}
public void Disconnect(bool waitPacketThread = true)
{
try
{
Tcp?.Close();
if (waitPacketThread)
{
PacketRecvThread?.Join();
}
// Not connected anymore
Program.getMain().Connected = false;
Log("Server disconnected.");
}
catch (Exception ex)
{
Log(ex.Message);
}
Tcp = null;
}
public void SendPacket(uint type, uint cmd, uint [] args, uint dataLen)
{
var t = 0;
_currentSeq += 1000;
var buf = new byte [84];
BitConverter.GetBytes(0x12345678).CopyTo(buf, t);
t += 4;
BitConverter.GetBytes(_currentSeq).CopyTo(buf, t);
t += 4;
BitConverter.GetBytes(type).CopyTo(buf, t);
t += 4;
BitConverter.GetBytes(cmd).CopyTo(buf, t);
for (var i = 0; i < 16; i++)
{
t += 4;
uint arg = 0;
if (args != null)
{
arg = args [i];
}
BitConverter.GetBytes(arg).CopyTo(buf, t);
}
t += 4;
BitConverter.GetBytes(dataLen).CopyTo(buf, t);
NetStream.Write(buf, 0, buf.Length);
}
public void SendHeartbeatPacket()
{
if (Tcp == null)
return;
lock (_syncLock)
{
if (_heartbeatSendable != 1)
return;
_heartbeatSendable = 0;
SendPacket(0, 0, null, 0);
}
}
}
}
I'm honestly stumped. I noticed that C#'s NetworkStream read and write methods are different from java, but I don't exactly know how different they are, or if it makes any difference.
Thanks in advance!
I have been trying to get a print of an Image but I have not been successful so far.The printer is a locally manufactured 2" thermal printer having a printing resolution of 8dots/mm, 384dots/line, 203 dpi. The printer is based of a board having the "NXP 2388 ARM v7 Microproc." having a Memory FLASH size of 512 KB, RAM: 128 KB & a Receive Buffer Size of 16KB.
I followed this question till now.
Problem: The image I tried printing is of 576x95 res.
The image got printed(with some error LED lighting up and debug buzzer noise :D) but the orientation of the image was vertical instead of getting horizontally printed; that too at the very left side of the page and the top part of the image was cut-off
Assuming here that I din't passed some of the flags(while making the "packet") compatible with the printer that I have.
I have not worked on bluetooth printing before so any help is appreciable :)
My Existing Main Activity:
public class MainActivity extends Activity
{
// will show the statuses
TextView myLabel;
// will enable user to enter any text to be printed
EditText myTextbox;
EditText devName;
public TableLayout tl2;
String devid;
String[] pName;
String[] LODQTY;
String[] rte;
String[] stk;
String[] oQty;
String[] oVal;
String[] fQty;
BitSet dots;
int mWidth;
int mHeight;
String mStatus;
String TAG = "TAG";
public String msg;
// android built in classes for bluetooth operations
BluetoothAdapter mBluetoothAdapter;
BluetoothSocket mmSocket;
BluetoothDevice mmDevice;
OutputStream mmOutputStream;
InputStream mmInputStream;
Thread workerThread;
byte[] readBuffer;
int readBufferPosition;
int counter;
volatile boolean stopWorker;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
devName = (EditText) findViewById(R.id.etdevice);
devName.setText("BTprinter0377");
String[] product_info = new String[6];
product_info[0] = "CPL400^10^1^0^4^0.4^0";
product_info[1] = "CPL400^10^1^0^4^0.4^0";
product_info[2] = "CPL400^10^1^0^4^0.4^0";
product_info[3] = "CPL400^10^1^0^4^0.4^0";
product_info[4] = "CPL400^10^1^0^4^0.4^0";
product_info[5] = "CPL400^10^1^0^4^0.4^0";
tl2 = (TableLayout) findViewById(R.id.dynSummary);
LayoutInflater inflater = getLayoutInflater();
for (int current = 0; current <= (product_info.length - 1); current++) {
final TableRow row = (TableRow)inflater.inflate(R.layout.table_summary_row, tl2 , false);
TextView tv1 = (TextView)row.findViewById(R.id.tvSkuName);
TextView tv2 = (TextView)row.findViewById(R.id.tvOrderQty);
TextView tv3 = (TextView)row.findViewById(R.id.tvFreeQty);
TextView tv4 = (TextView)row.findViewById(R.id.tvSampleQty);
TextView tv5 = (TextView)row.findViewById(R.id.tvTotalOrderKg);
TextView tv6 = (TextView)row.findViewById(R.id.tvTotalFreeKg);
TextView tv7 = (TextView)row.findViewById(R.id.tvTotalSampleKg);
StringTokenizer tokens = new StringTokenizer(String.valueOf(product_info[current]), "^");
//System.out.println("tokens.nextToken().trim()"+tokens.nextToken().trim());
tv1.setText(tokens.nextToken().trim());
tv2.setText(tokens.nextToken().trim());
tv3.setText(tokens.nextToken().trim());
tv4.setText(tokens.nextToken().trim());
tv5.setText(tokens.nextToken().trim());
tv6.setText(tokens.nextToken().trim());
tv7.setText(tokens.nextToken().trim());
tl2.addView(row);
}
try {
// we have three buttons for specific functions
Button openButton = (Button) findViewById(R.id.open);
Button sendButton = (Button) findViewById(R.id.send);
Button closeButton = (Button) findViewById(R.id.close);
myLabel = (TextView) findViewById(R.id.label);
// open bluetooth connection
openButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
devid = devName.getText().toString().trim();
try {
findBT();
openBT();
} catch (IOException ex) {
}
}
});
// send data typed by the user to be printed
sendButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
try {
sendData();
} catch (IOException ex) {
}
}
});
// close bluetooth connection
closeButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
try {
closeBT();
} catch (IOException ex) {
}
}
});
} catch (NullPointerException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
/*
* This will find a bluetooth printer device
*/
void findBT() {
try {
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter == null) {
myLabel.setText("No bluetooth adapter available");
}
if (!mBluetoothAdapter.isEnabled()) {
Intent enableBluetooth = new Intent(
BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBluetooth, 0);
}
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter
.getBondedDevices();
if (pairedDevices.size() > 0) {
for (BluetoothDevice device : pairedDevices) {
System.out.println("device.getName(): "+device.getName().toString());
if (device.getName().equals("BTprinter0377")) {
mmDevice = device;
break;
}
}
}
myLabel.setText("Bluetooth Device Found");
} catch (NullPointerException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
/*
* Tries to open a connection to the bluetooth printer device
*/
void openBT() throws IOException {
try {
// Standard SerialPortService ID
UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb");
mmSocket = mmDevice.createRfcommSocketToServiceRecord(uuid);
mmSocket.connect();
mmOutputStream = mmSocket.getOutputStream();
mmInputStream = mmSocket.getInputStream();
beginListenForData();
myLabel.setText("Bluetooth Opened");
} catch (NullPointerException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
/*
* After opening a connection to bluetooth printer device,
* we have to listen and check if a data were sent to be printed.
*/
void beginListenForData() {
try {
final Handler handler = new Handler();
// This is the ASCII code for a newline character
final byte delimiter = 10;
stopWorker = false;
readBufferPosition = 0;
readBuffer = new byte[1024];
workerThread = new Thread(new Runnable() {
public void run() {
while (!Thread.currentThread().isInterrupted()
&& !stopWorker) {
try {
int bytesAvailable = mmInputStream.available();
if (bytesAvailable > 0) {
byte[] packetBytes = new byte[bytesAvailable];
mmInputStream.read(packetBytes);
for (int i = 0; i < bytesAvailable; i++) {
byte b = packetBytes[i];
if (b == delimiter) {
byte[] encodedBytes = new byte[readBufferPosition];
System.arraycopy(readBuffer, 0,
encodedBytes, 0,
encodedBytes.length);
final String data = new String(
encodedBytes, "US-ASCII");
readBufferPosition = 0;
handler.post(new Runnable() {
public void run() {
myLabel.setText(data);
}
});
} else {
readBuffer[readBufferPosition++] = b;
}
}
}
} catch (IOException ex) {
stopWorker = true;
}
}
}
});
workerThread.start();
} catch (NullPointerException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
/*
* This will send data to be printed by the bluetooth printer
*/
void sendData() throws IOException {
System.out.println("tl2.getChildCount(): "+tl2.getChildCount());
try {
print_image("/sdcard/tryimg.png");
String msg22;
msg22 = "\n";
msg22 += "PN Or Fr Sa TOKg TFKg TSKg";
msg22 += "\n";
//mmOutputStream.write(msg22.getBytes());
// tell the user data were sent
myLabel.setText("Data Sent");
} catch (NullPointerException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
/*
* Close the connection to bluetooth printer.
*/
void closeBT() throws IOException {
try {
stopWorker = true;
mmOutputStream.close();
mmInputStream.close();
mmSocket.close();
myLabel.setText("Bluetooth Closed");
} catch (NullPointerException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
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());
}
}
private void print_image(String file) throws IOException {
File fl = new File(file);
if (fl.exists()) {
Bitmap bmp = BitmapFactory.decodeFile(file);
convertBitmap(bmp);
mmOutputStream.write(PrinterCommands.SET_LINE_SPACING_24);
int offset = 0;
while (offset < bmp.getHeight()) {
mmOutputStream.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));
}
mmOutputStream.write(slice);
}
}
offset += 24;
mmOutputStream.write(PrinterCommands.FEED_LINE);
mmOutputStream.write(PrinterCommands.FEED_LINE);
mmOutputStream.write(PrinterCommands.FEED_LINE);
mmOutputStream.write(PrinterCommands.FEED_LINE);
mmOutputStream.write(PrinterCommands.FEED_LINE);
mmOutputStream.write(PrinterCommands.FEED_LINE);
}
mmOutputStream.write(PrinterCommands.SET_LINE_SPACING_30);
} else {
Toast.makeText(this, "file doesn't exists", Toast.LENGTH_SHORT).show();
}
}
}
The PrinterCommands Class:
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, (byte) 255, 3};
//public static byte[] SELECT_BIT_IMAGE_MODE = {0x1B, 0x2A, 0x64, 0x63, 48, (byte) 255};
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};
}
As mentioned in the dev manual of the printer(pdf):
Bit Map Image Print
1. Select the image either from PC or from mobile's SD card.
2. Convert the image into monochrome bmp.
3. Resize the image to fit into the printer paper area if it is exceeding
4. Now read the processed image through fileinputstream and save it into byte array.
5. Make the packet of image and then send it to printer over outputstream.
The required packet structure:
The packet fields chart:
Alignment table & other info:
private byte[] printbyte = {(byte)0x1B,(byte)0x2A,(byte)0x6F,(byte)0x63}
File file = new File(Environment.getExternalStorageDirectory + File.seprator()+"file_name");
FileInputStream fin = new FileInputStream(file);
byte imageContent[] = new byte[(int)file.length()];
fin.read(imageContent);
byte [] width = hexToBuffer(Integer.toHexString(your_width));
byte [] height = hexToBuffer(Integer.toHexString(your_height));
byte[] imageToPrint = new byte[printbyte.lenght()+imageContent.lenght()+width.lenght()+height.lenght()];
System.arraycopy(imagetoprint,0,printbyte,0,printbyte.lenght());
System.arraycopy(imagetoprint,printbyte.lenght(),width ,0,width.lenght());
System.arraycopy(imagetoprint,width.lenght(),height,0,height.lenght());
System.arraycopy(imagetoprint,height.lenght(),imageContent,0,imageContent.lenght());
mmOutputStream.write(imagetoprint);
Hex to Buffer method -
public static byte[] hexToBuffer(String hexString)
throws NumberFormatException {
int length = hexString.length();
byte[] buffer = new byte[(length + 1) / 2];
boolean evenByte = true;
byte nextByte = 0;
int bufferOffset = 0;
if ((length % 2) == 1) {
evenByte = false;
}
for (int i = 0; i < length; i++) {
char c = hexString.charAt(i);
int nibble; // A "nibble" is 4 bits: a decimal 0..15
if ((c >= '0') && (c <= '9')) {
nibble = c - '0';
} else if ((c >= 'A') && (c <= 'F')) {
nibble = c - 'A' + 0x0A;
} else if ((c >= 'a') && (c <= 'f')) {
nibble = c - 'a' + 0x0A;
} else {
throw new NumberFormatException("Invalid hex digit '" + c +
"'.");
}
if (evenByte) {
nextByte = (byte) (nibble << 4);
} else {
nextByte += (byte) nibble;
buffer[bufferOffset++] = nextByte;
}
evenByte = !evenByte;
}
return buffer;
}
I have a thermal printer with bluetooth and Usb connection, if your printer support ESC/POS command search for its commands on internet,
for print raster image you should send this:
[Name] Print raster bit image
[Format] ASCII GS v 0 m xL xH yL yH d1...dk
Hex 1D 76 30 m xL xH yL yH d1...dk
Decimal 29 118 48 m xL xH yL yH d1...dk
[Range] 0£ m£ 3, 48£ m £ 51
0£ xL£ 255
0£ xH£ 255
0£ yL£ 255
0£ d£ 255
k=(xL+ xH*256)*(yL+yH*256)
Follow your printer guidelines, it is may be different from others.
I have extracted the Gray Value from an image file (format .3pi) and wrote them in file (Code below)-
public class ImageFile {
public static void main(String[] args) throws IOException {
FileInputStream fstream = new FileInputStream ("Z:\\20100204-000083-011.3pi");
DataInputStream in = new DataInputStream (fstream);
BufferedReader reader = new BufferedReader (new InputStreamReader (in));
String str = "";
String temp [];
int counter = 0, NumberOfColumn = 0, NumberOfRow = 0;
try {
while (counter != 3) {
str = reader.readLine();
counter ++;
if (counter == 2) {
temp = str.split(" ");
NumberOfRow = Integer.valueOf(temp[5].trim()).intValue();
}
else if (counter == 3) {
temp = str.split(" ");
NumberOfColumn = Integer.valueOf(temp[3].trim()).intValue();
}
}
}
catch (FileNotFoundException e){
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
//System.out.println ("Row : "+NumberOfRow);
//System.out.println ("Column : "+NumberOfColumn);
int found = 0, CurrentColumn = 0, CurrentRow = 0, GrayValue;
int image [][] = new int [NumberOfRow][NumberOfColumn];
FileInputStream fstream2 = new FileInputStream ("Z:\\20100204-000083-011.3pi");
DataInputStream in2 = new DataInputStream (fstream2);
BufferedReader reader2 = new BufferedReader (new InputStreamReader (in2));
FileWriter fstream3 = new FileWriter("Z:\\Test.txt",true);
BufferedWriter writer = new BufferedWriter (fstream3);
while ((str = reader2.readLine()) != null) {
str = str.trim();
temp = str.split(" ");
if (temp [0].contentEquals("#:Profile:")) {
CurrentColumn = Integer.valueOf(temp[1].trim()).intValue();
//System.out.println ("Current Column : "+CurrentColumn);
found = 1;
continue;
}
else {
if (found == 1) {
CurrentRow = Integer.valueOf(temp[4].trim()).intValue();
GrayValue = Integer.valueOf(temp[3].trim()).intValue();
image [CurrentRow][CurrentColumn] = GrayValue;
}
}
}
for (int i= 0; i< NumberOfRow; i++){
for (int j= 0; j< NumberOfColumn; j++){
writer.write (image [i] [j]+" ");
}
writer.write("\n");
}
writer.close();
}
}
Now, I want to create a jpg/ bmp/ any other image with the Gray value information in Test.txt file. How can I achieve it? Help appreciated.
Zereen
The Java Image I/O API Guide should provide with a lot of useful information about image I/O in Java.
If you have pixel data (the colors you would like to use), you can use the class Graphics2D (part of AWT) to draw on a BufferedImage (part of AWT) as described here. You can then use ImageIO to write the data. So:
try {
BufferedImage off_Image =
new BufferedImage(100, 50, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = off_Image.createGraphics();
for (int i= 0; i< NumberOfRow; i++) {
for (int j= 0; j< NumberOfColumn; j++) {
g2.setColor(new Color(....)); // here convert the value in image[i][j] to aRGB
g2.draw(new Rectangle(i, j, 1, 1);
}
}
File outputfile = new File("saved.png");
ImageIO.write(bi, "png", outputfile);
} catch (IOException e) {
// handle exception
}