Cannot add a eng.traineddata to my Tesseract project Android 5.0 - android

I am currently trying to implement Tesseract OCR into my project but have came to a crossing road. I followed all of the directions from https://github.com/rmtheis/tess-two and got stuck at the actual implementation portion of this project. The current code I have running is:
TessBaseAPI baseApi = new TessBaseAPI();
baseApi.init(TESS_DATA_FILE_PATH, "eng");
baseApi.setImage(icon);
String recognizedText = baseApi.getUTF8Text();
baseApi.end();
Now the TESS_DATA_FILE_PATH is the current issue. I have been trying to add the eng.traineddata file to my project, but I simply do not know where or how to do it.
Things I have tried:
In the assets folder I added the file eng.traineddata but that is read only and I cannot change it at run time. So this wont work
I tried to add in other ways of running the project, and running the adb push command to add it directly to the device, but that wont work since I will be pushing this application to the masses.
So what I am looking for is an answer of, How do I add the eng.traineddata to my project. And what do I place in the TESS_DATA_FILE_PATH part of the init call.
Side Notes:
I did receive the BUILD SUCCESSFUL call at the end of all the steps at the link provided above.

I have successfully added the language pack to my project, and ran tess two on my android project.
Here is the code for how I did it:
This is what sets up the files path, and adds the traineddata folder
public void setupOCR(){
File folder = new File(Environment.getExternalStorageDirectory() + "/classlinkp/tessdata");
if (!folder.exists()) {
folder.mkdirs();
}
File saving = new File(folder, "eng.traineddata");
try {
saving.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
InputStream stream = null;
try {
stream = mContext.getAssets().open("eng.traineddata", AssetManager.ACCESS_STREAMING);
} catch (IOException e) {
e.printStackTrace();
}
if (stream != null){
copyInputStreamToFile(stream, saving);
}
}
Here is how I saved out the eng.traineddata file:
private void copyInputStreamToFile( InputStream in, File file ) {
try {
OutputStream out = new FileOutputStream(file);
byte[] buf = new byte[1024];
int len;
while((len=in.read(buf))>0){
out.write(buf,0,len);
}
out.close();
in.close();
} catch (Exception e) {
e.printStackTrace();
}
}
The saving method was gathered from: https://stackoverflow.com/a/28131358/3781164

Related

Android Studio Data Collection

I am designing an app for my job to collect data on dog training. I need to be able to access the data on my computer to analyze it. I have completed the front end of the app and organized all of the information into a single string that I would like to save into a file for later analysis. I run the app and can not find the data anywhere on the tablet that runs the app. The code that saves the app is:
String output="Example, Data";
File file = new File(Environment.getExternalStoragePublicDirectory(DIRECTORY_DOCUMENTS),"TrainingData.txt");
try {
FileOutputStream fout = new FileOutputStream(file);
OutputStreamWriter outputStream = new OutputStreamWriter(fout);
outputStream.write(output);
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
Is there something wrong with the saving part of the code listed or is it correct and I'm just failing to find the file on the tablet. Any help would be greatly appreciated.
Try this instead:
File path = context.getFilesDir();
File file = new File(path, "the-file.txt");
and then:
FileOutputStream stream = new FileOutputStream(file);
try {
stream.write(output".getBytes());
} finally {
stream.close();
}

it works fine on desktop, but not on android. why?

saving socres to highscore.sav file, it works fine on desktop, but not on android. why?
String fileName = "highScores.sav";
file = new File(fileName);
public static void save(){
try{
FileOutputStream fileOut = new FileOutputStream(file);
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(gd);
out.close();
}
catch(Exception e){
e.printStackTrace();
System.out.println(e);
Gdx.app.exit();
}
}
public static void load(){
try{
if(!saveFileExists()){
init();
return;
}
FileInputStream fileIn = new FileInputStream(file);
ObjectInputStream in = new ObjectInputStream(fileIn);
gd = (GameData) in.readObject();
in.close();
}
catch(Exception e){
e.printStackTrace();
System.out.println(e);
Gdx.app.exit();
}
}
got error: java.io.FileNotFoundException: /highScores.sav: open failed: EROFS (Read-only file system)
This isn't working because you have not specified a directory to save into. Android has tight restrictions on where an app can write files.
You don't need any permissions to read or write a file to internal memory. But you do need to specify internal memory (called local memory in libgdx).
Libgdx already handles this directly for you so you don't need to differentiate between desktop and Android. This explains exactly how to do it. All you need is the string or bytes you want to write into the file, and the libgdx API's handle the rest.
FileHandle file = Gdx.files.local(filename);
file.writeString(stringToWrite, false);
If you want to continue using your method of writing the file, you can get the path to the file like this:
String fileName = "highScores.sav";
file = new File(Gdx.files.getLocalStoragePath () + "/" + fileName);
Have you added the permission to the android app to allow writing to the storage space?

creating a copy of sdcard picture to another directory?

i am able to get the path of the picture i want to copy, and able to get the path from where i want it to be copy, but still cant find the way to copy them.
any suggestion?
private void copyPictureToFolder(String picturePath, String folderName)
throws IOException {
Log.d("debug", folderName);
Log.d("debug", picturePath);
try {
FileInputStream fileInputStream = new FileInputStream(picturePath);
FileOutputStream fileOutputStream = new FileOutputStream(folderName+"/");
int bufferSize;
byte[] bufffer = new byte[512];
while ((bufferSize = fileInputStream.read(bufffer)) > 0) {
fileOutputStream.write(bufffer, 0, bufferSize);
}
fileInputStream.close();
fileOutputStream.close();
} catch (Exception e) {
Log.d("disaster","didnt work");
}
}
thanks.
You should use Commons-IO to copy a file, we are in 2013 ! No one wants do that manually. If you really want then you should consider a few things :
first a loop that copies your file, at every iteration you copy buffer.length bytes. In you current code, you don't loop and copy 512 bytes of source image into dest (whatever the source image size is).
take care of last iteration and only copy what you read
your try/catch structure is not correct, you should add a finally close to always close your source and destination file. Look here for an example : what is the exact order of execution for try, catch and finally?
With IOUtils, it will give something like
try {
IOUtils.copy( source, dest );
} finally {
IOUtils.closeQuietly( source );
IOUtils.closeQuietly( dest );
}
and don't catch anything, it will be forwarded to the caller.

Why does AssetManager list() not show my assets folder?

In my Android app I have packaged a file in the /assets folder that needs to be copied to the SDCARD. When I list the contents of the assets folder to a String[] I get "images", "sounds", "webkit" and "kioskmode" but not my file manually added to the assets folder.
My code is here:
private void copyAsset () {
AssetManager am = getApplicationContext().getAssets();
String[] files = null;
try {
files = am.list("");
} catch (IOException e) {
}
for (String filename : files) {
if (filename.equals("images") || filename.equals("kioskmode") ||
filename.equals("sounds") || filename.equals("webkit")) {
Log.i(TAG, "Skipping folder " + filename);
continue;
}
InputStream in = null;
OutputStream out = null;
try {
in = am.open(filename);
File outFile = new File(Environment.getExternalStorageDirectory().getPath(), filename);
out = new FileOutputStream(outFile);
copyFile(in, out);
in.close();
in = null;
out.flush();
out.close();
out = null;
} catch (IOException e) {
e.printStackTrace();
Log.e(TAG, "Error copying asset ", e);
}
}
}
Does it make a difference that this is a second class in my app and is called in my MainActivity using Intent showHelper = new Intent(this, HelperManager.class);
startActivity(showHelper); ?
I have tried the 2nd line (AssetManager am = ...) with and without the getApplicationContext() bit, tried moving the file into a subfolder of /assets and tried files = am.list("") with leading and trailing slashes. If I use a subfolder the files array is empty when the code runs (set a breakpoint on the files = am.list(""); line and inspected it at run time.
The strange thing is that it worked once - when I first wrote the code, but for further testing, I deleted the file from the /sdcard folder on the phone, and it never worked since even though the file is still in the assets folder.
I am using Android Studio if that matters.
Thanks
Managed to get a solution using Load a simple text file in Android Studio as a fix. It still puts the 4 folders in the files array but I Can skip them using code as given above, although I should rather check for the file I want rather than the 4 I don't!

java.io.FileNotFoundException: /file/path.jpg open failed: ENOENT (No such file or directory)

I am trying to save an image to parse.com. I need to convert it to byte array. The way I have decided to try to do this is to use apache commons-io. It is not quite working properly. This is my code snippet;
private void saveImage() throws IOException {
// TODO Auto-generated method stub
InputStream header = new FileInputStream("/ClashMMA/res/drawable-hdpi/beatdown.jpg");
ParseFile file = new ParseFile(toByteArray(header));
try{
file.save();
} catch (ParseException e) {
e.printStackTrace();
}
ParseObject displayImage = new ParseObject("displayImage");
displayImage.put("header", file);
try{
displayImage.save();
} catch (ParseException e1){
e1.printStackTrace();
}
}
private byte[] toByteArray(InputStream header) throws IOException {
// TODO Auto-generated method stub
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
int l;
byte[] data = new byte[1024];
while ((l = header.read(data, 0, data.length)) != -1) {
buffer.write(data, 0, l);
}
buffer.flush();
return buffer.toByteArray();
}
And my error is this;
java.io.FileNotFoundException: /ClashMMA/res/drawable-hdpi/beatdown.jpg: open failed: ENOENT (No such file or directory)
But I am sure that the file is there, because I went to my file directory (in eclipse), right clicked, and clicked on Copy Qualified Name. Which essentially copies the file path. I have tried a few other paths, Like right off of my computer, and in my src folder. Can someone please tell me what I am doing wrong? Why won't it read the file when in fact it is there? Detailed explanations please.
The files in your Eclipse projects are not in the (real or emulated) Android file system, and that is where the Android FileInputStream is looking. (With good reason! The host file system for Eclipse won't be there on a real Android device.)
You've basically got two choices:
get them into the APK archive so that you can load them using getSystemResourceAsStream: see How to load image for Android ImageView from classpath?
copy the files into the Android file system so that FileInputStream can find them.

Categories

Resources