Compare commits

...

22 Commits
7.0.x ... 8.0.x

Author SHA1 Message Date
Norman Breau
7f33ef4add chore: version 8.0.0 2024-10-30 11:08:58 -03:00
Norman Breau
4c9dc10512 deprecation: allowEdit (#914)
* deprecation: allowEdit

* applied suggestions to verbiage
2024-10-30 09:48:20 -03:00
Norman Breau
de468b6f63 fix: Remove WRITE_EXTERNAL_PERMISSION (#915) 2024-10-29 01:15:50 -03:00
Norman Breau
48c4cdd47f refactor(android): Make WRITE_EXTERNAL_STORAGE optional (#909)
* refactor(android): Rework permission management to make WRITE_EXTERNAL_STORAGE optional

* removed unused getPermissions API

* Proper error if WRITE_EXTERNAL_STORAGE is required but missing the declaration

* removed obsolete hasPermissions API
2024-10-28 15:21:37 -03:00
Norman Breau
7d159cf3c9 docs: Revisions for v8 public API changes with the return string formats of getPicture (#913) 2024-10-28 14:01:04 -03:00
Norman Breau
c208754c08 refactor(android): remove query img usage (#907)
* refactor: remove unnecessary duplicate image checks and queryImgDb usage

* remove unused imageType parameter, because it's a private API anyway
2024-10-28 13:32:35 -03:00
Norman Breau
0d86764b90 refactor(android): replace image path usage with image uris (#906)
* refactor(android): clean up image file path usages

* removed references of image paths in log messages
2024-10-28 12:35:50 -03:00
Norman Breau
7adccc8ee9 fix(ios): Sync camera API return to match Android changes (#911) 2024-10-27 08:32:38 -03:00
Norman Breau
53795454f4 fix(browser): Make data uri be returned as actual URI strings (#912) 2024-10-27 08:32:14 -03:00
Norman Breau
2eaa9a3972 fix: return content uris when possible when selecting from gallery (#902) 2024-10-26 00:58:24 -03:00
Norman Breau
a672c31efb fix(android): Return data uris as an URI (#910) 2024-10-26 00:58:00 -03:00
Norman Breau
16325102c7 fix(android): Improper serialization of image uri in save instance state (#903) 2024-10-25 13:59:29 -03:00
Norman Breau
36bf8e7331 fix(android): improper cache path construction during image manipulation (#905) 2024-10-25 13:15:59 -03:00
Norman Breau
feb7643bc3 fix(android): Use VERSION_CODES instead of hard-coded API literals (#904) 2024-10-25 13:10:05 -03:00
Norman Breau
44480300d9 fix(android): Isolate provider access to a subdirectory (#901) 2024-10-25 13:09:03 -03:00
ravi-yk
faa4615ee0 Remove media permissions to make complaint with Android 14 requirements (#889)
Co-authored-by: Ravi Yakasiri <ravi.yakasiri@planonsoftware.com>
2024-10-24 13:38:18 -03:00
Norman Breau
0a4bfe1a74 chore: Update package to 8.0.0-dev (#899) 2024-10-21 09:38:35 -03:00
Norman Breau
49438dee6d chore: Update eslint config to 5.1.0 (#898) 2024-10-19 12:17:43 -03:00
jcesarmobile
f38aba2b59 ci: sync workflow with paramedic (#895) 2024-08-08 12:16:56 +09:00
Norman Breau
3b73186b91 chore: Added npmrc 2024-07-27 01:30:29 -03:00
Norman Breau
40a5db10c7 ci(android): Update Android CI to be compatible with cordova-android@13 (#890) 2024-07-16 14:54:17 -03:00
Erisu
9eecbaa1af chore: bump version 7.0.1-dev 2023-09-06 17:02:23 +09:00
19 changed files with 704 additions and 576 deletions

View File

@@ -23,6 +23,7 @@ on:
- '**.md'
- 'LICENSE'
- '.eslint*'
pull_request:
paths-ignore:
- '**.md'
@@ -32,7 +33,7 @@ on:
jobs:
test:
name: Android ${{ matrix.versions.android }} Test
runs-on: macos-latest
runs-on: ubuntu-latest
continue-on-error: true
# hoist configurations to top that are expected to be updated
@@ -40,12 +41,12 @@ jobs:
# Storing a copy of the repo
repo: ${{ github.event.pull_request.head.repo.full_name || github.repository }}
node-version: 16
node-version: 20
# These are the default Java configurations used by most tests.
# To customize these options, add "java-distro" or "java-version" to the strategy matrix with its overriding value.
default_java-distro: temurin
default_java-version: 11
default_java-version: 17
# These are the default Android System Image configurations used by most tests.
# To customize these options, add "system-image-arch" or "system-image-target" to the strategy matrix with its overriding value.
@@ -56,31 +57,48 @@ jobs:
strategy:
matrix:
versions:
# Test the lowest minimum supported APIs
- android: 7
android-api: 24
# Test the last 3-4 supported APIs
- android: 7.1
android-api: 25
- android: 8
android-api: 26
- android: 8.1
android-api: 27
system-image-arch: x86
- android: 9
android-api: 28
- android: 10
android-api: 29
- android: 11
android-api: 30
- android: 12
android-api: 31
- android: 12L
android-api: 32
- android: 13
android-api: 33
- android: 14
android-api: 34
timeout-minutes: 60
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ env.node-version }}
- uses: actions/setup-java@v3
- uses: actions/setup-java@v4
env:
java-version: ${{ matrix.versions.java-version == '' && env.default_java-version || matrix.versions.java-version }}
java-distro: ${{ matrix.versions.java-distro == '' && env.default_java-distro || matrix.versions.java-distro }}
@@ -88,6 +106,12 @@ jobs:
distribution: ${{ env.java-distro }}
java-version: ${{ env.java-version }}
- name: Enable KVM group perms
run: |
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
sudo udevadm control --reload-rules
sudo udevadm trigger --name-match=kvm
- name: Run Environment Information
run: |
node --version
@@ -105,7 +129,7 @@ jobs:
if: ${{ endswith(env.repo, '/cordova-paramedic') != true }}
run: npm i -g github:apache/cordova-paramedic
- uses: reactivecircus/android-emulator-runner@d94c3fbe4fe6a29e4a5ba47c12fb47677c73656b
- uses: reactivecircus/android-emulator-runner@v2
env:
system-image-arch: ${{ matrix.versions.system-image-arch == '' && env.default_system-image-arch || matrix.versions.system-image-arch }}
system-image-target: ${{ matrix.versions.system-image-target == '' && env.default_system-image-target || matrix.versions.system-image-target }}
@@ -119,7 +143,7 @@ jobs:
script: echo "Pregenerate the AVD before running Paramedic"
- name: Run paramedic tests
uses: reactivecircus/android-emulator-runner@d94c3fbe4fe6a29e4a5ba47c12fb47677c73656b
uses: reactivecircus/android-emulator-runner@v2
env:
system-image-arch: ${{ matrix.versions.system-image-arch == '' && env.default_system-image-arch || matrix.versions.system-image-arch }}
system-image-target: ${{ matrix.versions.system-image-target == '' && env.default_system-image-target || matrix.versions.system-image-target }}

View File

@@ -39,11 +39,11 @@ jobs:
# Storing a copy of the repo
repo: ${{ github.event.pull_request.head.repo.full_name || github.repository }}
node-version: 16
node-version: 20
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ env.node-version }}

View File

@@ -40,7 +40,7 @@ jobs:
# Storing a copy of the repo
repo: ${{ github.event.pull_request.head.repo.full_name || github.repository }}
node-version: 16
node-version: 20
# > Starting April 26, 2021, all iOS and iPadOS apps submitted to the App Store must be built with Xcode 12 and the iOS 14 SDK.
# Because of Apple's requirement, listed above, We will only be using the latest Xcode release for testing.
@@ -50,28 +50,24 @@ jobs:
strategy:
matrix:
versions:
- os-version: macos-11
ios-version: 13.x
xcode-version: 11.x
- os-version: macos-11
ios-version: 14.x
xcode-version: 12.x
- os-version: macos-11
- os-version: macos-12
ios-version: 15.x
xcode-version: 13.x
- os-version: macos-12
- os-version: macos-14
ios-version: 16.x
xcode-version: 14.x
- os-version: macos-14
ios-version: 17.x
xcode-version: 15.x
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ env.node-version }}
- uses: maxim-lobanov/setup-xcode@9a697e2b393340c3cacd97468baa318e4c883d98
- uses: maxim-lobanov/setup-xcode@60606e260d2fc5762a71e64e74b2174e8ea3c8bd
env:
xcode-version: ${{ matrix.versions.xcode-version == '' && env.default_xcode-version || matrix.versions.xcode-version }}
with:

View File

@@ -34,11 +34,11 @@ jobs:
name: Lint Test
runs-on: ubuntu-latest
env:
node-version: 16
node-version: 20
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ env.node-version }}

2
.npmrc Normal file
View File

@@ -0,0 +1,2 @@
registry=https://registry.npmjs.org

216
README.md
View File

@@ -135,8 +135,31 @@ To add these entries into the `info.plist`, you can use the `edit-config` tag in
### camera.getPicture(successCallback, errorCallback, options)
Takes a photo using the camera, or retrieves a photo from the device's
image gallery. The image is passed to the success callback as a
Base64-encoded `String`, or as the URI for the image file.
image gallery. The result is provided in the first parameter of the `successCallback` as a string.
As of v8.0.0, the result is formatted as URIs. The scheme will vary depending on settings and platform.
|Platform|Destination Type|Format|
|---|---|---|
|Android|FILE_URI|An URI scheme such as `file://...` or `content://...`|
||DATA_URL|Base 64 encoded with the proper data URI header|
|iOS|FILE_URI|`file://` schemed paths|
||DATA_URL|Base 64 encoded with the proper data URI header|
|Browser|FILE_URI|Not supported|
||DATA_URL|Base 64 encoded with the proper data URI header|
v7 and earlier versions, the return format is as follows:
|Platform|Destination Type|Format|
|---|---|---|
|Android|FILE_URI|Raw file path (unprefixed)|
||DATA_URL|Base 64 encoded, without the `data:` prefix
|iOS|FILE_URI|`file://` schemed paths|
||DATA_URL|Base 64 encoded, without the `data:` prefix
|Browser|FILE_URI|Not supported|
||DATA_URL|Base 64 encoded, without the `data:` prefix|
For this reason, upgrading to v8 is strongly recommended as it greatly streamlines the return data.
The `camera.getPicture` function opens the device's default camera
application that allows users to snap pictures by default - this behavior occurs,
@@ -149,16 +172,10 @@ that allows users to select an existing image.
The return value is sent to the [`cameraSuccess`](#module_camera.onSuccess) callback function, in
one of the following formats, depending on the specified
`cameraOptions`:
`cameraOptions`. You can do whatever you want with content:
- A `String` containing the Base64-encoded photo image.
- A `String` representing the image file location on local storage (default).
You can do whatever you want with the encoded image or URI, for
example:
- Render the image in an `<img>` tag, as in the example below
- Save the data locally (`LocalStorage`, [Lawnchair](http://brianleroux.github.com/lawnchair/), etc.)
- Render the content in an `<img>` or `<video>` tag
- Copy the data to a persistent location
- Post the data to a remote server
__NOTE__: Photo resolution on newer devices is quite good. Photos
@@ -167,6 +184,32 @@ quality, even if a `quality` parameter is specified. To avoid common
memory problems, set `Camera.destinationType` to `FILE_URI` rather
than `DATA_URL`.
__NOTE__: To use `saveToPhotoAlbum` option on Android 9 (API 28) and lower, the `WRITE_EXTERNAL_STORAGE` permission must be declared.
To do this, add the following in your `config.xml`:
```xml
<config-file target="AndroidManifest.xml" parent="/*" xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="28" />
</config-file>
```
Android 10 (API 29) and later devices does not require `WRITE_EXTERNAL_STORAGE` permission. If your application only supports Android 10 or later, then this step is not necessary.
#### FILE_URI Usage
When `FILE_URI` is used, the returned path is not directly usable. The file path needs to be resolved into
a DOM-usable URL using the [Cordova File Plugin](https://github.com/apache/cordova-plugin-file).
Additionally, the file URIs returned is a temporary read access grant. The OS reserves the right to revoke permission to access the resource, which typically occurs after the app has been closed. For images captured using the camera, the image is stored in a temporary location which can be cleared at any time, usually after the app exits. It's the application's decision to decide how the content should be used depending on their use cases.
For persistent access to the content, the resource should be copied to your app's storage container. An example use case is an app allowing an user to select a profile picture from their gallery or camera. The application will need
consistent access to that resource, so it's not suitable to retain the temporary access path. So the appplication should copy the resource to a persistent location.
For use cases that involve temporary use, it is valid and safe to use the temporary file path to display the content. An example of this could be an image editing application, rendering the data into a canvas.
__NOTE__: The returned schemes is an implementation detail. Do not assume that it will always be a `file://` URI.
__Supported Platforms__
- Android
@@ -232,15 +275,22 @@ Callback function that provides the image data.
| Param | Type | Description |
| --- | --- | --- |
| imageData | <code>string</code> | Base64 encoding of the image data, _or_ the image file URI, depending on [`cameraOptions`](#module_camera.CameraOptions) in effect. |
| imageData | <code>string</code> | Data URI, _or_ the image file URI, depending on [`cameraOptions`](#module_camera.CameraOptions) in effect. |
**Example**
```js
// Show image
//
// Show image captured with FILE_URI
function cameraCallback(imageData) {
window.resolveLocalFileSystemURL(uri, (entry) => {
let image = document.getElementById('myImage');
image.src = entry.toURL();
}, onError);
}
// Show image captured with DATA_URL
function cameraCallback(imageData) {
var image = document.getElementById('myImage');
image.src = "data:image/jpeg;base64," + imageData;
image.src = imageData;
}
```
<a name="module_camera.CameraOptions"></a>
@@ -257,13 +307,13 @@ Optional parameters to customize the camera settings.
| quality | <code>number</code> | <code>50</code> | Quality of the saved image, expressed as a range of 0-100, where 100 is typically full resolution with no loss from file compression. (Note that information about the camera's resolution is unavailable.) |
| destinationType | <code>[DestinationType](#module_Camera.DestinationType)</code> | <code>FILE_URI</code> | Choose the format of the return value. |
| sourceType | <code>[PictureSourceType](#module_Camera.PictureSourceType)</code> | <code>CAMERA</code> | Set the source of the picture. |
| allowEdit | <code>Boolean</code> | <code>false</code> | Allow simple editing of image before selection. |
| ~~allowEdit~~ | <code>Boolean</code> | <code>false</code> | **Deprecated**. Allow simple editing of image before selection. |
| encodingType | <code>[EncodingType](#module_Camera.EncodingType)</code> | <code>JPEG</code> | Choose the returned image file's encoding. |
| targetWidth | <code>number</code> | | Width in pixels to scale image. Must be used with `targetHeight`. Aspect ratio remains constant. |
| targetHeight | <code>number</code> | | Height in pixels to scale image. Must be used with `targetWidth`. Aspect ratio remains constant. |
| mediaType | <code>[MediaType](#module_Camera.MediaType)</code> | <code>PICTURE</code> | Set the type of media to select from. Only works when `PictureSourceType` is `PHOTOLIBRARY` or `SAVEDPHOTOALBUM`. |
| correctOrientation | <code>Boolean</code> | | Rotate the image to correct for the orientation of the device during capture. |
| saveToPhotoAlbum | <code>Boolean</code> | | Save the image to the photo album on the device after capture. |
| saveToPhotoAlbum | <code>Boolean</code> | | Save the image to the photo album on the device after capture.<br />See [Android Quirks](#cameragetpicturesuccesscallback-errorcallback-options). |
| popoverOptions | <code>[CameraPopoverOptions](#module_CameraPopoverOptions)</code> | | iOS-only options that specify popover location in iPad. |
| cameraDirection | <code>[Direction](#module_Camera.Direction)</code> | <code>BACK</code> | Choose the camera to use (front- or back-facing). |
@@ -282,7 +332,7 @@ Defines the output format of `Camera.getPicture` call.
| Name | Type | Default | Description |
| --- | --- | --- | --- |
| DATA_URL | <code>number</code> | <code>0</code> | Return base64 encoded string. DATA_URL can be very memory intensive and cause app crashes or out of memory errors. Use FILE_URI if possible |
| DATA_URL | <code>number</code> | <code>0</code> | Return data uri. DATA_URL can be very memory intensive and cause app crashes or out of memory errors. Use FILE_URI if possible |
| FILE_URI | <code>number</code> | <code>1</code> | Return file uri (content://media/external/images/media/2 for Android) |
<a name="module_Camera.EncodingType"></a>
@@ -409,38 +459,46 @@ window.onorientationchange = function() {
Take a photo and retrieve the image's file location:
navigator.camera.getPicture(onSuccess, onFail, { quality: 50,
destinationType: Camera.DestinationType.FILE_URI });
```javascript
// Don't forget to install cordova-plugin-file for resolveLocalFileSystemURL!
function onSuccess(imageURI) {
var image = document.getElementById('myImage');
image.src = imageURI;
}
navigator.camera.getPicture(onSuccess, onFail, { quality: 50,
destinationType: Camera.DestinationType.FILE_URI });
function onFail(message) {
alert('Failed because: ' + message);
}
function onSuccess(imageURI) {
window.resolveLocalFileSystemURL(uri, (entry) => {
let img = document.getElementById('image');
img.src = entry.toURL();
}, onFail);
}
function onFail(message) {
alert('Failed because: ' + message);
}
```
Take a photo and retrieve it as a Base64-encoded image:
/**
* Warning: Using DATA_URL is not recommended! The DATA_URL destination
* type is very memory intensive, even with a low quality setting. Using it
* can result in out of memory errors and application crashes. Use FILE_URI
* instead.
*/
navigator.camera.getPicture(onSuccess, onFail, { quality: 25,
destinationType: Camera.DestinationType.DATA_URL
});
```javascript
/**
* Warning: Using DATA_URL is not recommended! The DATA_URL destination
* type is very memory intensive, even with a low quality setting. Using it
* can result in out of memory errors and application crashes. Use FILE_URI
* instead.
*/
navigator.camera.getPicture(onSuccess, onFail, { quality: 25,
destinationType: Camera.DestinationType.DATA_URL
});
function onSuccess(imageData) {
var image = document.getElementById('myImage');
image.src = "data:image/jpeg;base64," + imageData;
}
function onSuccess(imageData) {
var image = document.getElementById('myImage');
image.src = imageData;
}
function onFail(message) {
alert('Failed because: ' + message);
}
function onFail(message) {
alert('Failed because: ' + message);
}
```
#### Preferences (iOS)
@@ -461,7 +519,7 @@ successful.
#### Browser Quirks
Can only return photos as Base64-encoded image.
Can only return photos as data URI image.
#### iOS Quirks
@@ -470,9 +528,11 @@ can cause problems. Wrap the alert within a `setTimeout()` to allow
the iOS image picker or popover to fully close before the alert
displays:
setTimeout(function() {
// do your thing here!
}, 0);
```javascript
setTimeout(function() {
// do your thing here!
}, 0);
```
## `CameraOptions` Errata <a name="CameraOptions-quirks"></a>
@@ -486,11 +546,6 @@ displays:
- Ignores the `encodingType` parameter if the image is unedited (i.e. `quality` is 100, `correctOrientation` is false, and no `targetHeight` or `targetWidth` are specified). The `CAMERA` source will always return the JPEG file given by the native camera and the `PHOTOLIBRARY` and `SAVEDPHOTOALBUM` sources will return the selected file in its existing encoding.
#### iOS Quirks
- When using `destinationType.FILE_URI`, photos are saved in the application's temporary directory. The contents of the application's temporary directory is deleted when the application ends.
[android_lifecycle]: http://cordova.apache.org/docs/en/dev/guide/platforms/android/lifecycle.html
## Sample: Take Pictures, Select Pictures from the Picture Library, and Get Thumbnails <a name="sample"></a>
@@ -639,9 +694,9 @@ function openFilePicker(selection) {
## Take a picture and get a FileEntry Object <a name="convert"></a>
If you want to do something like copy the image to another location, or upload it somewhere using the FileTransfer plugin, you need to get a FileEntry object for the returned picture. To do that, call `window.resolveLocalFileSystemURL` on the file URI returned by the Camera app. If you need to use a FileEntry object, set the `destinationType` to `Camera.DestinationType.FILE_URI` in your CameraOptions object (this is also the default value).
If you want to do something like copy the image to another location, or upload it somewhere, an `FileEntry` is needed for the returned picture. To do this, call `window.resolveLocalFileSystemURL` on the file URI returned by the Camera app. If you need to use a FileEntry object, set the `destinationType` to `Camera.DestinationType.FILE_URI` in your CameraOptions object (this is also the default value).
>*Note* You need the [File plugin](https://www.npmjs.com/package/cordova-plugin-file) to call `window.resolveLocalFileSystemURL`.
__NOTE:__ You need the [File plugin](https://www.npmjs.com/package/cordova-plugin-file) to call `window.resolveLocalFileSystemURL`.
Here is the call to `window.resolveLocalFileSystemURL`. The image URI is passed to this function from the success callback of `getPicture`. The success handler of `resolveLocalFileSystemURL` receives the FileEntry object.
@@ -649,39 +704,26 @@ Here is the call to `window.resolveLocalFileSystemURL`. The image URI is passed
function getFileEntry(imgUri) {
window.resolveLocalFileSystemURL(imgUri, function success(fileEntry) {
// Do something with the FileEntry object, like write to it, upload it, etc.
// writeFile(fileEntry, imgUri);
console.log("got file: " + fileEntry.fullPath);
// displayFileData(fileEntry.nativeURL, "Native URL");
// Example 1: Copy to app data directory
window.resolveLocalFileSystemURL(cordova.file.dataDirectory, function (dataDirectoryEntry) {
fileEntry.copyTo(dataDirectoryEntry, "profilePic", onSuccess, onError);
}, onError);
// Example 2: Upload it!
fileEntry.file(function (file) {
var reader = new FileReader();
reader.onloadend = function() {
var xhr = new XMLHttpRequest();
xhr.open('POST', 'https://myserver.com/upload');
xhr.onload = function () {
// All done!
};
xhr.send(this.result);
};
}, function () {
// If don't get the FileEntry (which may happen when testing
// on some emulators), copy to a new FileEntry.
createNewFileEntry(imgUri);
});
}
```
In the example shown in the preceding code, you call the app's `createNewFileEntry` function if you don't get a valid FileEntry object. The image URI returned from the Camera app should result in a valid FileEntry, but platform behavior on some emulators may be different for files returned from the file picker.
>*Note* To see an example of writing to a FileEntry, see the [File plugin README](https://www.npmjs.com/package/cordova-plugin-file).
The code shown here creates a file in your app's cache (in sandboxed storage) named `tempFile.jpeg`. With the new FileEntry object, you can copy the image to the file or do something else like upload it.
```js
function createNewFileEntry(imgUri) {
window.resolveLocalFileSystemURL(cordova.file.cacheDirectory, function success(dirEntry) {
// JPEG file
dirEntry.getFile("tempFile.jpeg", { create: true, exclusive: false }, function (fileEntry) {
// Do something with it, like write to it, upload it, etc.
// writeFile(fileEntry, imgUri);
console.log("got file: " + fileEntry.fullPath);
// displayFileData(fileEntry.fullPath, "File copied to");
}, onErrorCreateFile);
}, onErrorResolveUrl);
reader.readAsArrayBuffer(file);
}, onError);
}, onError);
}
```

View File

@@ -20,6 +20,41 @@
-->
# Release Notes
### 8.0.0 (Oct 30, 2024)
**Breaking Changes:**
* [GH-889](https://github.com/apache/cordova-plugin-camera/pull/889) fix(android): Remove media permissions to make complaint with **Android** 14 requirements (#889)
* [GH-902](https://github.com/apache/cordova-plugin-camera/pull/902) fix(android): return content uris when possible when selecting from gallery (#902)
* [GH-909](https://github.com/apache/cordova-plugin-camera/pull/909) refactor(android): Make WRITE_EXTERNAL_STORAGE optional (#909)
* [GH-910](https://github.com/apache/cordova-plugin-camera/pull/910) fix(android): Return data uris as an URI (#910)
* [GH-911](https://github.com/apache/cordova-plugin-camera/pull/911) fix(ios): Sync camera API return to match **Android** changes (#911)
* [GH-912](https://github.com/apache/cordova-plugin-camera/pull/912) fix(browser): Make data uri be returned as actual URI strings (#912)
**Fixes**:
* [GH-901](https://github.com/apache/cordova-plugin-camera/pull/901) fix(android): Isolate provider access to a subdirectory (#901)
* [GH-915](https://github.com/apache/cordova-plugin-camera/pull/903) fix(android): Improper serialization of image uri in save instance state (#903)
* [GH-904](https://github.com/apache/cordova-plugin-camera/pull/904) fix(android): Use VERSION_CODES instead of hard-coded API literals (#904)
* [GH-915](https://github.com/apache/cordova-plugin-camera/pull/905) fix(android): improper cache path construction during image manipulation (#905)
* [GH-906](https://github.com/apache/cordova-plugin-camera/pull/906) refactor(android): replace image path usage with image uris (#906)
* [GH-915](https://github.com/apache/cordova-plugin-camera/pull/907) refactor(android): remove query img usage (#907)
* [GH-915](https://github.com/apache/cordova-plugin-camera/pull/915) fix!: Remove WRITE_EXTERNAL_PERMISSION (#915)
**CI**:
* [GH-890](https://github.com/apache/cordova-plugin-camera/pull/890) ci(android): Update **Android** CI to be compatible with `cordova-android`@13 (#890)
* [GH-895](https://github.com/apache/cordova-plugin-camera/pull/895) ci: sync workflow with paramedic (#895)
**Documentation**:
* [GH-913](https://github.com/apache/cordova-plugin-camera/pull/913) docs: Revisions for v8 public API changes with the return string formats of getPicture (#913)
**Other**:
* [GH-898](https://github.com/apache/cordova-plugin-camera/pull/898) chore: Update eslint config to 5.1.0 (#898)
* [GH-914](https://github.com/apache/cordova-plugin-camera/pull/914) deprecation: allowEdit (#914)
### 7.0.0 (Sep 06, 2023)
**Breaking Changes:**

23
package-lock.json generated
View File

@@ -1,15 +1,15 @@
{
"name": "cordova-plugin-camera",
"version": "7.0.0",
"version": "8.0.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "cordova-plugin-camera",
"version": "7.0.0",
"version": "8.0.0",
"license": "Apache-2.0",
"devDependencies": {
"@cordova/eslint-config": "^5.0.0"
"@cordova/eslint-config": "^5.1.0"
},
"engines": {
"cordovaDependencies": {
@@ -41,6 +41,11 @@
"cordova-ios": ">=5.1.0"
},
"8.0.0": {
"cordova": ">=9.0.0",
"cordova-android": ">=12.0.0",
"cordova-ios": ">=5.1.0"
},
"9.0.0": {
"cordova": ">100"
}
}
@@ -56,9 +61,9 @@
}
},
"node_modules/@cordova/eslint-config": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/@cordova/eslint-config/-/eslint-config-5.0.0.tgz",
"integrity": "sha512-tBSV8LbT6RjWsO2lSp45Y+zU7hfXhGMGhfYTZjDrjzli87WOgE6IAS37k6F45JNoGq1XlCJEVkCWwz4KCF8Scw==",
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/@cordova/eslint-config/-/eslint-config-5.1.0.tgz",
"integrity": "sha512-9Da72mSQli08ylGf6jYKWJo67LSu6HWlDPELJsW+bVVos3b0ZMxXsHUCluwrlmZ+sxCFq7VhxAFjK+2/YQFncw==",
"dev": true,
"dependencies": {
"eslint": "^8.31.0",
@@ -2494,9 +2499,9 @@
"dev": true
},
"@cordova/eslint-config": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/@cordova/eslint-config/-/eslint-config-5.0.0.tgz",
"integrity": "sha512-tBSV8LbT6RjWsO2lSp45Y+zU7hfXhGMGhfYTZjDrjzli87WOgE6IAS37k6F45JNoGq1XlCJEVkCWwz4KCF8Scw==",
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/@cordova/eslint-config/-/eslint-config-5.1.0.tgz",
"integrity": "sha512-9Da72mSQli08ylGf6jYKWJo67LSu6HWlDPELJsW+bVVos3b0ZMxXsHUCluwrlmZ+sxCFq7VhxAFjK+2/YQFncw==",
"dev": true,
"requires": {
"eslint": "^8.31.0",

View File

@@ -1,6 +1,6 @@
{
"name": "cordova-plugin-camera",
"version": "7.0.0",
"version": "8.0.0",
"description": "Cordova Camera Plugin",
"types": "./types/index.d.ts",
"cordova": {
@@ -57,11 +57,16 @@
"cordova": ">=9.0.0"
},
"8.0.0": {
"cordova-android": ">=12.0.0",
"cordova-ios": ">=5.1.0",
"cordova": ">=9.0.0"
},
"9.0.0": {
"cordova": ">100"
}
}
},
"devDependencies": {
"@cordova/eslint-config": "^5.0.0"
"@cordova/eslint-config": "^5.1.0"
}
}

View File

@@ -21,7 +21,7 @@
<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
xmlns:android="http://schemas.android.com/apk/res/android"
id="cordova-plugin-camera"
version="7.0.0">
version="8.0.0">
<name>Camera</name>
<description>Cordova Camera Plugin</description>
<license>Apache 2.0</license>
@@ -54,11 +54,6 @@
<param name="android-package" value="org.apache.cordova.camera.CameraLauncher"/>
</feature>
</config-file>
<config-file target="AndroidManifest.xml" parent="/*">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="32" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
</config-file>
<config-file target="AndroidManifest.xml" parent="application">
<provider
android:name="org.apache.cordova.camera.FileProvider"

File diff suppressed because it is too large Load Diff

View File

@@ -19,6 +19,7 @@
package org.apache.cordova.camera;
import java.io.IOException;
import java.io.InputStream;
import android.media.ExifInterface;
@@ -56,6 +57,16 @@ public class ExifHelper {
this.inFile = new ExifInterface(filePath);
}
/**
* The file before it is compressed
*
* @param input
* @throws IOException
*/
public void createInFile(InputStream input) throws IOException {
this.inFile = new ExifInterface(input);
}
/**
* The file after it has been compressed
*

View File

@@ -17,5 +17,5 @@
-->
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<cache-path name="cache_files" path="." />
</paths>
<cache-path name="cache_files" path="org.apache.cordova.camera/" />
</paths>

View File

@@ -39,7 +39,7 @@ function takePicture (success, error, opts) {
const imageData = readerEvent.target.result;
return success(imageData.substr(imageData.indexOf(',') + 1));
return success(imageData);
};
reader.readAsDataURL(inputEvent.target.files[0]);
@@ -78,8 +78,7 @@ function capture (success, errorCallback, opts) {
canvas.getContext('2d').drawImage(video, 0, 0, targetWidth, targetHeight);
// convert image stored in canvas to base64 encoded image
let imageData = canvas.toDataURL('image/png');
imageData = imageData.replace('data:image/png;base64,', '');
const imageData = canvas.toDataURL('image/png');
// stop video stream, remove video and button.
// Note that MediaStream.stop() is deprecated as of Chrome 47.

View File

@@ -58,6 +58,9 @@ static NSString* toBase64(NSData* data) {
}
}
static NSString* MIME_PNG = @"image/png";
static NSString* MIME_JPEG = @"image/jpeg";
@implementation CDVPictureOptions
+ (instancetype) createFromTakePictureArguments:(CDVInvokedUrlCommand*)command
@@ -372,16 +375,50 @@ static NSString* toBase64(NSData* data) {
self.hasPendingOperation = NO;
}
- (NSData*)processImage:(UIImage*)image info:(NSDictionary*)info options:(CDVPictureOptions*)options
- (NSString*) getMimeForEncoding:(CDVEncodingType) encoding {
switch (encoding) {
case EncodingTypePNG: return MIME_PNG;
case EncodingTypeJPEG:
default:
return MIME_JPEG;
}
}
- (NSString*) formatAsDataURI:(NSData*) data withMIME:(NSString*) mime {
NSString* base64 = toBase64(data);
if (base64 == nil) {
return nil;
}
return [NSString stringWithFormat:@"data:%@;base64,%@", mime, base64];
}
- (NSString*) processImageAsDataUri:(UIImage*) image info:(NSDictionary*) info options:(CDVPictureOptions*) options
{
NSString* mime = nil;
NSData* data = [self processImage: image info: info options: options outMime: &mime];
return [self formatAsDataURI: data withMIME: mime];
}
- (NSData*) processImage:(UIImage*) image info:(NSDictionary*) info options:(CDVPictureOptions*) options
{
return [self processImage:image info: info options: options outMime: nil];
}
- (NSData*) processImage:(UIImage*)image info:(NSDictionary*)info options:(CDVPictureOptions*)options outMime:(NSString**) outMime
{
NSData* data = nil;
switch (options.encodingType) {
case EncodingTypePNG:
data = UIImagePNGRepresentation(image);
if (outMime != nil) *outMime = MIME_PNG;
break;
case EncodingTypeJPEG:
{
if (outMime != nil) *outMime = MIME_JPEG;
if ((options.allowsEditing == NO) && (options.targetSize.width <= 0) && (options.targetSize.height <= 0) && (options.correctOrientation == NO) && (([options.quality integerValue] == 100) || (options.sourceType != UIImagePickerControllerSourceTypeCamera))){
// use image unedited as requested , don't resize
data = UIImageJPEGRepresentation(image, 1.0);
@@ -439,7 +476,8 @@ static NSString* toBase64(NSData* data) {
default:
break;
};
return data;
}
@@ -564,9 +602,9 @@ static NSString* toBase64(NSData* data) {
case DestinationTypeDataUrl:
{
image = [self retrieveImage:info options:options];
NSData* data = [self processImage:image info:info options:options];
NSString* data = [self processImageAsDataUri:image info:info options:options];
if (data) {
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:toBase64(data)];
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString: data];
}
}
break;
@@ -574,6 +612,7 @@ static NSString* toBase64(NSData* data) {
{
image = [self retrieveImage:info options:options];
NSData* data = [self processImage:image info:info options:options];
if (data) {
if (pickerController.sourceType == UIImagePickerControllerSourceTypePhotoLibrary) {
NSMutableData *imageDataWithExif = [NSMutableData data];
@@ -823,7 +862,9 @@ static NSString* toBase64(NSData* data) {
switch (options.destinationType) {
case DestinationTypeDataUrl:
{
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:toBase64(self.data)];
NSString* mime = [self getMimeForEncoding: self.pickerController.pictureOptions.encodingType];
NSString* uri = [self formatAsDataURI: self.data withMIME: mime];
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString: uri];
}
break;
default: // DestinationTypeFileUri

13
tests/package-lock.json generated Normal file
View File

@@ -0,0 +1,13 @@
{
"name": "cordova-plugin-camera-tests",
"version": "8.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "cordova-plugin-camera-tests",
"version": "8.0.0",
"license": "Apache-2.0"
}
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "cordova-plugin-camera-tests",
"version": "7.0.0",
"version": "8.0.0",
"description": "",
"cordova": {
"id": "cordova-plugin-camera-tests",

View File

@@ -22,7 +22,7 @@
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:rim="http://www.blackberry.com/ns/widgets"
id="cordova-plugin-camera-tests"
version="7.0.0">
version="8.0.0">
<name>Cordova Camera Plugin Tests</name>
<license>Apache 2.0</license>

View File

@@ -143,6 +143,10 @@ cameraExport.getPicture = function (successCallback, errorCallback, options) {
const popoverOptions = getValue(options.popoverOptions, null);
const cameraDirection = getValue(options.cameraDirection, Camera.Direction.BACK);
if (allowEdit) {
console.warn('allowEdit is deprecated. It does not work reliably on all platforms. Utilise a dedicated image editing library instead. allowEdit functionality is scheduled to be removed in a future release.');
}
const args = [quality, destinationType, sourceType, targetWidth, targetHeight, encodingType,
mediaType, allowEdit, correctOrientation, saveToPhotoAlbum, popoverOptions, cameraDirection];