Merge pull request #1146 from jgfidelis/implement-local-cache
Create local cache directory and save image there when photo is taken.
This commit is contained in:
commit
683b3ee0c8
|
@ -65,6 +65,8 @@ public class MutableImage {
|
|||
return currentRepresentation.getHeight();
|
||||
}
|
||||
|
||||
public Bitmap getBitmap() { return currentRepresentation; }
|
||||
|
||||
public void fixOrientation() throws ImageMutationFailedException {
|
||||
try {
|
||||
Metadata metadata = originalImageMetaData();
|
||||
|
|
|
@ -2,6 +2,7 @@ package org.reactnative.camera;
|
|||
|
||||
import android.content.Context;
|
||||
|
||||
import org.reactnative.camera.utils.ScopedContext;
|
||||
import org.reactnative.facedetector.RNFaceDetector;
|
||||
import com.facebook.react.bridge.Arguments;
|
||||
import com.facebook.react.bridge.Promise;
|
||||
|
@ -25,7 +26,7 @@ public class CameraModule extends ReactContextBaseJavaModule {
|
|||
|
||||
private static ReactApplicationContext mReactContext;
|
||||
|
||||
// private static ScopedContext mScopedContext;
|
||||
private static ScopedContext mScopedContext;
|
||||
static final int VIDEO_2160P = 0;
|
||||
static final int VIDEO_1080P = 1;
|
||||
static final int VIDEO_720P = 2;
|
||||
|
@ -58,14 +59,15 @@ public class CameraModule extends ReactContextBaseJavaModule {
|
|||
public CameraModule(ReactApplicationContext reactContext) {
|
||||
super(reactContext);
|
||||
mReactContext = reactContext;
|
||||
mScopedContext = new ScopedContext(mReactContext);
|
||||
}
|
||||
|
||||
public static ReactApplicationContext getReactContextSingleton() {
|
||||
return mReactContext;
|
||||
}
|
||||
|
||||
public static Context getScopedContextSingleton() {
|
||||
return mReactContext;
|
||||
public static ScopedContext getScopedContext() {
|
||||
return mScopedContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -6,6 +6,8 @@ import android.os.Build;
|
|||
import android.support.annotation.Nullable;
|
||||
|
||||
import org.reactnative.camera.tasks.ResolveTakenPictureAsyncTask;
|
||||
import org.reactnative.camera.utils.ScopedContext;
|
||||
|
||||
import com.facebook.react.bridge.Promise;
|
||||
import com.facebook.react.bridge.ReadableArray;
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
|
|
|
@ -16,6 +16,8 @@ import org.reactnative.camera.tasks.FaceDetectorAsyncTask;
|
|||
import org.reactnative.camera.tasks.FaceDetectorAsyncTaskDelegate;
|
||||
import org.reactnative.camera.tasks.ResolveTakenPictureAsyncTask;
|
||||
import org.reactnative.camera.utils.ImageDimensions;
|
||||
import org.reactnative.camera.utils.RNFileUtils;
|
||||
import org.reactnative.camera.utils.ScopedContext;
|
||||
import org.reactnative.facedetector.RNFaceDetector;
|
||||
import com.facebook.react.bridge.Arguments;
|
||||
import com.facebook.react.bridge.LifecycleEventListener;
|
||||
|
@ -81,7 +83,8 @@ public class RNCameraView extends CameraView implements LifecycleEventListener,
|
|||
public void onPictureTaken(CameraView cameraView, final byte[] data) {
|
||||
Promise promise = mPictureTakenPromises.poll();
|
||||
ReadableMap options = mPictureTakenOptions.remove(promise);
|
||||
new ResolveTakenPictureAsyncTask(data, promise, options).execute();
|
||||
File cacheDirectory = CameraModule.getScopedContext().getCacheDirectory();
|
||||
new ResolveTakenPictureAsyncTask(data, promise, options, cacheDirectory).execute();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -89,8 +92,7 @@ public class RNCameraView extends CameraView implements LifecycleEventListener,
|
|||
if (mVideoRecordedPromise != null) {
|
||||
if (path != null) {
|
||||
WritableMap result = Arguments.createMap();
|
||||
// TODO - fix this
|
||||
//result.putString("uri", ExpFileUtils.uriFromFile(new File(path)).toString());
|
||||
result.putString("uri", RNFileUtils.uriFromFile(new File(path)).toString());
|
||||
mVideoRecordedPromise.resolve(result);
|
||||
} else {
|
||||
mVideoRecordedPromise.reject("E_RECORDING", "Couldn't stop recording - there is none in progress");
|
||||
|
@ -156,10 +158,9 @@ public class RNCameraView extends CameraView implements LifecycleEventListener,
|
|||
}
|
||||
|
||||
public void record(ReadableMap options, final Promise promise) {
|
||||
// try {
|
||||
// TODO - fix this
|
||||
String path = "";
|
||||
//String path = ExpFileUtils.generateOutputPath(CameraModule.getScopedContextSingleton().getCacheDir(), "Camera", ".mp4");
|
||||
try {
|
||||
File cacheDirectory = CameraModule.getScopedContext().getCacheDirectory();
|
||||
String path = RNFileUtils.getOutputFilePath(cacheDirectory, ".mp4");
|
||||
int maxDuration = options.hasKey("maxDuration") ? options.getInt("maxDuration") : -1;
|
||||
int maxFileSize = options.hasKey("maxFileSize") ? options.getInt("maxFileSize") : -1;
|
||||
|
||||
|
@ -175,9 +176,9 @@ public class RNCameraView extends CameraView implements LifecycleEventListener,
|
|||
} else {
|
||||
promise.reject("E_RECORDING_FAILED", "Starting video recording failed. Another recording might be in progress.");
|
||||
}
|
||||
// } catch (IOException e) {
|
||||
// promise.reject("E_RECORDING_FAILED", "Starting video recording failed - could not create video file.");
|
||||
// }
|
||||
} catch (IOException e) {
|
||||
promise.reject("E_RECORDING_FAILED", "Starting video recording failed - could not create video file.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
package org.reactnative.camera.tasks;
|
||||
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.Bitmap;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.support.media.ExifInterface;
|
||||
|
||||
import org.reactnative.MutableImage;
|
||||
import org.reactnative.camera.RNCameraViewHelper;
|
||||
import org.reactnative.camera.utils.RNFileUtils;
|
||||
|
||||
import com.facebook.react.bridge.Arguments;
|
||||
import com.facebook.react.bridge.Promise;
|
||||
|
@ -14,6 +16,9 @@ import com.facebook.react.bridge.ReadableMap;
|
|||
import com.facebook.react.bridge.WritableMap;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
public class ResolveTakenPictureAsyncTask extends AsyncTask<Void, Void, WritableMap> {
|
||||
|
@ -21,6 +26,7 @@ public class ResolveTakenPictureAsyncTask extends AsyncTask<Void, Void, Writable
|
|||
private Promise mPromise;
|
||||
private byte[] mImageData;
|
||||
private ReadableMap mOptions;
|
||||
private File mCacheDirectory;
|
||||
|
||||
public ResolveTakenPictureAsyncTask(byte[] imageData, Promise promise, ReadableMap options) {
|
||||
mPromise = promise;
|
||||
|
@ -28,6 +34,13 @@ public class ResolveTakenPictureAsyncTask extends AsyncTask<Void, Void, Writable
|
|||
mImageData = imageData;
|
||||
}
|
||||
|
||||
public ResolveTakenPictureAsyncTask(byte[] imageData, Promise promise, ReadableMap options, File cacheDirectory) {
|
||||
mPromise = promise;
|
||||
mOptions = options;
|
||||
mImageData = imageData;
|
||||
mCacheDirectory = cacheDirectory;
|
||||
}
|
||||
|
||||
private int getQuality() {
|
||||
return (int) (mOptions.getDouble("quality") * 100);
|
||||
}
|
||||
|
@ -52,9 +65,14 @@ public class ResolveTakenPictureAsyncTask extends AsyncTask<Void, Void, Writable
|
|||
response.putMap("exif", exifData);
|
||||
}
|
||||
|
||||
//TODO: create local cache directory, save image to file and insert into response "uri" key
|
||||
// with the path to the file
|
||||
//response.putString("uri", outputPath);
|
||||
ByteArrayOutputStream imageStream = new ByteArrayOutputStream();
|
||||
mutableImage.getBitmap().compress(Bitmap.CompressFormat.JPEG, getQuality(), imageStream);
|
||||
|
||||
// Write compressed image to file in cache directory
|
||||
String filePath = writeStreamToFile(imageStream);
|
||||
File imageFile = new File(filePath);
|
||||
String fileUri = Uri.fromFile(imageFile).toString();
|
||||
response.putString("uri", fileUri);
|
||||
|
||||
return response;
|
||||
} catch (Resources.NotFoundException e) {
|
||||
|
@ -78,6 +96,35 @@ public class ResolveTakenPictureAsyncTask extends AsyncTask<Void, Void, Writable
|
|||
return null;
|
||||
}
|
||||
|
||||
private String writeStreamToFile(ByteArrayOutputStream inputStream) throws IOException {
|
||||
String outputPath = null;
|
||||
IOException exception = null;
|
||||
FileOutputStream outputStream = null;
|
||||
|
||||
try {
|
||||
outputPath = RNFileUtils.getOutputFilePath(mCacheDirectory, ".jpg");
|
||||
outputStream = new FileOutputStream(outputPath);
|
||||
inputStream.writeTo(outputStream);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
exception = e;
|
||||
} finally {
|
||||
try {
|
||||
if (outputStream != null) {
|
||||
outputStream.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
if (exception != null) {
|
||||
throw exception;
|
||||
}
|
||||
|
||||
return outputPath;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(WritableMap response) {
|
||||
super.onPostExecute(response);
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
package org.reactnative.camera.utils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Created by jgfidelis on 23/01/18.
|
||||
*/
|
||||
|
||||
public class RNFileUtils {
|
||||
|
||||
public static File ensureDirExists(File dir) throws IOException {
|
||||
if (!(dir.isDirectory() || dir.mkdirs())) {
|
||||
throw new IOException("Couldn't create directory '" + dir + "'");
|
||||
}
|
||||
return dir;
|
||||
}
|
||||
|
||||
public static String getOutputFilePath(File directory, String extension) throws IOException {
|
||||
ensureDirExists(directory);
|
||||
String filename = UUID.randomUUID().toString();
|
||||
return directory + File.separator + filename + extension;
|
||||
}
|
||||
|
||||
public static Uri uriFromFile(File file) {
|
||||
return Uri.fromFile(file);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package org.reactnative.camera.utils;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* Created by jgfidelis on 23/01/18.
|
||||
*/
|
||||
|
||||
public class ScopedContext {
|
||||
|
||||
private File cacheDirectory = null;
|
||||
|
||||
public ScopedContext(Context context) {
|
||||
createCacheDirectory(context);
|
||||
}
|
||||
|
||||
public void createCacheDirectory(Context context) {
|
||||
cacheDirectory = new File(context.getCacheDir() + "/Camera/");
|
||||
}
|
||||
|
||||
public File getCacheDirectory() {
|
||||
return cacheDirectory;
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue