I am trying to create a facial/emotion detection application for my dissertation and have hit the wall that has stopped me from progressing and I cant figure out the reason why it is preventing the image saving to the directory of the phone. It seems to be saving to the SD card, but I dont use an SDcard in my phone / an emulated DCIM.
file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM)+ "/" + UUID.randomUUID(), toString()+ ".jpg");
ImageReader.OnImageAvailableListener readerListener = new ImageReader.OnImageAvailableListener() {
#Override
public void onImageAvailable(ImageReader imageReader) {
Image image = null;
try {
image = reader.acquireLatestImage();
ByteBuffer buffer = image.getPlanes() [0].getBuffer();
byte[] bytes = new byte[buffer.capacity()];
buffer.get(bytes);
save(bytes);
} catch (IOException e)
{
e.printStackTrace();
}
finally {
{
if (image != null)
image.close();
}
}
}
This is the code I have to create the file and save to the location, I have tried other solutions but they throw out errors.
File folder = new File(Environment.getExternalStorageDirectory() + "/CustomFolder");
File file;
if (!folder.exists()) {
boolean success = folder.mkdir();
if (success){
file = new File(folder.getPath() + "/" + UUID.randomUUID(), toString()+ ".jpg");
}else {
Toast.makeText(FacialDetection.this, "Failed to save file to folder", Toast.LENGTH_SHORT).show();
}
}else{
file = new File(folder.getPath() + "/" + UUID.randomUUID(), toString()+ ".jpg");
}
ImageReader.OnImageAvailableListener readerListener = new ImageReader.OnImageAvailableListener() {
#Override
public void onImageAvailable(ImageReader imageReader) {
Image image = null;
try {
image = reader.acquireLatestImage();
ByteBuffer buffer = image.getPlanes() [0].getBuffer();
byte[] bytes = new byte[buffer.capacity()];
buffer.get(bytes);
save(bytes);
} catch (IOException e)
{
e.printStackTrace();
}
finally {
{
if (image != null)
image.close();
}
}
}
private void save(byte[] bytes) throws IOException {
OutputStream outputStream = null;
try {
outputStream = new FileOutputStream(***file***);
outputStream.write(bytes);
}finally {
if (outputStream != null)
outputStream.close();
}
}
};
reader.setOnImageAvailableListener(readerListener, mBackgroundHandler);
final CameraCaptureSession.CaptureCallback captureListener = new CameraCaptureSession.CaptureCallback() {
#Override
public void onCaptureCompleted(#NonNull CameraCaptureSession session, #NonNull CaptureRequest request, #NonNull TotalCaptureResult result) {
super.onCaptureCompleted(session, request, result);
Toast.makeText(FacialDetection.this, "Saved " + ***file***, Toast.LENGTH_SHORT).show();
createCameraPreview();
}
};
The updated code, stuff bold and italic is what is throwing errors
I will advise you to create your own custom folder location this way:
File folder = new File(Environment.getExternalStorageDirectory() + "/CustomFolder");
File file;
if (!folder.exists()) {
boolean success = folder.mkdir();
if (success){
file = new File(folder.getPath() + "/" + UUID.randomUUID(), toString()+ ".jpg");
}else {
//Some message
}
}else {
file = new File(folder.getPath() + "/" + UUID.randomUUID(), toString()+ ".jpg");
}
//The rest of your code...
You're calling:
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM)
I would speculate that .getExternalStoragePublicDirectory() means get directory on SD card. Is there a getInternal... method?
//Create folder !exist
String folderPath = Environment.getExternalStorageDirectory() +"/myFoldername";
File folder = new File(folderPath);
if (!folder.exists()) {
File wallpaperDirectory = new File(folderPath);
wallpaperDirectory.mkdirs();
}
//create a new file
newFile = new File(folderPath, newPhoto.getName());
if (newFile != null) {
// save image here
Uri relativePath = Uri.fromFile(newFile);
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, relativePath);
startActivityForResult(intent, CAMERA_REQUEST);
}
Related
I hope you can fix my problem:
I have got a textureview to takes photos but when he capture photos, the file who need to contain the picture is empty. I don't know where and what is the problem. I just think that the problem is when the file is created. Thank you to help me.
This is a part of my code :
private void takePicture() throws CameraAccessException, IOException {
if(cameraDevice == null){
return;
}
CameraManager manager = (CameraManager) Objects.requireNonNull(getContext()).getSystemService(Context.CAMERA_SERVICE);
CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraDevice.getId());
Size[] jpegSizes = null;
jpegSizes = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP).getOutputSizes(ImageFormat.JPEG);
int width = 640;
int height = 480;
if(jpegSizes!=null && jpegSizes.length>0){
width = jpegSizes[0].getWidth();
height = jpegSizes[0].getHeight();
}
ImageReader reader = ImageReader.newInstance(width,height, ImageFormat.JPEG, 1);
List<Surface> outputSurface = new ArrayList<>(2);
outputSurface.add(reader.getSurface());
outputSurface.add(new Surface(textureView.getSurfaceTexture()));
final CaptureRequest.Builder captureBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
captureBuilder.addTarget(reader.getSurface());
captureBuilder.set(CaptureRequest.CONTROL_MODE,CameraMetadata.CONTROL_MODE_AUTO);
int rotation = Objects.requireNonNull(getActivity()).getWindowManager().getDefaultDisplay().getRotation();
captureBuilder.set(CaptureRequest.JPEG_ORIENTATION,ORIENTATIONS.get(rotation));
// First I get the path to gallery and crate new Album to my app
File file = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS);
mImageFolder = new File(file, "Fluico");
if (!mImageFolder.exists()) {
if (!mImageFolder.mkdirs()) {
Log.d("Fluicophoto", "failed to create directory");
}
}
/*Second I cut mFile = new File(getActivity().getExternalFilesDir(null), "pic.jpg");
from onActivityCreated and add here with the new path from my Album*/
#SuppressLint("SimpleDateFormat") String timestamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String prepend = "IMAGE_" + timestamp + "_";
file = File.createTempFile(prepend, ".jpg", mImageFolder);
Toast.makeText(getContext(), "file need to be save", Toast.LENGTH_SHORT).show();
ImageReader.OnImageAvailableListener readerListener = new ImageReader.OnImageAvailableListener() {
#Override
public void onImageAvailable(ImageReader reader) {
Image image = null;
image = reader.acquireLatestImage();
ByteBuffer buffer = image.getPlanes()[0].getBuffer();
byte[] bytes = new byte[buffer.capacity()];
buffer.get(bytes);
try {
save(bytes);
} finally {
image.close();
}
}
};
reader.setOnImageAvailableListener(readerListener,mBackgroundHandler);
final CameraCaptureSession.CaptureCallback captureListener = new CameraCaptureSession.CaptureCallback() {
#Override
public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result) {
super.onCaptureCompleted(session, request, result);
Toast.makeText(getContext(), "saved", Toast.LENGTH_SHORT).show();
try{
createCameraPreview();
}catch (CameraAccessException e){
Toast.makeText(getContext(), "capture not comleted", Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
}
};
cameraDevice.createCaptureSession(outputSurface, new CameraCaptureSession.StateCallback() {
#Override
public void onConfigured( CameraCaptureSession session) {
try {
session.capture(captureBuilder.build(), captureListener, mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
Toast.makeText(getContext(), "capture not configured", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onConfigureFailed( CameraCaptureSession session) {
}
},mBackgroundHandler);
}
private void save(byte[] bytes) {
OutputStream outputStream = null;
try {
outputStream = new FileOutputStream(file);
outputStream.write(bytes);
outputStream.close();
Toast.makeText(getContext(), "it's good", Toast.LENGTH_SHORT).show();
}catch (IOException e){
Toast.makeText(getContext(), "file not found", Toast.LENGTH_SHORT).show();
}
}
Try with below code:
File myDir;
String fname;
String id = "123456";
int count = 0;
String root = Environment.getExternalStorageDirectory().toString();
myDir = new File(root + "/PhotoApp/" + id);
myDir.mkdirs();
count++;
counter.setText(String.valueOf(count));
fname = "" + id + "-" + count + ".jpg";
File file = new File(myDir, fname);
if (file.exists()) file.delete();
This code will create a folder PhotoApp and inside the folder, all the images will store.
You can get full code with the camera in my GitHub:
Link: https://github.com/abhishekhzb/quick_camera
I'm trying to make an app that detects motion and takes picture when the motion is detected. Its saving the picture when I don't try to save it in the directory(folder). But when I try it with the directory, the picture is not being saved even though the directory is being created successfully.
What changes should I make to the following code in order to make it work:
private void createDirectoryAndSaveFile(String name, Bitmap bitmap) {
File folder = new File(Environment.getExternalStorageDirectory() +
File.separator + "XYX APP");
boolean success = true;
if (!folder.exists()) {
success = folder.mkdirs();
}
if (success) {
// Do something on success
} else {
// Do something else on failure
}
File photo = new File(new File(Environment.getExternalStorageDirectory()+"XYZ APP/"), name+ ".jpg");
if (photo.exists()) {
photo.delete();
}
try {
FileOutputStream out = new FileOutputStream(photo.getPath());
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
Note: The file name is generated in the following instruction:
String name = "MotDet_"+String.valueOf(System.currentTimeMillis());
if (bitmap != null) createDirectoryAndSaveFile(name, bitmap);
Update
It works with the following code but not with the code above :
private void save(String name, Bitmap bitmap) {
File photo = new File(Environment.getExternalStorageDirectory(), name + ".jpg");
if (photo.exists()) photo.delete();
try {
FileOutputStream fos = new FileOutputStream(photo.getPath());
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
fos.close();
} catch (java.io.IOException e) {
Log.e("PictureDemo", "Exception in photoCallback", e);
}
}
First of all you missed the FileSeperator before xyz
File photo = new File(folder.getAbsolutePath()+"/XYZ APP/"+ name+ ".jpg");
And your Function becomes
private void createDirectoryAndSaveFile(String name, Bitmap bitmap) {
File folder = new File(Environment.getExternalStorageDirectory() +
File.separator + "XYZ APP");//here you have created different name
boolean success = true;
if (!folder.exists()) {
success = folder.mkdirs();
}
if (success) {
// Do something on success
} else {
// Do something else on failure
}
File photo = new File(folder.getAbsolutePath(), name+ ".jpg");
if (photo.exists()) {
photo.delete();
}
try {
FileOutputStream out = new FileOutputStream(photo.getPath());
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
Marshmello comes with RuntimePermissions in order for you to save file in external directory you need to ask permission first, like below code
public boolean isStoragePermissionGranted() {
if (Build.VERSION.SDK_INT >= 23) {
if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED) {
Log.v(TAG,"Permission is granted");
return true;
} else {
Log.v(TAG,"Permission is revoked");
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
return false;
}
}
else { //permission is automatically granted on sdk<23 upon installation
Log.v(TAG,"Permission is granted");
return true;
}
}
permission result callback
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if(grantResults[0]== PackageManager.PERMISSION_GRANTED){
Log.v(TAG,"Permission: "+permissions[0]+ "was "+grantResults[0]);
//resume tasks needing this permission
}
}
before saving call isStoragePermissionsGranted() if it returns true proceed saving file.
Try this code :
String partFilename = currentDateFormat();
storeCameraPhotoInSDCard(bp, partFilename);
private String currentDateFormat(){
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd_HH_mm_ss");
String currentTimeStamp = dateFormat.format(new Date());
return currentTimeStamp;
}
private void storeCameraPhotoInSDCard(Bitmap bitmap, String currentDate){
File outputFile = new File(Environment.getExternalStorageDirectory(), "photo_" + currentDate + ".jpg");
try {
FileOutputStream fileOutputStream = new FileOutputStream(outputFile);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fileOutputStream);
fileOutputStream.flush();
fileOutputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
This code is work for me..Save image to directory.
You have to get permission of external storage at run time in android 6.0 and above to write in SDCard
Read Run time Permission
add in manifest.xml
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
replace your function with below one
private void createDirectoryAndSaveFile(String name, Bitmap bitmap) {
File folder = new File(Environment.getExternalStorageDirectory() +
File.separator + "XYZ APP");//here you have created different name
boolean success = true;
if (!folder.exists()) {
success = folder.mkdirs();
}
if (success) {
// Do something on success
} else {
// Do something else on failure
}
File photo = new File(folder.getAbsolutePath(), name+ ".jpg"); //use path of above created folder
if (photo.exists()) {
photo.delete();
}
try {
FileOutputStream out = new FileOutputStream(photo.getPath());
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
I keep a photo with my application to the array Bitmap.Then when I did need, I call the shots feature saveAll() as shown in the code below
public void saveAll(View view) {
for (Bitmap b : arrBitmap) {
SystemClock.sleep(1000);
try {
File pictureFile = getOutputMediaFile();
if (pictureFile == null) {
return;
}
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(convertBitmapToByteArray(b));
fos.close();
Toast.makeText(context, "Picture saved: " + pictureFile.getName(),
Toast.LENGTH_SHORT).show();
} catch (Exception e) {
}
}
}
private byte[] convertBitmapToByteArray(Bitmap bitmap) {
ByteArrayOutputStream stream = new ByteArrayOutputStream(bitmap.getWidth() *
bitmap.getHeight());
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
return stream.toByteArray();
}
private static File getOutputMediaFile() {
File mediaStorageDir = new File("/sdcard/", "JCG Camera");
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
return null;
}
}
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File mediaFile;
mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_" +
timeStamp + ".jpg");
return mediaFile;
}
and photo is saved very strange at first may not Save or Save all but the first or the first did not survive, but then when I further tested the code they may appear,but every time Toast shows that all is saved.Please tell me
what am I doing wrong?
I'm working on this Camera application but I'm having trouble displaying the image that the user takes. The camera, preview, and capture buttons work perfectly on the main activity. Right now, the application saves the photo to Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "MyCameraApp" But I DON'T want the images to save there. I just want to pass that image to the next activity, (Not save it to a public directory). Is there a way to do this? I've looked at the tutorials but can't figure out how to implement MODE.PRIVATE.
Here's where it is called:
#Override
public void onPictureTaken(final byte[] data, Camera camera) {
new AsyncTask<Void, Void, String>() {
#Override
protected String doInBackground(Void... params) {
File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
if (pictureFile == null){
Log.d(TAG, "Error creating media file, check storage permissions: ");
return null;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
return pictureFile.getPath();
} catch (FileNotFoundException e) {
Log.d(TAG, "File not found: " + e.getMessage());
return null;
} catch (IOException e) {
Log.d(TAG, "Error accessing file: " + e.getMessage());
return null;
}
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
if(result != null){
Intent intent = new Intent(mContext, ImageDisplayActivity.class);
intent.putExtra(ImageDisplayActivity.KEY_PATH, result);
startActivity(intent);
}
}
}.execute();
}
Here is the code for the method:
private static File getOutputMediaFile(int type){
// To be safe, you should check that the SDCard is mounted
// using Environment.getExternalStorageState() before doing this.
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "MyCameraApp");
// This location works best if you want the created images to be shared
// between applications and persist after your app has been uninstalled.
// Create the storage directory if it does not exist
if (! mediaStorageDir.exists()){
if (! mediaStorageDir.mkdirs()){
Log.d("MyCameraApp", "failed to create directory");
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date());
File mediaFile;
if (type == MEDIA_TYPE_IMAGE){
mediaFile = new File(mediaStorageDir.getPath() + File.separator +
"IMG_"+ timeStamp + ".jpg");
} else {
return null;
}
return mediaFile;
}
Try this one ,
ActivityOne.Java
try {
//Write file
String filename = "photo.png";
FileOutputStream stream = this.openFileOutput(filename, Context.MODE_PRIVATE);
bmp.compress(Bitmap.CompressFormat.PNG, 200, stream);
//Cleanup
stream.close();
//Pop intent
Intent mIntent= new Intent(this, ActivityTwo.class);
in1.putExtra("bitmap", filename);
startActivity(mIntent);
} catch (Exception e) {
e.printStackTrace();
}
ActivityTwo.Java
Bitmap bmp = null;
String filename = getIntent().getStringExtra("bitmap");
try {
FileInputStream is = this.openFileInput(filename);
bmp = BitmapFactory.decodeStream(is);
is.close();
} catch (Exception e) {
e.printStackTrace();
}
and set Imageview with bitmap you can get your bitmap which you captured from camera
http://developer.android.com/guide/topics/data/data-storage.html#filesInternal
Look at the example :
String FILENAME = "hello_file";
String string = "hello world!";
FileOutputStream fos = openFileOutput(FILENAME, Context.MODE_PRIVATE);
fos.write(string.getBytes());
fos.close();
So basically, you just need to have a FILENAME to create a file on private mode.
Just keep the last part your method getOutputMediaFile(int type) it should be something like this :
private static File getOutputMediaFile(int type){
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss",
Locale.getDefault()).format(new Date());
if (type == MEDIA_TYPE_IMAGE) {
mediaFile = "IMG_"+ timeStamp + ".jpg";
} else {
return null;
}
return mediaFile;
}
and then just change this try of your doInBackground function :
try {
FileOutputStream fos = openFileOutput(pictureFile, Context.MODE_PRIVATE);
fos.write(data);
fos.close();
return pictureFile;
}
And just give the path to your other Activity and create a bmp
String filepath = intent.getStringExtra("EXTRA_FILE");
java.io.FileInputStream in = openFileInput(filepath);
Bitmap bmp = BitmapFactory.decodeStream(in)
I am using tesseract OCR in my app (Spl!t). When I launch the app from Eclipse to my phone, eng.traineddata is copied into /storage/emulated/0/Pictures/Receipts/tessdata/. But when I installed the app from the market, the eng.traineddata file is not copied into the folder. Is there something wrong with my code?
private File getOutputPhotoFile() {
directory = new File(
Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
"Receipts");
dataPath = directory.getAbsolutePath();
if (!directory.exists()) {
directory.mkdirs();
Toast.makeText(Trans_List.this, "Receipts Folder Created", Toast.LENGTH_SHORT).show();
File tessDir = new File(directory, "tessdata");
if (!tessDir.exists()) {
tessDir.mkdirs();
Toast.makeText(Trans_List.this, "Tessdata Folder Created", Toast.LENGTH_SHORT).show();
File trainingData = new File(tessDir, "eng.traineddata");
if(!trainingData.exists())
new CopyLibrary().execute(LANG);
}
}
String timeStamp = new SimpleDateFormat("yyyMMdd_HHmmss")
.format(new Date());
return new File(directory.getPath() + File.separator + "Receipt_"
+ timeStamp + ".jpg");
}
private class CopyLibrary extends AsyncTask<String, Void, Void> {
private void copyFile(InputStream in, OutputStream out)
throws IOException {
byte[] buffer = new byte[1024];
int read;
while ((read = in.read(buffer)) != -1)
out.write(buffer, 0, read);
}
#Override
protected Void doInBackground(String... s) {
AssetManager assetManager = getAssets();
String[] files = null;
try {
files = assetManager.list("");
} catch (IOException e) {
Log.e("Spl!t", "Failed to get asset file list.");
}
for (String filename : files) {
InputStream in = null;
OutputStream out = null;
try {
in = assetManager.open(filename);
File outFile = new File(dataPath + File.separator
+ "tessdata" + File.separator, LANG
+ ".traineddata");
out = new FileOutputStream(outFile);
copyFile(in, out);
in.close();
in = null;
out.flush();
out.close();
Toast.makeText(Trans_List.this, "Tessdata copied", Toast.LENGTH_SHORT).show();
out = null;
} catch (IOException e) {
Log.e(TAG, "Failed to copy asset file");
}
}
return null;
}
}