fix(android): include orientation option (#454)

* add orientation to data return about image

* reverse witdh-height on andorid if orientation indicates rotation

* update readme

* return whitespace to original state

Co-authored-by: Mats01 <“matej.butkovic@gmail.com”>
This commit is contained in:
Mats01-fer
2023-01-23 15:04:47 +01:00
committed by GitHub
co-authored by Mats01
parent 321ec5637f
commit 872105f2a8
3 changed files with 38 additions and 14 deletions
+2
View File
@@ -241,6 +241,7 @@ Returns a Promise with photo identifier objects from the local camera roll of th
* `location`: Ensures `location` is available in each node. This has a large performance impact on Android.
* `imageSize` : Ensures `image.width` and `image.height` are available in each node. This has a small performance impact on Android.
* `playableDuration` : Ensures `image.playableDuration` is available in each node. This has a medium peformance impact on Android.
* `orientation` : Ensures `image.orientation` is available in each node. This has a small peformance impact on Android. **Android only**
Returns a Promise which when resolved will be of the following shape:
@@ -256,6 +257,7 @@ Returns a Promise which when resolved will be of the following shape:
* `width`: {number | null} : Only set if the `include` parameter contains `imageSize`
* `fileSize`: {number | null} : Only set if the `include` parameter contains `fileSize`
* `playableDuration`: {number | null} : Only set for videos if the `include` parameter contains `playableDuration`. Will be null for images.
* `orientation`: {number | null} : Only set for images if the `include` parameter contains `orientation`. **Android only**
* `timestamp`: {number}
* `location`: {object | null} : Only set if the `include` parameter contains `location`. An object with the following shape:
* `latitude`: {number}
@@ -84,6 +84,7 @@ public class CameraRollModule extends ReactContextBaseJavaModule {
private static final String INCLUDE_LOCATION = "location";
private static final String INCLUDE_IMAGE_SIZE = "imageSize";
private static final String INCLUDE_PLAYABLE_DURATION = "playableDuration";
private static final String INCLUDE_ORIENTATION = "orientation";
private static final String[] PROJECTION = {
Images.Media._ID,
@@ -95,7 +96,8 @@ public class CameraRollModule extends ReactContextBaseJavaModule {
MediaStore.MediaColumns.WIDTH,
MediaStore.MediaColumns.HEIGHT,
MediaStore.MediaColumns.SIZE,
MediaStore.MediaColumns.DATA
MediaStore.MediaColumns.DATA,
MediaStore.MediaColumns.ORIENTATION,
};
private static final String SELECTION_BUCKET = Images.Media.BUCKET_DISPLAY_NAME + " = ?";
@@ -569,6 +571,7 @@ public class CameraRollModule extends ReactContextBaseJavaModule {
int heightIndex = media.getColumnIndex(MediaStore.MediaColumns.HEIGHT);
int sizeIndex = media.getColumnIndex(MediaStore.MediaColumns.SIZE);
int dataIndex = media.getColumnIndex(MediaStore.MediaColumns.DATA);
int orientationIndex = media.getColumnIndex(MediaStore.MediaColumns.ORIENTATION);
boolean includeLocation = include.contains(INCLUDE_LOCATION);
boolean includeFilename = include.contains(INCLUDE_FILENAME);
@@ -576,17 +579,18 @@ public class CameraRollModule extends ReactContextBaseJavaModule {
boolean includeFileExtension = include.contains(INCLUDE_FILE_EXTENSION);
boolean includeImageSize = include.contains(INCLUDE_IMAGE_SIZE);
boolean includePlayableDuration = include.contains(INCLUDE_PLAYABLE_DURATION);
boolean includeOrientation = include.contains(INCLUDE_ORIENTATION);
for (int i = 0; i < limit && !media.isAfterLast(); i++) {
WritableMap edge = new WritableNativeMap();
WritableMap node = new WritableNativeMap();
boolean imageInfoSuccess =
putImageInfo(resolver, media, node, widthIndex, heightIndex, sizeIndex, dataIndex,
putImageInfo(resolver, media, node, widthIndex, heightIndex, sizeIndex, dataIndex, orientationIndex,
mimeTypeIndex, includeFilename, includeFileSize, includeFileExtension, includeImageSize,
includePlayableDuration);
includePlayableDuration, includeOrientation);
if (imageInfoSuccess) {
putBasicNodeInfo(media, node, mimeTypeIndex, groupNameIndex, dateTakenIndex, dateAddedIndex, dateModifiedIndex);
putLocationInfo(media, node, dataIndex, includeLocation,mimeTypeIndex,resolver);
putLocationInfo(media, node, dataIndex, includeLocation, mimeTypeIndex, resolver);
edge.putMap("node", node);
edges.pushMap(edge);
@@ -631,19 +635,21 @@ public class CameraRollModule extends ReactContextBaseJavaModule {
int heightIndex,
int sizeIndex,
int dataIndex,
int orientationIndex,
int mimeTypeIndex,
boolean includeFilename,
boolean includeFileSize,
boolean includeFileExtension,
boolean includeImageSize,
boolean includePlayableDuration) {
boolean includePlayableDuration,
boolean includeOrientation) {
WritableMap image = new WritableNativeMap();
Uri photoUri = Uri.parse("file://" + media.getString(dataIndex));
image.putString("uri", photoUri.toString());
String mimeType = media.getString(mimeTypeIndex);
boolean isVideo = mimeType != null && mimeType.startsWith("video");
boolean putImageSizeSuccess = putImageSize(resolver, media, image, widthIndex, heightIndex,
boolean putImageSizeSuccess = putImageSize(resolver, media, image, widthIndex, heightIndex, orientationIndex,
photoUri, isVideo, includeImageSize);
boolean putPlayableDurationSuccess = putPlayableDuration(resolver, image, photoUri, isVideo,
includePlayableDuration);
@@ -668,6 +674,12 @@ public class CameraRollModule extends ReactContextBaseJavaModule {
image.putNull("extension");
}
if (includeOrientation) {
image.putInt("orientation", media.getInt(orientationIndex));
} else {
image.putNull("orientation");
}
node.putMap("image", image);
return putImageSizeSuccess && putPlayableDurationSuccess;
}
@@ -743,6 +755,7 @@ public class CameraRollModule extends ReactContextBaseJavaModule {
WritableMap image,
int widthIndex,
int heightIndex,
int orientationIndex,
Uri photoUri,
boolean isVideo,
boolean includeImageSize) {
@@ -814,6 +827,13 @@ public class CameraRollModule extends ReactContextBaseJavaModule {
}
int orientation = media.getInt(orientationIndex);
if (orientation % 180 != 0) {
int temp = width;
width = height;
height = temp;
}
image.putInt("width", width);
image.putInt("height", height);
return success;
+10 -8
View File
@@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import {Platform} from 'react-native';
import { Platform } from 'react-native';
import RNCCameraRoll from './nativeInterface';
const GROUP_TYPES_OPTIONS = {
@@ -38,7 +38,8 @@ export type Include =
| 'fileExtension'
| 'location'
| 'imageSize'
| 'playableDuration';
| 'playableDuration'
| 'orientation';
export type AssetType = 'All' | 'Videos' | 'Photos';
@@ -108,6 +109,7 @@ export type PhotoIdentifier = {
width: number;
fileSize: number | null;
playableDuration: number;
orientation: number | null;
};
timestamp: number;
location: {
@@ -174,8 +176,8 @@ export class CameraRoll {
tag: string,
options: SaveToCameraRollOptions = {},
): Promise<string> {
let {type = 'auto'} = options;
const {album = ''} = options;
let { type = 'auto' } = options;
const { album = '' } = options;
if (tag === '') throw new Error('tag must be a valid string');
if (type === 'auto') {
@@ -183,7 +185,7 @@ export class CameraRoll {
if (['mov', 'mp4'].indexOf(fileExtension.toLowerCase()) >= 0) type = 'video';
else type = 'photo';
}
return RNCCameraRoll.saveToCameraRoll(tag, {type, album});
return RNCCameraRoll.saveToCameraRoll(tag, { type, album });
}
static saveToCameraRoll(
@@ -193,17 +195,17 @@ export class CameraRoll {
console.warn(
'CameraRoll.saveToCameraRoll(tag, type) is deprecated. Use the save function instead',
);
return CameraRoll.save(tag, {type});
return CameraRoll.save(tag, { type });
}
static getAlbums(
params: GetAlbumsParams = {assetType: 'All'},
params: GetAlbumsParams = { assetType: 'All' },
): Promise<Album[]> {
return RNCCameraRoll.getAlbums(params);
}
static getParamsWithDefaults(params: GetPhotosParams): GetPhotosParams {
const newParams = {...params};
const newParams = { ...params };
if (newParams.assetType === undefined) newParams.assetType = 'All';
if (newParams.groupTypes === undefined && Platform.OS !== 'android')