How to split inputStream from Serial port? - java

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

Related

java.lang.NumberFormatException: For input string: "010010101101111111"

I have been trying to hide an image in another image(both of same type) by making changes in the pixels.But it gives an error like this:
Exception in thread "main" java.lang.NumberFormatException: For input
string: "010010101101111111"
at java.lang.NumberFormatException.forInputString(Unknown Source)
at java.lang.Integer.parseInt(Unknown Source)
at java.lang.Integer.parseInt(Unknown Source)
at Image.main(Image.java:160)**
The code is shown as below:
public class Image {
public static void main(String argv[]) throws Exception
{
String imageFile1 = "C:/Users/Desktop/1.jpg";
String imageFile2 = "C:/Users/Desktop/2.jpg";
File file1 = new File(imageFile1);
FileInputStream fis1 = null;
try {
fis1 = new FileInputStream(imageFile1);
} catch (FileNotFoundException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
File file2 = new File(imageFile2);
FileInputStream fis2 = null;
try {
fis2 = new FileInputStream(imageFile2);
} catch (FileNotFoundException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
BufferedImage oimage1 = ImageIO.read(file1);
BufferedImage oimage2 = ImageIO.read(file2);
ByteArrayOutputStream baos1=new ByteArrayOutputStream();
byte[] buf1 = new byte[1024];
try {
for (int readNum; (readNum = fis1.read(buf1)) != -1;) {
baos1.write(buf1, 0, readNum);
}
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
ByteArrayOutputStream baos2=new ByteArrayOutputStream();
byte[] buf2 = new byte[1024];
try {
for (int readNum; (readNum = fis2.read(buf1)) != -1;) {
baos2.write(buf2, 0, readNum);
}
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
final byte[] imageInByte1 = baos1.toByteArray();
final int size1 = imageInByte1.length;
final byte[] imageInByte2 = baos2.toByteArray();
final int size2 = imageInByte2.length;
int width1 = oimage1.getWidth();
int height1 = oimage1.getHeight();
int pixel1 = 0;
int red1,green1,blue1;
int width2 = oimage2.getWidth();
int height2 = oimage2.getHeight();
int pixel2=0,red2,green2,blue2;
final BufferedImage newimg1 = new BufferedImage(width1, height1, BufferedImage.TYPE_INT_ARGB);
final BufferedImage newimg2 = new BufferedImage(width2, height2, BufferedImage.TYPE_INT_ARGB);
for (int i = 0; i < width1; i++)
for (int j = 0; j < height1; j++) {
//scan through each pixel
pixel1 = oimage1.getRGB(i, j);
pixel2 = oimage2.getRGB(i, j);
//for red
String redpix1=Integer.toBinaryString(pixel1);
String binaryred1 = redpix1.substring(20,23);
String redpix2=Integer.toBinaryString(pixel2);
String binaryred2=redpix2.substring(20,23);
String newred= binaryred1 + binaryred2;
//for green
String greenpix1=Integer.toBinaryString(pixel1);
String binarygreen1=greenpix1.substring(12,15);
String greenpix2=Integer.toBinaryString(pixel2);
String binarygreen2=greenpix2.substring(12,15);
String newgreen= binarygreen1 + binarygreen2;
//for blue
String bluepix1=Integer.toBinaryString(pixel1);
String binaryblue1=bluepix1.substring(4,7);
String bluepix2=Integer.toBinaryString(pixel2);
String binaryblue2=bluepix2.substring(4,7);
String newblue= binaryblue1 + binaryblue2;
//combining the new values
String spixel=newred +newgreen + newblue;
int newpixel = Integer.parseInt(spixel);
newimg2.setRGB(i,j,newpixel);
}
JFrame f =new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().add(new JLabel(new ImageIcon(newimg2)));
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
The size of 1.jpg is greater than size of 2.jpg.
Can this code be modified to get output? or is any another easy way to embed the image?
The error message isn’t very explanatory. The NumberFormatExceptiondocumentation isn’t either in this case. It says:
Thrown to indicate that the application has attempted to convert a
string to one of the numeric types, but that the string does not have
the appropriate format.
What happens is an int overflow. The largest int you can have is 2 147 483 647 (10 digits), so 10010101101111111 (17 digits after I removed the leading 0) is way too large. This problem shows as a NumberFormatException.
If you intended that to be a binary number, use Integer.parseInt(spixel, 2) to indicate radix 2 (that is, binary). Then you should be able to parse it since up to 31 binary digits fit in an ìnt (not 32 because it’s signed, so there’s a sign bit).
There is a similar question to this one: What is a NumberFormatException and how can I fix it? However, while the accepted answer to that one does mention overflow (pretty deep down in the answer), it doesn’t cover trying to parse a string with the wrong radix. Still you may want to read through the question and answers and learn.

how do i make asynctask throw WriterException?

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;
}

java How to load in a string value

Hello I have an application that loads in values. The values are x,y,and a string value. I want to know how to load in a string because I only know how to o it with an integer. Take a look at this code:
public static void loadStars() {
try {
BufferedReader bf = new BufferedReader(new FileReader ("files/cards.txt"));
for (int i = 0; i < 10; i++) {
String line;
while ((line = bf.readLine()) != null) {
String[] args = line.split(" ");
int x = Integer.parseInt(args[0]);
int y = Integer.parseInt(args[1]);
String name = Integer.parseInt(args[2]);
play.s.add(new Star(x,y,name));
}
}
bf.close();
} catch (Exception e) {
e.printStackTrace();
}
}
I have
play.s.add(new star(x,y,name));
I know how to load in x and y but I don't know how to load in name.
Please help me.
Edit----
In the file that is loaded in it is formatted like this:
x y name
example:
10 10 jack
100 500 conor
each star is represented by 1 line.
public class Star extends BasicStar {
private Image img;
public Star(int x, int y,String starname) {
this.x = x;
this.y = y;
this.starname = starname;
r = new Rectangle(x, y, 3, 3);
}
public void tick() {
if (r.contains(Comp.mx, Comp.my) && Comp.ml) {
remove = true;
}
}
public void render(Graphics g) {
if (!displaySolar) {
ImageIcon i2 = new ImageIcon("res/planets/star.png");
img = i2.getImage();
g.drawImage(img, x, y, null);
}
}
}
Array args[] is already String so you just need to change
String name = Integer.parseInt(args[2]);
to
String name = args[2];
And that's it.
Try this.
public static void loadStars() {
try {
BufferedReader bf = new BufferedReader(new FileReader ("files/cards.txt"));
for (int i = 0; i < 10; i++) {
String line;
while ((line = bf.readLine()) != null) {
String[] args = line.split(" ");
int x = Integer.parseInt(args[0]);
int y = Integer.parseInt(args[1]);
String name = args[2]; // args array contain string, no need of conversion.
play.s.add(new Star(x,y,name));
}
}
bf.close();
} catch (Exception e) {
e.printStackTrace();
}
}
you improve your code by using a StringTokenizer. Try This.
public static void loadStars()
throws IOException {
String line;
BufferedReader bf = new BufferedReader(new FileReader ("files/cards.txt"));
try
{
while((line = bf.readLine()) != null)
{
if (line == null || line.trim().isEmpty())
throw new IllegalArgumentException(
"Line null!");
StringTokenizer tokenizer = new StringTokenizer(line, " ");
if (tokenizer.countTokens() < 3)
throw new IllegalArgumentException(
"Token number not valid (<= 3)");
int x, y;
String xx = tokenizer.nextToken(" ").trim();
String yy = tokenizer.nextToken(" ").trim();
String name = tokenizer.nextToken(" ").trim();
try
{
x = Integer.parseInt(xx);
}catch(ParseException e){throw new IllegalArgumentException(
"Number format not valid!");}
try
{
y = Integer.parseInt(yy);
}catch(ParseException e){throw new IllegalArgumentException(
"Number format not valid!");}
play.s.add(new Star(x,y,name));
}
} catch (NoSuchElementException | NumberFormatException | ParseException e) {
throw new IllegalArgumentException(e);
}
}
Array args[] is already String so you just need to change
String name = Integer.parseInt(args[2]);
// If you are using this values anywhere else you'd do this so de GC can collects the arg[] array
String name = new String(args[2]);
Be aware that if you have spaces in string arguments each word will be a new argument. If you have a call like:
java -jar MyProgram 1 2 This is a sentence.
Your arg[] will be:
{"1", "2", "This", "is", "a", "sentence."}
If you need the sentence to be one String you should use apostrophes:
java -jar MyProgram 1 2 "This is a sentence."
Your arg[] will be:
{"1", "2", "This is a sentence."}

Java serial port write/send ASCII data

My problem is that I need to control mobile robot E-puck via Bluetooth in Java, by sending it commands like "D,100,100" to set speed, "E" to get speed, and etc. I have some code:
String command = "D,100,100";
OutputStream mOutputToPort = serialPort.getOutputStream();
mOutputToPort.write(command.getBytes());
So with this method write I can only send byte[] data, but my robot won't understand that.
For example previously I have been using this commands on Matlab like that:
s = serial('COM45');
fopen(s);
fprintf(s,'D,100,100','async');
Or on program Putty type only:
D,100,100 `enter`
Additional info:
I've also figured out, that Matlab has another solution for same thing.
s = serial('COM45');
fopen(s);
data=[typecast(int8('-D'),'int8') typecast(int16(500),'int8') typecast(int16(500),'int8')];
In this case:
data = [ -68 -12 1 -12 1];
fwrite(s,data,'int8','async');
Wouldn't it be the same in Java:
byte data[] = new byte[5];
data[0] = -'D';
data[1] = (byte)(500 & 0xFF);
data[2] = (byte)(500 >> 8);
data[3] = (byte)(500 & 0xFF);
data[4] = (byte)(500>> 8);
And then:
OutputStream mOutputToPort = serialPort.getOutputStream();
mOutputToPort.write(data);
mOutputToPort.flush();
Main details in code comments. Now you can change wheel speed by typing in command window D,1000,-500 and hitting enter.
public class serialRobot {
public static void main(String[] s) {
SerialPort serialPort = null;
try {
CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier("COM71");
if (portIdentifier.isCurrentlyOwned()) {
System.out.println("Port in use!");
} else {
System.out.println(portIdentifier.getName());
serialPort = (SerialPort) portIdentifier.open(
"ListPortClass", 300);
int b = serialPort.getBaudRate();
System.out.println(Integer.toString(b));
serialPort.setSerialPortParams(115200, SerialPort.DATABITS_8,
SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
serialPort.setInputBufferSize(65536);
serialPort.setOutputBufferSize(4096);
System.out.println("Opened " + portIdentifier.getName());
OutputStream mOutputToPort = serialPort.getOutputStream();
InputStream mInputFromPort = serialPort.getInputStream();
PerpetualThread t = readAndPrint(mInputFromPort);
inputAndSend(mOutputToPort);
t.stopRunning();
mOutputToPort.close();
mInputFromPort.close();
}
} catch (IOException ex) {
System.out.println("IOException : " + ex.getMessage());
} catch (UnsupportedCommOperationException ex) {
System.out.println("UnsupportedCommOperationException : " + ex.getMessage());
} catch (NoSuchPortException ex) {
System.out.println("NoSuchPortException : " + ex.getMessage());
} catch (PortInUseException ex) {
System.out.println("PortInUseException : " + ex.getMessage());
} finally {
if(serialPort != null) {
serialPort.close();
}
}
}
private static PerpetualThread readAndPrint(InputStream in) {
final BufferedInputStream b = new BufferedInputStream(in);
PerpetualThread thread = new PerpetualThread() {
#Override
public void run() {
byte[] data = new byte[16];
int len = 0;
for(;isRunning();) {
try {
len = b.read(data);
} catch (IOException e) {
e.printStackTrace();
}
if(len > 0) {
System.out.print(new String(data, 0, len));
}
}
}
};
thread.start();
return thread;
}
private static void inputAndSend(OutputStream out) {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
int k = 0;
for(;;) {
String komanda;
try {
komanda = in.readLine();
} catch (IOException e) {
e.printStackTrace();
return;
}
komanda = komanda.trim();
if(komanda.equalsIgnoreCase("end")) return;
byte komandaSiust[] = proces(komanda); //Command we send after first
//connection, it's byte array where 0 member is the letter that describes type of command, next two members
// is about left wheel speed, and the last two - right wheel speed.
try {
if(k == 0){
String siunc = "P,0,0\n"; // This command must be sent first time, when robot is connected, otherwise other commands won't work
ByteBuffer bb = ByteBuffer.wrap(siunc.getBytes("UTF-8"));
bb.order(ByteOrder.LITTLE_ENDIAN);
out.write(bb.array());
out.flush();
}else{
ByteBuffer bb = ByteBuffer.wrap(komandaSiust);
bb.order(ByteOrder.LITTLE_ENDIAN);
out.write(bb.array());
out.flush();
}
k++;
} catch (IOException e) {
e.printStackTrace();
return;
}
}
}
private static byte[] proces(String tekstas){
tekstas = tekstas.trim();
char[] charArray = tekstas.toCharArray();
byte kodas1[];
int fComa = tekstas.indexOf(',', 1);
int sComa = tekstas.indexOf(',', 2);
int matavimas = charArray.length;
int skir1 = sComa - fComa - 1;
int skir2 = matavimas - sComa -1;
char leftSpeed[] = new char[skir1];
for(int i = 0; i < skir1; i++){
leftSpeed[i] = charArray[fComa + i + 1];
}
char rightSpeed[] = new char[skir2];
for(int i = 0; i < skir2; i++){
rightSpeed[i] = charArray[sComa + i + 1];
}
String right = String.valueOf(rightSpeed);
String left = String.valueOf(leftSpeed);
int val1 = Integer.parseInt(left);
int val2 = Integer.parseInt(right);
kodas1 = new byte[5];
kodas1[0] = (byte)-charArray[0];
kodas1[1] = (byte)(val1 & 0xFF);
kodas1[2] = (byte)(val1 >> 8);
kodas1[3] = (byte)(val2 & 0xFF);
kodas1[4] = (byte)(val2 >> 8);
return kodas1;
}
private static class PerpetualThread extends Thread {
private boolean isRunning = true;
public boolean isRunning() { return isRunning; }
public void stopRunning() {
isRunning = false;
this.interrupt();
}
}
}
According to the documentation, you need to call setSerialPortParams(int baudrate, int dataBits, int stopBits, int parity) on your serial port.

Constructing image from Grayvalues

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
}

Categories