mirror of
https://github.com/status-im/react-native-camera-roll.git
synced 2026-08-27 19:31:12 +00:00
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:
@@ -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
@@ -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')
|
||||
|
||||
Reference in New Issue
Block a user