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.
Related
I am trying to use the /system/bin/screencapture tool in Android in my program. I want to have the screenshot in a Bitmap object. (I know about the other methods, however, my program is using a SurfaceView and I cannot change that so none available on the internet I could find worked.)
I have found that using the -p option to encode it into a png file takes too much time. So I want to use the output without the -p option. However, I am unable to figure out what format that output uses. I have tried reading it into a byte array and using BitmapFactory.decodeByteArray() but that doesn't seem to work (method just returns null.)
TL;DR: What format does /system/bin/screencapture use when not using the -p option (or writing to a file name that ends with ".png")
Here's the relevant code:
Bitmap bitmap = null;
try {
Runtime.getRuntime().exec("/system/bin/screencap /storage/emulated/0/storage/screencap");
try {
Thread.sleep(45);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.v("findMe", "Finished writing file");
byte[] data = new byte[0];
FileInputStream fis = new FileInputStream("/system/bin/screencap");
while(fis.available() > 0){
data = append_to_byte_arr(data, (byte) fis.read());
}
Log.d("findMe", data.length + " is data.length");
bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
} catch (IOException ioe) {
Log.e("findMe", "you failed", ioe);
return;
}
//...
private byte[] append_to_byte_arr(byte[] arr, byte item) {
byte[] temp = new byte[arr.length + 1];
System.arraycopy(arr, 0, temp, 0, arr.length);
temp[arr.length] = item;
return temp;
}
Thanks for the help.
Without the "-p" option the format depends about the filename extension: if it is ".png" the screenshot is automatically saved as PNG. Without any filename the screenshot is printed to "stdout". I tried many was and the best is to print out to "stdout" and then read directly the Bitmap pixels from there because the other methods involves the "screencap" to save to file and then your App should read it wasting "a lot of time" (near 1.5 seconds in both operations)
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
I am facing a problem downloading PNG images from my server to my Android app. The problem is specific to PNG images (JPG works fine), and the issue is that the downloaded files are corrupt images. I will explain in more details, below.
Scenario :
I need to download JPG and PNG images from my server, and display them to the user of the Android app.
Issue :
The JPG images get downloaded without an issue. But the downloaded PNG files are corrupt. I have double checked the source of the images at my server, and they are proper. Its only the downloaded PNG files, that are corrupt. So, the problem probably lies in the way I am downloading them in Android.
Code Sample :
URL imageURL;
File imageFile = null;
InputStream is = null;
FileOutputStream fos = null;
byte[] b = new byte[1024];
try {
// get the input stream and pass to file output stream
imageURL = new URL(image.getServerPath());
imageFile = new File(context.getExternalFilesDir(null), image.getLocalPath());
fos = new FileOutputStream(imageFile);
// get the input stream and pass to file output stream
is = imageURL.openConnection().getInputStream();
// also tried but gave same results :
// is = imageURL.openStream();
while(is.read(b) != -1)
fos.write(b);
} catch (FileNotFoundException e) {
} catch (MalformedURLException e) {
} catch (IOException e) {
} finally {
// close the streams
try {
if(fos != null)
fos.close();
if(is != null)
is.close();
} catch(IOException e){
}
}
Any pointers on how I can work on this, will be very appreciated.
Note :
Since this is happening in a service, there are no problems of doing this inside an AsyncTask.
The problem is here
while(is.read(b) != -1)
fos.write(b);
This is wrong, because in each iteration it will write the full buffer (1024 bytes) to the file. But the previous read could have read less bytes than than (almost surely on the last loop, unless the image lenght happens to be exactly a multiple of 1024). You should check how many bytes were read each time, and write that amount of bytes.
int bytesRead;
while( (bytesRead = is.read(b)) != -1)
fos.write(b,0,bytesRead );
Your error makes you write always files with sizes that are multiple of 1024 - which of course is not the case in general. Now, what happens when a image is saved with extra trailing bytes depends on the format and on the image reader. In some cases, it might work. Still, it's wrong.
BTW: never swallow exceptions - even if that's not the problem today, it might be tomorrow and you might spend hours finding the problem.
So in this app I made, The user makes a project and when they save, the number of frames is saved to numberFrames.txt on the SD card. Then I retrieve the file in another class. Only thing is that nFrames = 50 when i show a toast of nFrames to the screen after I run this code. The only initializing of nFrames I do is to zero right above this code, which is located in the onCreate().
File sdcardLocal = Environment.getExternalStorageDirectory();
File dir = new File (sdcardLocal.getAbsolutePath() + "/Flipbook/"+customizeDialog.getTitle()+"/");
dir.mkdirs();
File fileNum = new File(dir, "numberFrames.txt");
FileWriter myFileWriter = null;
try {
myFileWriter = new FileWriter(fileNum);
} catch (IOException e) {
e.printStackTrace();
}
BufferedWriter out = new BufferedWriter(myFileWriter);
try {
String text = bitmaps.size()+"";
out.write(text);
out.close();
} catch (IOException e) {
e.printStackTrace();
}
I retrieve the file like this. I have no idea where this "50" value for nFrames came from as there are no loops around this and I know for sure that the particular project saved has only 3 frames. Why is this?
FileInputStream is = null;
BufferedInputStream bis = null;
try {
is = new FileInputStream(new File(mFolderDialog.getPath()+"/numberFrames.txt"));
bis = new BufferedInputStream(is);
nFrames = bis.read();
}catch (IOException e) {
e.printStackTrace();
}
You are writing out a string, and then reading the first byte as an integer. 50 is the ascii code for the '2' character.
You can use BufferedReader.readLine to read the entire first line of the file as a String, and then Integer.parseInt to convert that to an integer.
Also, I would take a closer look at your application's workflow. You don't give much information, but saving a file with a single integer value to the sdcard has a certain "smell" to it :). Have you looked at using a database, or maybe store the text file in your application's directory instead?
as I need to get a specific Frame from a Website I want to display in an WebView, I decided to grab the .html from the net and save it under file:///data/data//files/file.html. Stroed there I can edit it using regex or String methods.
Now two questions:
Is there a way to bind this file to an resource. e.g. to /res/raw/file.html and get it updated dynamically as i edit it? Or can i write the File directly to the resources?
Is this whole stuff I do there any good or performant at all? I mean maybe there is a better way to get the .html code between two tags from a Webpage and display it via WebView.
Kind regards
Markus
I believe that application assets are readonly. So you cannot write anything to it.
You can though, get access to the internal (device memory) files directory and write your data there. As for automatically updating the file, you'll have to take care of that in your code.
Here is an example of how you would go about writing a file (in my case a stream) to the files directory for your application
// ... code ...
// assumed variables:
// InputStream data, String directory, String filename
File storageLocation = new File(directory, filename)
try {
FileOutputStream outputStream = new FileOutputStream(storageLocation);
byte[] buff = new byte[0x2000];
int bytesRead = 0;
DataOutputStream dos = new DataOutputStream(outputStream);
while( (bytesRead = data.read(buffer)) > 0) { dos.write(buffer, 0, bytesRead); }
dos.flush();
dos.close();
outputStream.close();
} catch (Exception e) {
// TODO: Actually handle the exception
e.printStackTrace();
}
// ... more code ...