Zxing - UPC +5 Supplement Barcode Detection - java

I have been attempting to use Zxing 2.3.0 to read images of UPC barcodes with a +5 supplement in java however i cannot read the supplement portion of the barcode. The code successfully reads the first portion only. After searching multiple websites i cannot find any further indications of how to read the supplement other than my current method. Any help would greatly be appreciated.
public static void main(String[] args) {
decodeUPC5();
}
public static void decodeUPC5(){
InputStream barCodeInputStream = null;
try {
barCodeInputStream = new FileInputStream("C:/Users/apoclyps/git/zxing-barcoder/Zxing-Test/img/upc5.png");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
BufferedImage barCodeBufferedImage = null;
try {
barCodeBufferedImage = ImageIO.read(barCodeInputStream);
} catch (IOException e) {
e.printStackTrace();
}
LuminanceSource source = new BufferedImageLuminanceSource(barCodeBufferedImage);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
// Attempting to read UPC + 5 Supplement
GenericMultipleBarcodeReader multiReader = new GenericMultipleBarcodeReader(new MultiFormatReader());
try {
multiReader.decodeMultiple(bitmap);
} catch (NotFoundException e1) {
e1.printStackTrace();
}
Result[] result = null;
try {
result = multiReader.decodeMultiple(bitmap);
} catch (NotFoundException e) {
e.printStackTrace();
}
System.out.println("Results length "+result.length);
for(Result r : result ){
System.out.println("Barcode text is " + r.toString());
}
}
Barcode image!
Output
Results length 1
Barcode text is 9780735200449

Keep in mind that the content of the barcode is 9780735200449 and not 9780735200449 51299. It will always (correctly) return the 9780735200449 as the contents of the barcode.
The +5 extension is returned as ResultMetadata, under key ResultMetadatatype.UPC_EAN_EXTENSION.
Note that it will still return the UPC barcode even if it doesn't see a +5 extension, obviously. So it's possible you would see it return without a +5 extension on this image. However it works for me with the app and so would imagine it easily detects the +5. (If you scan with the app, look at the left for "Metadata $12.99")

Related

JFugue converts midi file incorrectly

(using jfugue 5.0.9) I wanted to convert .mid to .txt (staccato), and later to .mid again, to confirm conversions worked. Both .mid (original and converted) should be equal ideally, but the converted (midi -> staccato -> midi) file has weird delayed notes, and one enlargened note duration. JFugue probably struggles because the midi is a human, hyper-sensible recording. Is there any way to fix this?
Heres the 3 files https://drive.google.com/drive/folders/1DepX0lCqNaIRCoHRfGwBRsO1xRFCbCpl?usp=sharing
And here are the 2 methods used:
public static Pattern convMidToStac(String fileName, boolean makeAFile) {
Pattern p = new Pattern();
// Convert midi file to a JFugue Staccato pattern.
try {
p = MidiFileManager.loadPatternFromMidi(new File("D:/eclipse-workspace/MidiReader/" + fileName + ".mid"));
if (makeAFile) {
makeFile(fileName, p.toString());
}
return p;
} catch (Exception e) {
System.out.println("An error occurred.");
e.printStackTrace();
return null;
}
}
public static void convStacToMid(String fileName) {
Pattern p = new Pattern();
try {
p = MidiFileManager.loadPatternFromMidi(new File("D:/eclipse-workspace/MidiReader/" + fileName + ".mid"));
File filePath = new File("D:/eclipse-workspace/MidiReader/" + fileName + "MIDI.mid");
MidiFileManager.savePatternToMidi(p, filePath);
} catch (Exception e) {
e.printStackTrace();
}
}

How to create multiple barcodes in java using barbecue library?

I want to generate multiple barcodes in java using java.
The scenario looks like this:
I have a textfield named copies, I want to generate barcodes using the barbecue library and based on the number given,
uy
So, if I input 3 in the textfield, it will generate 3 barcodes with a number incremented. And the number will increment (e.g, 1, 2,3) for three barcodes.
Can anyone help me? your help is much highly appreciated
Here's my code in producing the single barcode:
new File("C:\\Generated Barcodes").mkdir();
new File("D:\\Back-Up Generated Barcodes").mkdir();
//Get 128B Barcode instance from the Factory
Barcode barcode = null;
try {
barcode = BarcodeFactory.createCode128B(res.getText());
} catch (BarcodeException ex) {
Logger.getLogger(Barcode_IT.class.getName()).log(Level.SEVERE, null, ex);
}
barcode.setBarHeight(40);
barcode.setBarWidth(2);
generate2.setEnabled(false);
save.setEnabled(true);
Edit.setEnabled(true);
File imgFile = new File("C://Generated Barcodes//"+res2.getText()+"_"+res.getText()+".png");
try {
//Write the bar code to PNG file
BarcodeImageHandler.savePNG(barcode, imgFile);
} catch (OutputException ex) {
Logger.getLogger(Barcode_IT.class.getName()).log(Level.SEVERE, null, ex);
}
ImageIcon imgThisImg = new ImageIcon("C://Generated Barcodes//"+res2.getText()+"_"+res.getText()+".png");
lres.setIcon(imgThisImg);
file.setText(res2.getText()+"_"+res.getText()+".png");
}
}catch(Exception e){
JOptionPane.showMessageDialog(Jframe, "Something Went Wrong!",
"Inane warning", JOptionPane.ERROR_MESSAGE);
}
do you know for loop?use a loop to generate multiple bar codes .
like this
//Get 128B Barcode instance from the Factory
Barcode barcode = null;
int code = Integer.parseInt(res.getText());
for (int i = 1; i <= code; i++) {
try {
barcode = BarcodeFactory.createCode128B(i + "");
} catch (BarcodeException ex) {
Logger.getLogger(NewJFrame.class.getName()).log(Level.SEVERE, null, ex);
}
barcode.setBarHeight(40);
barcode.setBarWidth(2);
File imgFile = new File("C://Generated Barcodes//" + res2.getText() + "_" + i + ".png");
System.out.println(code);
try {
//Write the bar code to PNG file
BarcodeImageHandler.savePNG(barcode, imgFile);
} catch (OutputException ex) {
ex.printStackTrace();
}
ImageIcon imgThisImg = new ImageIcon("C://Generated Barcodes//" + res2.getText() + "_" + i + ".png");
lres.setIcon(imgThisImg);
}

Java-Write in file

I want get name, last name and a spacial code from user, and save in one array, after that write to a file. My code doesn't have compiler error but it doesn't work.
public class WriteFile {
public static void main(String[] args){
try {
String array[][] = new String[100][2];
for (int i = 0; i < array.length; i++) {
RandomAccessFile raf=new RandomAccessFile("D://employee.txt","rw");
String inputName=JOptionPane.showInputDialog("Please Insert First Name");
array[i][0]=inputName;
String inputLName=JOptionPane.showInputDialog("Please Insert Last Name");
array[i][1]=inputLName;
String inputMeliiC=JOptionPane.showInputDialog("Please Insert Melii Code");
array[i][2]=inputMeliiC;
raf.writeUTF(array[i][0]);
raf.writeUTF(array[i][1]) ;
raf.writeUTF(array[i][1]);
}
} catch (FileNotFoundException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
} catch (IOException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}
You are doing many things wrong.
First of all, why do you use an array at all here? It is unwarranted. Collect in a List!
Second: .writeUTF() will not write text.
Third: why write as you ask for input? Write all at once.
Fourth: you don't close your resource at all.
Ask for input first, then attempt to write to the file. And don't use File, it's obsolete. Use this (supposes Java 7+):
final Path dst = Paths.get("d:\\employee.txt");
// Change open options if necessary
try (
final BufferedWriter writer = Files.newBufferedWriter(dst,
StandardCharsets.UTF_8,
StandardOpenOption.CREATE, StandardOpenOption.APPEND);
) {
// write your data
}
Or even better yet, use this. Provided you have collected all of your employee data in a List as I suggest, and not an array, this is as easy as:
Files.write(thePath, myList, StandardCharsets.UTF_8, yourOpenOptionsHere);
Ok well you can for this modified code:
public static void main(String[] args){
RandomAccessFile raf = null;
try {
String array[][] = new String[2][3];
raf=new RandomAccessFile("D:\\employee.txt","rw");
for (int i = 0; i < array.length; i++) {
String inputName=JOptionPane.showInputDialog("Please Insert First Name");
array[i][0]=inputName;
String inputLName=JOptionPane.showInputDialog("Please Insert Last Name");
array[i][1]=inputLName;
String inputMeliiC=JOptionPane.showInputDialog("Please Insert Melii Code");
array[i][2]=inputMeliiC;
raf.writeChars(array[i][0]);
raf.writeChar(':');
raf.writeChars(array[i][1]) ;
raf.writeChar(':');
raf.writeChars(array[i][2]);
raf.writeChars("\n");
}
raf.seek(0);
String str = raf.readLine();
while(str != null ){
System.out.println(str);
String arr[] = str.split(":");
System.out.println(Arrays.asList(arr));
str = raf.readLine();
}
raf.close();
} catch (FileNotFoundException e) {
try {
raf.close();
} catch (IOException ex) {
Logger.getLogger(Ideone.class.getName()).log(Level.SEVERE, null, ex);
}
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
} catch (IOException e) {
try {
raf.close();
} catch (IOException ex) {
Logger.getLogger(Ideone.class.getName()).log(Level.SEVERE, null, ex);
}
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}
Couple of issues:
You defined array as new String[100][2] and using it till the index array[i][2]=inputMeliiC; As array starts from 0, you should define your array as new String[100][3]. Are you doing further processing on your array?
You are not writing the inputMeliiC, instead you are duplicating the inputLName bu doing raf.writeUTF(array[i][1]); twice. You should do raf.writeUTF(array[i][2]);
Most importantly why you r write is not working is, you need to flush out the buffer. So you should do raf.close(); once you are done. Make sure UTF wont write in simple text as you are entering and you are opening file in both read write mode.

JSONArray throwing out of memory exception in android

In my app I sync some data at the end of day to the app server.For this I wrap all my data as a JSONArray of JSONObjects.The data mainly includes about 50 pictures each with a size of approx 50kb(along with some text data).All these pictures are encoded using base64 encoding.Everthing works fine when the pictures uploaded(along with some text data) are few in number,but when I upload a large no of pictures ,say around 50 then I see in the logs that all the data is properly formed into the JSONArray,however when I try to display the JSONArray using 'array.toString()' method I encounter an out of memory exception.This I believe is due to the heap getting full(however,when I try making android:largeHeap="true" in the manifest everything is working fine,however I want to avoid using this approach,since this is not a good practice).My intention is just to write this JSONArray value into a file and then break this file into small chunks and send it across to the server.
Please guide me of the best approach of writing the JSONAray value to the file which won't lead to OOM issues.Thanks !
Following is the format of the JSONArray:
[{"pid":"000027058451111","popup_time":"2014-01-13 23:36:01","picture":"...base64encoded string......","punching_time":"Absent","status":"Absent"},{"pid":"000027058451111","popup_time":"2014-01-13 23:36:21","picture":"...base64encoded string......","punching_time":"Absent","status":"Absent"}]
Following are the main snippets of my code:
JSONObject aux;
JSONArray array = new JSONArray();
.
.
// Looping through each record in the cursor
for (int i = 0; i < count; i++) {
aux = new JSONObject();
try {
aux.put("pid", c.getString(c.getColumnIndex("pid")));
aux.put("status", c.getString(c.getColumnIndex("status")));
aux.put("pop_time", c.getString(c.getColumnIndex("pop_time")));
aux.put("punching_time", c.getString(c.getColumnIndex("punching_time")));
aux.put("picture", c.getString(c.getColumnIndex("image_str"))); // stores base64encoded picture
} catch (Exception e) {
e.printStackTrace();
}
array.put(aux); // Inserting individual objects into the array , works perfectly fine,no error here
c.moveToNext(); // Moving the cursor to the next record
}
Log.d("Log", "length of json array - "+array.length()); // shows me the total no of JSONObjects in the JSONArray,works fine no error
// HAD GOT OOM HERE
//Log.d("Log", "JSONArray is - " + array.toString());
if (array.length() != 0){
try {
String responseCode = writeToFile(array); //Writing the JSONArray value to file,which will then send file to server.
if(responseCode.equals("200"))
Log.d("Log","Data sent successfully from app to app server");
else
Log.d("Log","Data NOT sent successfully from app to app server");
} catch (Exception e) {
e.printStackTrace();
}
}
.
.
private String writeToFile(JSONArray data) {
Log.d("Log", "Inside writeToFile");
File externalStorageDir = new File(Environment.getExternalStorageDirectory().getPath(), "Pictures/File");
if (!externalStorageDir.exists()) {
externalStorageDir.mkdirs();
}
String responseCode = "";
File dataFile = new File(externalStorageDir, "File");
/* FileWriter writer;
String responseCode = "";
try {
writer = new FileWriter(dataFile);
writer.append(data);
writer.flush();
writer.close();
responseCode = sendFileToServer(dataFile.getPath(), AppConstants.url_app_server); // Sends the file to server,worked fine for few pictures
} catch (IOException e) {
e.printStackTrace();
}*/
try {
FileWriter file = new FileWriter("storage/sdcard0/Pictures/File/File");
file.write(data.toString()); // GOT OOM here.
file.flush();
file.close();
Log.d("Log","data written from JSONArray to file");
responseCode = sendFileToServer(dataFile.getPath(), AppConstants.url_app_server); // Sends the file to server,worked fine for few pictures
} catch (IOException e) {
e.printStackTrace();
}
return responseCode;
}
public String sendFileToServer(String filename, String targetUrl) {
.
.
// Sends the file to server,worked fine for few pictures
.
.
return response;
}
Here's the issue. You're trying to load your entire dataset into memory. And you're running out of memory.
Android's JSON classes (and some other JSON libraries) are designed to take a Java object (in memory), serialize it to a parse tree of objects (e.g. JSONObject, JSONArray) (in memory), then convert that tree to a String (in memory) and write it out somewhere.
Specifically in your case (at the moment) it appears what when it converts the parse tree into a String it runs out of memory; That String is effectively doubling the amount of memory required at that point.
To solve your issue you have a few different choices, I'll offer 3:
Don't use JSON at all. Refactor to simply send files and information to your server.
Refactor things so that you only read X images into memory at a time and have multiple output files. Where X is some number of images. Note this is still problematic if your image sizes vary greatly / aren't predictable.
Switch to using Jackson as a JSON library. It supports streaming operations where you can stream the JSON to the output file as you create each object in the array.
Edit to add: for your code, it would look something like this using Jackson:
// Before you get here, have created your `File` object
JsonFactory jsonfactory = new JsonFactory();
JsonGenerator jsonGenerator =
jsonfactory.createJsonGenerator(file, JsonEncoding.UTF8);
jsonGenerator.writeStartArray();
// Note: I don't know what `c` is, but if it's a cursor of some sort it
// should have a "hasNext()" or similar you should be using instead of
// this for loop
for (int i = 0; i < count; i++) {
jsonGenerator.writeStartObject();
jsonGenerator.writeStringField("pid", c.getString(c.getColumnIndex("pid")));
jsonGenerator.writeStringField("status", c.getString(c.getColumnIndex("status")));
jsonGenerator.writeStringField("pop_time", c.getString(c.getColumnIndex("pop_time")));
jsonGenerator.writeStringField("punching_time", c.getString(c.getColumnIndex("punching_time")));
// stores base64encoded picture
jsonGenerator.writeStringField("picture", c.getString(c.getColumnIndex("image_str")));
jsonGenerator.writeEndObject();
c.moveToNext(); // Moving the cursor to the next record
}
jsonGenerator.writeEndArray();
jsonGenerator.close();
The above is untested, but it should work (or at least get you going in the right direction).
First and foremost.Thanks a Billion to Brian Roach for assisting me.His inputs helped me solve the problem.I am sharing my answer.
What was I trying to solve? - In my project I had some user data(name,age,picture_time) and some corresponding pictures for each of the user data.At the EOD I needed to sync all this data to the app server.However when I tried to sync a lot of pictures(say 50 of 50kb approx) I faced an OOM(Out of Memory) issue.Initially, I was trying to upload all the data using a conventional JSONArray approach,however soon I found that I was hitting OOM.This, I attribute to the heap getting full when I was trying to access the JSONArray(which had loads of values and why not ?, afterall I was encoding the pics by base64encoding,which trust me has a hell lot of string data in it !)
Inputs from Brian suggested that I write all my data into a file one by one.So,after the whole process is complete I get one single file that has all the data(name,age,picture_time,base64encoded pictures etc) in it,and then I stream this file to the server.
Following is the code snippet which takes the user data from app database,corresponding pictures from sd card,loops through all the records,creates a JSONArray of JSONObjects using Jackson Json Library(which you need to include in your libs folder,should you use this code) and stores them into a file.This file is then streamed to the server(this snippet not included).Hope this helps someone!
// Sync the values in DB to the server
Log.d("SyncData", "Opening db to read files");
SQLiteDatabase db = context.openOrCreateDatabase("data_monitor", Context.MODE_PRIVATE, null);
db.execSQL("CREATE TABLE IF NOT EXISTS user_data(device_id VARCHAR,name VARCHAR,age VARCHAR,picture_time VARCHAR);");
Cursor c = db.rawQuery("SELECT * FROM user_data", null);
int count = c.getCount();
if (count > 0) {
File file = new File(Environment.getExternalStorageDirectory().getPath(), "Pictures/UserFile/UserFile");
JsonFactory jsonfactory = new JsonFactory();
JsonGenerator jsonGenerator = null;
try {
jsonGenerator = jsonfactory.createJsonGenerator(file, JsonEncoding.UTF8);
jsonGenerator.writeStartObject();
jsonGenerator.writeArrayFieldStart("user_data"); //Name for the JSONArray
} catch (IOException e3) {
e3.printStackTrace();
}
c.moveToFirst();
// Looping through each record in the cursor
for (int i = 0; i < count; i++) {
try {
jsonGenerator.writeStartObject(); //Start of inner object '{'
jsonGenerator.writeStringField("device_id", c.getString(c.getColumnIndex("device_id")));
jsonGenerator.writeStringField("name", c.getString(c.getColumnIndex("name")));
jsonGenerator.writeStringField("age", c.getString(c.getColumnIndex("age")));
jsonGenerator.writeStringField("picture_time", c.getString(c.getColumnIndex("picture_time")));
} catch (Exception e) {
e.printStackTrace();
}
// creating a fourth column for the input of corresponding image from the sd card
Log.d("SyncData", "Name of image - " + c.getString(c.getColumnIndex("picture_time")));
image = c.getString(c.getColumnIndex("picture_time")).replaceAll("[^\\d]", ""); //Removing everything except digits
Log.d("SyncData", "imagename - " + image);
File f = new File(Environment.getExternalStorageDirectory().getPath(), "Pictures/UserPic/" + image + ".jpg");
Log.d("SyncData", "------------size of " + image + ".jpg" + "= " + f.length());
String image_str;
if (!f.exists() || f.length() == 0) {
Log.d("SyncData", "Image has either size of 0 or does not exist");
try {
jsonGenerator.writeStringField("picture", "Error Loading Image");
} catch (Exception e) {
e.printStackTrace();
}
} else {
try {
// Reusing bitmaps to avoid Out Of Memory
Log.d("SyncData", "Image exists,encoding underway...");
if (bitmap_reuse == 0) { //ps : bitmap reuse was initialized to 0 at the start of the code,not included in this snippet
// Create bitmap to be re-used, based on the size of one of the bitmaps
mBitmapOptions = new BitmapFactory.Options();
mBitmapOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(f.getPath(), mBitmapOptions);
mCurrentBitmap = Bitmap.createBitmap(mBitmapOptions.outWidth, mBitmapOptions.outHeight, Bitmap.Config.ARGB_8888);
mBitmapOptions.inJustDecodeBounds = false;
mBitmapOptions.inBitmap = mCurrentBitmap;
mBitmapOptions.inSampleSize = 1;
BitmapFactory.decodeFile(f.getPath(), mBitmapOptions);
bitmap_reuse = 1;
}
BitmapFactory.Options bitmapOptions = null;
// Re-use the bitmap by using BitmapOptions.inBitmap
bitmapOptions = mBitmapOptions;
bitmapOptions.inBitmap = mCurrentBitmap;
mCurrentBitmap = BitmapFactory.decodeFile(f.getPath(), mBitmapOptions);
if (mCurrentBitmap != null) {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
try {
mCurrentBitmap.compress(Bitmap.CompressFormat.JPEG, 35, stream);
Log.d("SyncData", "------------size of " + "bitmap_compress" + "= " + mCurrentBitmap.getByteCount());
} catch (Exception e) {
e.printStackTrace();
}
byte[] byte_arr = stream.toByteArray();
Log.d("SyncData", "------------size of " + "image_str" + "= " + byte_arr.length);
stream.close();
stream = null;
image_str = Base64.encodeToString(byte_arr, Base64.DEFAULT);
jsonGenerator.writeStringField("picture", image_str);
}
} catch (Exception e1) {
e1.printStackTrace();
}
}
try {
jsonGenerator.writeEndObject(); //End of inner object '}'
} catch (JsonGenerationException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
c.moveToNext(); // Moving the cursor to the next record
}
try {
jsonGenerator.writeEndArray(); //close the array ']'
//jsonGenerator.writeStringField("file_size", "0"); // If need be, place another object here.
jsonGenerator.writeEndObject();
jsonGenerator.flush();
jsonGenerator.close();
} catch (JsonGenerationException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
c.close();
db.close();
}

Finding Duration of an MP3 file in Java

OK so I have tried using ID3 tags to get the duration and I also tried using JMF media player.getDuration().
player.getDuration().getSeconds()
The file is VBR. Are there any light weight libraries or something inside JMF that could be used to solve this problem.
Thanks.
I use JAudioTagger to achieve this. The below code will get you the duration of an MP3 track.
int duration = 0;
try {
AudioFile audioFile = AudioFileIO.read(new File("file.mp3"));
duration = audioFile.getAudioHeader().getTrackLength();
} catch (Exception e) {
e.printStackTrace();
}
You can alternatively cast audioFile.getAudioHeader() to MP3AudioHeader and use the method getPreciseTrackLength() to get a more precise duration. However, this (i believe) only applies to MP3 files and no other formats (such as WAV files).
I using this lib and this code :
File f = new File("path/mp3");
MediaLocator ml = null;
Player p = null;
try {
ml = new MediaLocator(f.toURL());
p = Manager.createPlayer(ml);
p.start();
while (true) {
Thread.sleep(1000);
System.out.println("Media Time :: "+p.getMediaTime().getSeconds());
System.out.println("Duration :: "+p.getDuration().getSeconds());
if(p.getMediaTime().getSeconds() == p.getDuration().getSeconds())
break;
}
p.stop();
p.deallocate();
p.close();
} catch (NoPlayerException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
Good luck.

Categories

Resources