Skip to content

Commit

Permalink
feat(camera): unify saveToGallery behavior (#2671)
Browse files Browse the repository at this point in the history
  • Loading branch information
jcesarmobile committed Apr 1, 2020
1 parent 05f23fb commit 2185833
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 23 deletions.
1 change: 1 addition & 0 deletions android-template/app/src/main/res/xml/file_paths.xml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="my_images" path="." />
<cache-path name="my_cache_images" path="." />
</paths>
78 changes: 56 additions & 22 deletions android/capacitor/src/main/java/com/getcapacitor/plugin/Camera.java
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ public class Camera extends Plugin {
private static final String IMAGE_GALLERY_SAVE_ERROR = "Unable to save the image in the gallery";

private String imageFileSavePath;
private String imageEditedFileSavePath;
private Uri imageFileUri;
private boolean isEdited = false;

Expand Down Expand Up @@ -223,18 +224,10 @@ public void openPhotos(final PluginCall call) {
}

public void processCameraImage(PluginCall call) {
boolean saveToGallery = call.getBoolean("saveToGallery", CameraSettings.DEFAULT_SAVE_IMAGE_TO_GALLERY);
if(imageFileSavePath == null) {
call.error(IMAGE_PROCESS_NO_FILE_ERROR);
return;
}
if (saveToGallery) {
try {
MediaStore.Images.Media.insertImage(getActivity().getContentResolver(), imageFileSavePath, "", "");
} catch (FileNotFoundException e) {
Log.e(getLogTag(), IMAGE_GALLERY_SAVE_ERROR, e);
}
}
// Load the image as a Bitmap
File f = new File(imageFileSavePath);
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
Expand Down Expand Up @@ -331,10 +324,20 @@ private void returnResult(PluginCall call, Bitmap bitmap, Uri u) {
bitmap.compress(Bitmap.CompressFormat.JPEG, settings.getQuality(), bitmapOutputStream);

if (settings.isAllowEditing() && !isEdited) {
editImage(call, u);
editImage(call, bitmap, u, bitmapOutputStream);
return;
}

boolean saveToGallery = call.getBoolean("saveToGallery", CameraSettings.DEFAULT_SAVE_IMAGE_TO_GALLERY);
if (saveToGallery && (imageEditedFileSavePath != null || imageFileSavePath != null)) {
try {
String fileToSave = imageEditedFileSavePath != null ? imageEditedFileSavePath : imageFileSavePath;
MediaStore.Images.Media.insertImage(getActivity().getContentResolver(), fileToSave, "", "");
} catch (FileNotFoundException e) {
Log.e(getLogTag(), IMAGE_GALLERY_SAVE_ERROR, e);
}
}

if (settings.getResultType() == CameraResultType.BASE64) {
returnBase64(call, exif, bitmapOutputStream);
} else if (settings.getResultType() == CameraResultType.URI) {
Expand All @@ -348,22 +351,30 @@ private void returnResult(PluginCall call, Bitmap bitmap, Uri u) {
// Result returned, clear stored paths
imageFileSavePath = null;
imageFileUri = null;
imageEditedFileSavePath = null;
}

private void returnFileURI(PluginCall call, ExifWrapper exif, Bitmap bitmap, Uri u, ByteArrayOutputStream bitmapOutputStream) {
ByteArrayInputStream bis = null;

try {
bis = new ByteArrayInputStream(bitmapOutputStream.toByteArray());
Uri newUri = saveTemporaryImage(bitmap, u, bis);
Uri newUri = getTempImage(bitmap, u, bitmapOutputStream);
if (newUri != null) {
JSObject ret = new JSObject();
ret.put("format", "jpeg");
ret.put("exif", exif.toJson());
ret.put("path", newUri.toString());
ret.put("webPath", FileUtils.getPortablePath(getContext(), bridge.getLocalUrl(), newUri));
call.resolve(ret);
} else {
call.reject(UNABLE_TO_PROCESS_IMAGE);
}
}

private Uri getTempImage(Bitmap bitmap, Uri u, ByteArrayOutputStream bitmapOutputStream) {
ByteArrayInputStream bis = null;
Uri newUri = null;
try {
bis = new ByteArrayInputStream(bitmapOutputStream.toByteArray());
newUri = saveTemporaryImage(bitmap, u, bis);
} catch (IOException ex) {
call.reject(UNABLE_TO_PROCESS_IMAGE, ex);
} finally {
if (bis != null) {
try {
Expand All @@ -373,6 +384,7 @@ private void returnFileURI(PluginCall call, ExifWrapper exif, Bitmap bitmap, Uri
}
}
}
return newUri;
}

/**
Expand Down Expand Up @@ -478,22 +490,44 @@ protected void handleOnActivityResult(int requestCode, int resultCode, Intent da
}
}

private void editImage(PluginCall call, Uri uri) {
private void editImage(PluginCall call, Bitmap bitmap, Uri uri, ByteArrayOutputStream bitmapOutputStream) {
Uri origPhotoUri = uri;
if (imageFileUri != null) {
origPhotoUri = imageFileUri;
}
try {
Intent editIntent = createEditIntent(origPhotoUri, false);
startActivityForResult(call, editIntent, REQUEST_IMAGE_EDIT);
} catch (SecurityException ex) {
Uri tempImage = getTempImage(bitmap, uri, bitmapOutputStream);
Intent editIntent = createEditIntent(tempImage, true);
if (editIntent != null) {
startActivityForResult(call, editIntent, REQUEST_IMAGE_EDIT);
} else {
call.error(IMAGE_EDIT_ERROR);
}
} catch (Exception ex) {
call.error(IMAGE_EDIT_ERROR, ex);
}
}

private Intent createEditIntent(Uri origPhotoUri, boolean expose) {
Uri editUri = origPhotoUri;
try {
Uri origPhotoUri = uri;
if (imageFileUri != null) {
origPhotoUri = imageFileUri;
if (expose) {
editUri = FileProvider.getUriForFile(getActivity(), getContext().getPackageName() + ".fileprovider", new File(origPhotoUri.getPath()));
}
Intent editIntent = new Intent(Intent.ACTION_EDIT);
editIntent.setDataAndType(origPhotoUri, "image/*");
editIntent.setDataAndType(editUri, "image/*");
File editedFile = CameraUtils.createImageFile(getActivity());
imageEditedFileSavePath = editedFile.getAbsolutePath();
Uri editedUri = Uri.fromFile(editedFile);
editIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
editIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
editIntent.putExtra(MediaStore.EXTRA_OUTPUT, editedUri);
startActivityForResult(call, editIntent, REQUEST_IMAGE_EDIT);
return editIntent;
} catch (Exception ex) {
call.error(IMAGE_EDIT_ERROR, ex);
return null;
}
}

Expand Down
3 changes: 2 additions & 1 deletion core/src/core-plugin-definitions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,8 @@ export interface CameraOptions {
*/
resultType: CameraResultType;
/**
* Whether to save the photo to the gallery/photo stream.
* Whether to save the photo to the gallery.
* If the photo was picked from the gallery, it will only be saved if edited.
* Default: false
*/
saveToGallery?: boolean;
Expand Down
1 change: 1 addition & 0 deletions example/android/app/src/main/res/xml/file_paths.xml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="my_images" path="." />
<cache-path name="my_cache_images" path="." />
</paths>
6 changes: 6 additions & 0 deletions ios/Capacitor/Capacitor/Plugins/Camera.swift
Original file line number Diff line number Diff line change
Expand Up @@ -198,9 +198,12 @@ public class CAPCameraPlugin : CAPPlugin, UIImagePickerControllerDelegate, UINav
public func imagePickerController(_ picker: UIImagePickerController,
didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
var image: UIImage?
var isEdited = false
var isGallery = true

if let editedImage = info[UIImagePickerController.InfoKey.editedImage] as? UIImage {
// Use editedImage Here
isEdited = true
image = editedImage
} else if let originalImage = info[UIImagePickerController.InfoKey.originalImage] as? UIImage {
// Use originalImage Here
Expand All @@ -210,6 +213,7 @@ public class CAPCameraPlugin : CAPPlugin, UIImagePickerControllerDelegate, UINav
var imageMetadata: [AnyHashable: Any] = [:]
if let photoMetadata = info[UIImagePickerController.InfoKey.mediaMetadata] as? [AnyHashable: Any] {
imageMetadata = photoMetadata
isGallery = false
}
if let asset = info[UIImagePickerController.InfoKey.phAsset] as? PHAsset {
imageMetadata = getImageMeta(asset: asset)!
Expand All @@ -232,7 +236,9 @@ public class CAPCameraPlugin : CAPPlugin, UIImagePickerControllerDelegate, UINav
}

if settings.saveToGallery {
if !isGallery || isEdited {
UIImageWriteToSavedPhotosAlbum(image!, nil, nil, nil);
}
}

guard let jpeg = image!.jpegData(compressionQuality: CGFloat(settings.quality/100)) else {
Expand Down

0 comments on commit 2185833

Please sign in to comment.