基于 react-native-image-crop-picker 的 OpenHarmony 适配版,图片选择与裁剪(支持多选、相机)
| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
| 11 天前 | ||
| 11 天前 | ||
| 1 个月前 | ||
| 1 个月前 | ||
| 1 年前 | ||
| 11 天前 | ||
| 11 天前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 1 年前 | ||
| 8 年前 | ||
| 1 年前 | ||
| 4 个月前 | ||
| 8 个月前 | ||
| 11 天前 | ||
| 11 天前 | ||
| 1 年前 | ||
| 8 个月前 | ||
| 1 个月前 | ||
| 11 天前 | ||
| 8 年前 | ||
| 1 年前 |
模板版本:v0.4.2
react-native-image-crop-picker
本项目基于 react-native-image-crop-picker 开发。
该第三方库的仓库已迁移至 Gitcode,并支持直接从 npm 下载,新的包名为:@react-native-ohos/react-native-image-crop-picker,各版本对应关系如下:
| 三方库名称 | 三方库版本(npm地址) | 发布信息 | 支持RN版本 | Autolink | 编译API版本 | 社区基线版本 | 源码地址 |
|---|---|---|---|---|---|---|---|
| @react-native-ohos/react-native-image-crop-picker | ~ 0.51.4(开发中) | Gitcode Releases | 0.82./0.84. | 是 | API12+ | 0.51.1 | master |
| @react-native-ohos/react-native-image-crop-picker | 0.51.1-0.51.3 | Gitcode Releases | 0.82./0.84. | 否 | API12+ | 0.51.1 | master |
| @react-native-ohos/react-native-image-crop-picker | ~ 0.50.1 | Gitcode Releases | 0.77.* | 否 | API12+ | 0.51.1 | br_rnoh0.77 |
| @react-native-ohos/react-native-image-crop-picker | ~ 0.40.5 | Gitcode Releases | 0.72.* | 是 | API12+ | 0.40.3 | br_rnoh0.72 |
| @react-native-oh-tpl/react-native-image-crop-picker | <= 0.40.3-0.0.14@deprecated | Github Releases(deprecated) | 0.72.* | 否 | API12+ | 0.40.3 | sig |
简介
本项目基于 react-native-image-crop-picker 开发,为 HarmonyOS 平台提供图片选择与裁剪适配能力。
下载安装
进入工程目录,并执行以下命令:
npm
npm install @react-native-ohos/react-native-image-crop-picker
yarn
yarn add @react-native-ohos/react-native-image-crop-picker
链接
| 是否支持autolink | RN框架版本 | |
|---|---|---|
| ~0.51.4 | 是 | 0.82/0.84 |
| 0.51.1-0.51.3 | 否 | 0.82/0.84 |
使用 AutoLink 的工程需要根据该文档进行配置,Autolink 框架指导文档:https://gitcode.com/CPF-RN/ohos_react_native/blob/master/docs/zh-cn/Autolinking.md
如果您使用的版本支持 Autolink,并且工程已接入 Autolink,则可以跳过 ManualLink 配置。
ManualLink:此步骤介绍如何手动配置原生依赖项。
首先,需要使用 DevEco Studio 打开项目中的 HarmonyOS 工程 harmony。
2.1 在工程根目录的 oh-package.json5 中添加 overrides 字段
为了让工程依赖同一版本的 RN SDK,需要在工程根目录的 oh-package.json5 中添加 overrides 字段,并指向工程需要使用的 RN SDK 版本。替换的版本可以是一个具体版本号、一个模糊版本,也可以是本地存在的 HAR 包或源码目录。
关于该字段的作用,请阅读官方说明
{
"overrides": {
"@rnoh/react-native-openharmony": "^0.82.33" // ohpm 在线版本
// "@rnoh/react-native-openharmony" : "./react_native_openharmony.har" // 指向本地 har 包的路径
// "@rnoh/react-native-openharmony" : "./react_native_openharmony" // 指向源码路径
}
}
2.2 引入原生端代码
目前有两种方式:
- 通过 har 包引入(推荐);
- 直接链接源码。
方式一:通过 har 包引入
har 包位于三方库安装路径的 `harmony` 文件夹下。
打开 entry/oh-package.json5,添加以下依赖
"dependencies": {
"@rnoh/react-native-openharmony": "file:../react_native_openharmony",
"@react-native-ohos/react-native-image-crop-picker": "file:../../node_modules/@react-native-ohos/react-native-image-crop-picker/harmony/image_crop_picker.har"
}
点击右上角的 sync 按钮
或在终端执行:
cd entry
ohpm install
方法二:直接链接源码
如需使用直接链接源码,请参考[直接链接源码说明](https://gitcode.com/CPF-RN/usage-docs/blob/master/zh-cn/link-source-code.md)
2.3 配置 CMakeLists 并引入 ImageCropPickerPackage
打开 entry/src/main/cpp/CMakeLists.txt,添加:
project(rnapp)
cmake_minimum_required(VERSION 3.4.1)
set(RNOH_APP_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
+ set(OH_MODULES "${CMAKE_CURRENT_SOURCE_DIR}/../../../oh_modules")
set(RNOH_CPP_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../react-native-harmony/harmony/cpp")
add_subdirectory("${RNOH_CPP_DIR}" ./rn)
# RNOH_BEGIN: manual_package_linking_1
add_subdirectory("../../../../sample_package/src/main/cpp" ./sample-package)
+ add_subdirectory("${OH_MODULES}/@react-native-ohos/react-native-image-crop-picker/src/main/cpp" ./image-crop-picker)
# RNOH_END: manual_package_linking_1
add_library(rnoh_app SHARED
${GENERATED_CPP_FILES}
"./PackageProvider.cpp"
"${RNOH_CPP_DIR}/RNOHAppNapiBridge.cpp"
)
target_link_libraries(rnoh_app PUBLIC rnoh)
# RNOH_BEGIN: manual_package_linking_2
target_link_libraries(rnoh_app PUBLIC rnoh_sample_package)
+ target_link_libraries(rnoh_app PUBLIC rnoh_image_crop_picker)
# RNOH_END: manual_package_linking_2
打开 entry/src/main/cpp/PackageProvider.cpp,添加:
#include "RNOH/PackageProvider.h"
#include "SamplePackage.h"
+ #include "ImageCropPickerPackage.h"
using namespace rnoh;
std::vector<std::shared_ptr<Package>> PackageProvider::getPackages(Package::Context ctx) {
return {
std::make_shared<SamplePackage>(ctx),
+ std::make_shared<ImageCropPickerPackage>(ctx),
};
}
2.4 在 ArkTs 侧引入 ImageCropPickerPackage
打开 entry/src/main/ets/RNPackagesFactory.ts,添加:
...
+ import { ImageCropPickerPackage } from '@react-native-ohos/react-native-image-crop-picker/ts';
export function createRNPackages(ctx: RNPackageContext): RNPackage[] {
return [
new SamplePackage(ctx),
+ new ImageCropPickerPackage(ctx),
];
}
必要的配置项
此模块的内容无法通过 autolink 自动生成,必须手动配置。
配置 Entry(该模块始终需要手动配置)
(1) 在 entry/src/main/ets/entryability 目录下创建 ImageEditAbility.ets
import UIAbility from '@ohos.app.ability.UIAbility'
import window from '@ohos.window'
import { BusinessError } from "@ohos.base";
const TAG = 'ImageEditAbility';
export default class ImageEditAbility extends UIAbility {
onWindowStageCreate(windowStage: window.WindowStage) {
this.setWindowOrientation(windowStage, window.Orientation.PORTRAIT)
windowStage.loadContent('pages/ImageEdit', (err, data) => {
let windowClass: window.Window = windowStage.getMainWindowSync()
let isLayoutFullScreen = true
windowClass.setWindowLayoutFullScreen(isLayoutFullScreen).then(() => {
console.info('Succeeded in setting the window layout to full-screen mode.')
}).catch((err: BusinessError) => {
console.error(`Failed to set the window layout to full-screen mode. Code is ${err.code}, message is ${err.message}`)
})
let type = window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR;
let avoidArea = windowClass.getWindowAvoidArea(type);
let bottomRectHeight = avoidArea.bottomRect.height; // 获取到导航区域的高度
AppStorage.setOrCreate('bottomRectHeight', bottomRectHeight);
type = window.AvoidAreaType.TYPE_SYSTEM;
avoidArea = windowClass.getWindowAvoidArea(type);
let topRectHeight = avoidArea.topRect.height; // 获取状态栏区域高度
AppStorage.setOrCreate('topRectHeight', topRectHeight);
windowClass.on('avoidAreaChange', (data) => {
if (data.type === window.AvoidAreaType.TYPE_SYSTEM) {
let topRectHeight = data.area.topRect.height;
AppStorage.setOrCreate('topRectHeight', topRectHeight);
} else if (data.type == window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR) {
let bottomRectHeight = data.area.bottomRect.height;
AppStorage.setOrCreate('bottomRectHeight', bottomRectHeight);
}
});
if (err.code) {
console.info(TAG,'Failed to load the content. Cause: %{public}s',
JSON.stringify(err) ?? '')
return;
}
console.info(TAG,'Succeeded in loading the content')
});
try {
windowStage.getMainWindowSync().setWindowLayoutFullScreen(true, (err)=>{
if (err.code) {
console.error('Failed to enable the full-screen mode. Cause: ' + JSON.stringify(err));
return;
}
console.info('Succeeded in enabling the full-screen mode.');
})
} catch (exception) {
console.error('Failed to set the system bar to be invisible. Cause: ' + JSON.stringify(exception));
}
}
setWindowOrientation(stage: window.WindowStage, orientation: window.Orientation): void {
console.info(TAG,"into setWindowOrientation :")
if (!stage || !orientation) {
return;
}
stage.getMainWindow().then(windowInstance => {
windowInstance.setPreferredOrientation(orientation);
})
}
onBackground() {
this.context.terminateSelf();
}
}
(2) 在 entry/src/main/module.json5 中注册 ImageEditAbility
"abilities":[
...
+ {
+ "name": "ImageEditAbility",
+ "srcEntry": "./ets/entryability/ImageEditAbility.ets",
+ "description": "$string:EntryAbility_desc",
+ "icon": "$media:icon",
+ "startWindowIcon": "$media:startIcon",
+ "startWindowBackground": "$color:start_window_background",
+ "removeMissionAfterTerminate": true,
+ }
]
(3) 在 entry/src/main/ets/pages 目录下创建 ImageEdit.ets
import { ImageEditInfo } from '@react-native-ohos/react-native-image-crop-picker';
import { CircleImageInfo } from '@react-native-ohos/react-native-image-crop-picker';
@Entry
@Component
struct ImageEdit {
@State cropperCircleOverlay: boolean = false;
aboutToAppear(): void {
this.cropperCircleOverlay = AppStorage.Get('cropperCircleOverlay') || false
}
build() {
Row() {
Column() {
if(!this.cropperCircleOverlay){
ImageEditInfo()
} else {
CircleImageInfo()
}
}
.width('100%')
}
.height('100%')
}
}
(4) 在 entry/src/main/resources/base/profile/main_pages.json 中添加配置
{
"src": [
"pages/Index",
"pages/ImageEdit"
]
}
运行
点击右上角的 sync 按钮
或者在终端中执行:
cd entry
ohpm install
然后编译并运行即可。
约束与限制
兼容性
要使用此库,请确保使用匹配的 React-Native 与 RNOH 版本,同时搭配相应的 DevEco Studio 和手机 ROM。
version>=0.51.2 的版本需要在 DevEco Studio 6.0.1 (API21) 或更高版本中编译。
已在以下版本中验证通过:
- RNOH: 0.82.1; SDK: HarmonyOS 6.0.0 Release SDK; IDE: DevEco Studio 6.0.0.858; ROM: 6.0.0.120; 鸿蒙化 react-native-image-crop-picker 版本在 0.51.2 及以后,编译需要 DevEco Studio 6.0.1 (API21) 及以上版本。
使用示例
以下代码展示了该库的基本用法:
使用时,import 的库名保持不变。
import React, {Component} from 'react';
import {
Alert,
Image,
ScrollView,
StyleSheet,
Text,
TouchableOpacity,
View,
} from 'react-native';
import ImagePicker from 'react-native-image-crop-picker';
export class ImageCropPickerDemo extends Component {
constructor(props: {}) {
super(props);
this.state = {
image: null,
images: null,
};
}
pickSingleWithCamera(
cropping: boolean,
mediaType: 'photo' | 'video' = 'photo',
) {
ImagePicker.openCamera({
cropping: cropping,
width: 500,
height: 500,
includeExif: true,
mediaType,
})
.then(image => {
this.setState({
image: {
uri: image.path,
width: image.width,
height: image.height,
mime: image.mime,
},
images: null,
});
})
.catch(e => Alert.alert('Error', e.message));
}
renderImage(image) {
return (
<Image
style={{width: 300, height: 300, resizeMode: 'contain'}}
source={image}
/>
);
}
render() {
return (
<View style={styles.container}>
<ScrollView>
{this.state.image ? this.renderImage(this.state.image) : null}
{this.state.images
? this.state.images.map(i => (
<View key={i.uri}>{this.renderImage(i)}</View>
))
: null}
</ScrollView>
<TouchableOpacity
onPress={() => this.pickSingleWithCamera(false)}
style={styles.button}>
<Text style={styles.text}>Select Single Image With Camera</Text>
</TouchableOpacity>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
button: {
backgroundColor: 'blue',
marginBottom: 10,
},
text: {
color: 'white',
fontSize: 20,
textAlign: 'center',
},
});
接口说明
API
"Platform" 列表示该属性在原三方库中支持的平台。
"HarmonyOS Support" 列:支持表示 HarmonyOS 平台支持该属性;不支持表示 HarmonyOS 平台不支持该属性;部分支持表示部分支持。各平台使用方法一致,效果对标 iOS 或 Android。
| 名称 | 类型 | 参数类型 | 返回值 | 必填 | 平台 | HarmonyOS平台支持 | 描述 |
|---|---|---|---|---|---|---|---|
| openPicker | function | options: Options | Promise<PossibleArray<O, MediaType<O>>> | 否 | 全部 | 支持 | 调用带裁剪功能的单图选择器 |
| openCamera | function | options: Options | Promise<PossibleArray<O, MediaType<O>>> | 否 | 全部 | 支持 | 从相机选择图片 |
| openCropper | function | options: CropperOptions | Promise<Image> | 否 | 全部 | 支持 | 裁剪图片并支持旋转 |
| clean | function | / | Promise<void> | 否 | 全部 | 支持 | 清除本库生成的所有临时文件 |
| cleanSingle | function | path: string | Promise<void> | 否 | 全部 | 支持 | 删除单个缓存文件 |
属性
"Platform" 列表示该属性在原三方库中支持的平台。
"HarmonyOS Support" 列:支持表示 HarmonyOS 平台支持该属性;不支持表示 HarmonyOS 平台不支持该属性;部分支持表示部分支持。各平台使用方法一致,效果对标 iOS 或 Android。
以下为该库的可配置选项,按功能分组:
选择配置
| 名称 | 类型 | 参数类型 | 返回值 | 必填 | 平台 | HarmonyOS平台支持 | 描述 |
|---|---|---|---|---|---|---|---|
| mediaType | property | mediaType: string (默认 any) | / | 否 | 全部 | 支持 | 图片选择支持的媒体类型,可选值为 'photo'(照片)、'video'(视频)或 'any'(任意) |
| multiple | property | multiple: boolean (默认 false) | / | 否 | 全部 | 支持 | 启用或禁用多图选择功能 |
| minFiles(仅 iOS) | property | minFiles: number (默认 1) | / | 否 | iOS | 不支持 | 启用 multiple 时,最少选择的文件数量 |
| maxFiles(仅 iOS) | property | maxFiles: number (默认 5) | / | 否 | iOS | 支持 | 启用 multiple 时,最多选择的文件数量 |
| showsSelectedCount(仅 iOS) | property | showsSelectedCount: boolean (默认 true) | / | 否 | iOS | 不支持 | 是否显示已选中的资源数量 |
| useFrontCamera | property | useFrontCamera: boolean (默认 false) | / | 否 | 全部 | 支持 | 打开相机时是否默认使用前置 / 自拍相机 |
| writeTempFile(仅 iOS) | property | writeTempFile: boolean (默认 true) | / | 否 | iOS | 支持 | 设为 false 时,不会为选中的图片生成临时文件(配合 includeBase64 提升性能) |
| includeBase64 | property | includeBase64: boolean (默认 false) | / | 否 | 全部 | 支持 | 图片文件内容将以 Base64 编码字符串的形式存在于 data 属性中 |
| includeExif | property | includeExif: boolean (默认 false) | / | 否 | 全部 | 支持 | 在响应中包含图片的 EXIF 数据 |
| smartAlbums(仅 iOS) | property | smartAlbums: array | / | 否 | iOS | 不支持 | 可选择的智能相册列表 |
| sortOrder(仅 iOS) | property | sortOrder: string (默认 'none') | / | 否 | iOS | 不支持 | 按创建日期对相册 / 图片视图中的媒体资源进行排序 |
| loadingLabelText(仅 iOS) | property | loadingLabelText: string | / | 否 | iOS | 不支持 | 选择器中图片加载时显示的文本 |
| waitAnimationEnd(仅 iOS) | property | waitAnimationEnd: boolean (默认 true) | / | 否 | iOS | 不支持 | 视图控制器的 completion 回调块被调用后,Promise 才会解析 / 拒绝 |
裁剪配置
| 名称 | 类型 | 参数类型 | 返回值 | 必填 | 平台 | HarmonyOS平台支持 | 描述 |
|---|---|---|---|---|---|---|---|
| cropping | property | cropping: boolean (默认 false) | / | 否 | 全部 | 支持 | 启用或禁用裁剪功能 |
| width | property | width: number | / | 否 | 全部 | 支持 | 启用 cropping 时,结果图片的宽度 |
| height | property | height: number | / | 否 | 全部 | 支持 | 启用 cropping 时,结果图片的高度 |
| avoidEmptySpaceAroundImage(仅 iOS) | property | avoidEmptySpaceAroundImage: boolean (默认 true) | / | 否 | iOS | 不支持 | 设为 true 时,图片将始终填充遮罩区域 |
| freeStyleCropEnabled | property | freeStyleCropEnabled: boolean (默认 false) | / | 否 | 全部 | 支持 | 允许用户自定义裁剪区域的矩形范围 |
| cropperCircleOverlay | property | cropperCircleOverlay: boolean (默认 false) | / | 否 | 全部 | 支持 | 启用或禁用圆形裁剪遮罩 |
| enableRotationGesture(仅 Android) | property | enableRotationGesture: boolean (默认 false) | / | 否 | Android | 支持 | 是否允许通过手势旋转图片 |
| cropperRotateButtonsHidden(仅 iOS) | property | cropperRotateButtonsHidden: boolean (默认 false) | / | 否 | iOS | 支持 | 启用或禁用裁剪器的旋转按钮 |
| showCropGuidelines(仅 Android) | property | showCropGuidelines: boolean (默认 true) | / | 否 | Android | 支持 | 裁剪过程中是否在图片上方显示 3x3 网格线 |
| showCropFrame(仅 Android) | property | showCropFrame: boolean (默认 true) | / | 否 | Android | 支持 | 裁剪过程中是否显示裁剪框 |
| hideBottomControls(仅 Android) | property | hideBottomControls: boolean (默认 false) | / | 否 | Android | 不支持 | 是否显示底部控制栏 |
裁剪页 UI 配置
| 名称 | 类型 | 参数类型 | 返回值 | 必填 | 平台 | HarmonyOS平台支持 | 描述 |
|---|---|---|---|---|---|---|---|
| cropperToolbarTitle | property | cropperToolbarTitle: string (默认 Edit Photo) | / | 否 | 全部 | 支持 | 裁剪图片时,指定工具栏的标题 |
| cropperCancelText(仅 iOS) | property | cropperCancelText: string (默认 Cancel) | / | 否 | iOS | 支持 | 取消按钮的文本 |
| cropperCancelColor(仅 iOS) | property | cropperCancelColor: string | / | 否 | iOS | 支持 | 取消按钮颜色,默认值为 iOS 系统默认 tint 颜色 |
| cropperChooseText(仅 iOS) | property | cropperChooseText: string (默认 choose) | / | 否 | iOS | 支持 | 确认选择按钮的文本 |
| cropperChooseColor(仅 iOS) | property | cropperChooseColor: string (默认 #FFCC00) | / | 否 | iOS | 支持 | 确认选择按钮的十六进制颜色值 |
| cropperTintColor | property | cropperTintColor: string | / | 否 | 全部 | 不支持 | 裁剪页主题色(tint 色) |
| cropperActiveWidgetColor(仅 Android) | property | cropperActiveWidgetColor: string (默认 #424242) | / | 否 | Android | 不支持 | 裁剪框活动组件(ActiveWidget)的颜色 |
| cropperStatusBarColor(仅 Android)自 0.51.1 起已弃用 | property | cropperStatusBarColor: string (默认 #424242) | / | 否 | Android | 不支持 | 裁剪图片时,指定状态栏(StatusBar)的颜色 |
| cropperStatusBarLight(仅 Android)自 0.51.1 起支持 | property | cropperStatusBarLight: boolean (默认 true) | / | 否 | Android | 不支持 | 状态栏为浅色(深色图标)则为真,反之假 |
| cropperNavigationBarLight(仅 Android)自 0.51.1 起支持 | property | cropperNavigationBarLight: boolean (默认 false) | / | 否 | Android | 不支持 | 导航栏为浅色(深色图标)则为真,反之假 |
| cropperToolbarColor(仅 Android) | property | cropperToolbarColor: string (默认 #424242) | / | 否 | Android | 不支持 | 裁剪图片时,指定工具栏(Toolbar)的颜色 |
| cropperToolbarWidgetColor(仅 Android) | property | cropperToolbarWidgetColor: string (默认 darker orange) | / | 否 | Android | 不支持 | 裁剪图片时,指定工具栏文本和按钮的颜色 |
| disableCropperColorSetters(仅 Android) | property | disableCropperColorSetters: boolean (默认 false) | / | 否 | Android | 不支持 | 裁剪图片时,禁用裁剪库的颜色设置功能 |
压缩配置
| 名称 | 类型 | 参数类型 | 返回值 | 必填 | 平台 | HarmonyOS平台支持 | 描述 |
|---|---|---|---|---|---|---|---|
| compressImageQuality | property | compressImageQuality: number (默认 1 (Android)/0.8 (iOS)) | / | 否 | 全部 | 支持 | 按指定质量压缩图片(取值范围 0-1,1 为最佳质量) |
| compressImageMaxWidth | property | compressImageMaxWidth: number (默认 none) | / | 否 | 全部 | 不支持 | 按最大宽度压缩图片 |
| compressImageMaxHeight | property | compressImageMaxHeight: number (默认 none) | / | 否 | 全部 | 不支持 | 按最大高度压缩图片 |
| forceJpg(仅 iOS) | property | forceJpg: boolean (默认 false) | / | 否 | iOS | 支持 | 是否将照片转换为 JPG 格式 |
| compressVideoPreset(仅 iOS) | property | compressVideoPreset: string (默认 MediumQuality) | / | 否 | iOS | 不支持 | 选择视频压缩所使用的预设参数 |
类型定义
| 类型 | 取值 | 参数类型 | 返回值 | 必填 | 平台 | HarmonyOS平台支持 | 描述 |
|---|---|---|---|---|---|---|---|
| Options | AnyOptions | VideoOptions | ImageOptions | / | / | 否 | 全部 | 是 | 全部选项的联合类型,用作 openPicker / openCamera 的参数 |
| ImageOptions | CommonOptions & { mediaType: 'photo'; width?; height?; includeBase64?; includeExif?; forceJpg?; cropping?; avoidEmptySpaceAroundImage?; cropperActiveWidgetColor?; cropperStatusBarLight?; cropperNavigationBarLight?; cropperToolbarColor?; cropperToolbarWidgetColor?; cropperToolbarTitle?; freeStyleCropEnabled?; cropperTintColor?; cropperCircleOverlay?; cropperCancelText?; cropperCancelColor?; cropperChooseText?; cropperChooseColor?; cropperRotateButtonsHidden?; showCropGuidelines?; showCropFrame?; enableRotationGesture?; disableCropperColorSetters?; compressImageMaxWidth?; compressImageMaxHeight?; compressImageQuality? } | / | / | 否 | 全部 | 是 | 图片选项 |
| VideoOptions | CommonOptions & { mediaType: 'video'; compressVideoPreset? } | / | / | 否 | 全部 | 是 | 视频选项 |
| AnyOptions | Omit<ImageOptions, 'mediaType'> & Omit<VideoOptions, 'mediaType'> & { mediaType?: 'any' } | / | / | 否 | 全部 | 是 | 任意媒体类型选项 |
| CropperOptions | ImageOptions & { path: string } | / | / | 否 | 全部 | 是 | 裁剪指定图片的选项,path 为必填项 |
| CommonOptions | { multiple?; minFiles?; maxFiles?; waitAnimationEnd?; smartAlbums?; useFrontCamera?; loadingLabelText?; showsSelectedCount?; sortOrder?; hideBottomControls?; writeTempFile? } | / | / | 否 | 全部 | 是 | 通用选项 |
| Image | ImageVideoCommon & { data?: string | null; cropRect?: CropRect | null } | / | / | 否 | 全部 | 是 | 图片返回对象 |
| Video | ImageVideoCommon & { duration: number | null } | / | / | 否 | 全部 | 是 | 视频返回对象 |
| ImageVideoCommon | { path; size; width; height; mime; exif?; localIdentifier?; sourceURL?; filename?; creationDate?; modificationDate? } | / | / | 否 | 全部 | 是 | 图片 / 视频公共字段 |
| Exif | object | / | / | 否 | 全部 | 是 | 图片 EXIF 元数据对象,启用 includeExif 时返回,字段因平台而异 |
| CropRect | { x: number; y: number; width: number; height: number } | / | / | 否 | 全部 | 是 | 裁剪矩形,坐标基于原图 |
| ImageOrVideo | Image | Video | / | / | 否 | 全部 | 是 | 图片或视频 |
| PossibleArray<O, T> | O extends { multiple: true } ? T[] : T | O, T | T[] | T | 否 | 全部 | 是 | 条件类型:根据 multiple 的取值,返回数组或单个对象 |
| MediaType<O> | O extends { mediaType: 'photo' } ? Image : O extends { mediaType: 'video' } ? Video : ImageOrVideo | O | Image | Video | ImageOrVideo | 否 | 全部 | 是 | 条件类型:根据 mediaType 的取值,确定返回类型 |
错误码
源库通过 Promise reject 抛出以下错误码。HarmonyOS 适配版当前以错误消息字符串形式 reject(例如取消选择时抛出 "User cancelled image selection",等价于 `E_PICKER_CANCELLED`)。下表“HarmonyOS平台支持”列用于标注鸿蒙侧是否存在等价错误。
| 错误码 | 说明 | 平台 | HarmonyOS平台支持 |
|---|---|---|---|
| E_PICKER_CANCELLED | 用户取消了选择操作 | 全部 | 支持 |
| E_NO_IMAGE_DATA_FOUND | 无法找到图片数据 | 全部 | 部分支持(以 "sourceFilePaths is empty" 等消息抛出) |
| E_NO_LIBRARY_PERMISSION | 用户未授予相册访问权限 | 全部 | 不支持 |
| E_NO_CAMERA_PERMISSION | 用户未授予相机权限 | 全部 | 不支持 |
| E_ERROR_WHILE_CLEANING_FILES | 清理临时文件时出错 | 全部 | 部分支持(以原始错误消息抛出) |
| E_PICKER_CANNOT_RUN_CAMERA_ON_SIMULATOR | 相机无法在模拟器上运行 | iOS | 不支持 |
| E_CROPPER_IMAGE_NOT_FOUND | 裁剪器未找到图片 | iOS | 不支持 |
| E_CANNOT_SAVE_IMAGE | 无法保存图片 | iOS | 不支持 |
| E_CANNOT_PROCESS_VIDEO | 无法处理视频 | iOS | 不支持 |
| E_ACTIVITY_DOES_NOT_EXIST | Activity(页面上下文)不存在 | Android | 支持(以 "ability doesn't exist" 消息抛出) |
| E_CALLBACK_ERROR | 回调错误 | Android | 不支持 |
| E_FAILED_TO_SHOW_PICKER | 选择器打开失败 | Android | 不支持 |
| E_FAILED_TO_OPEN_CAMERA | 相机打开失败 | Android | 不支持 |
| E_CAMERA_IS_NOT_AVAILABLE | 相机不可用 | Android | 不支持 |
| E_CANNOT_LAUNCH_CAMERA | 无法启动相机 | Android | 不支持 |
遗留问题
其他
目录结构
/rntpc_react-native-image-crop-picker # 项目根目录
├── .github/ # GitHub Actions、Issue/PR 模板与社区配置
├── example/ # 示例工程:演示与调试用的 React Native / HarmonyOS 示例
│ ├── src/ # 示例应用源码(ImageCropPickDemo 等)
│ ├── harmony/ # 示例中的 HarmonyOS 原生工程(用于本地调试)
│ └── ... # 其他示例配置与脚本(babel/metro/jest 等)
├── harmony/ # HarmonyOS 平台相关的原生代码与资源
│ ├── image_crop_picker.har # 打包好的 HAR(可直接导入 DevEco Studio)
│ └── image_crop_picker/ # 原生源码(C++ / ArkTS / 资源 / 配置)
│ ├── src/main/cpp/ # C++ 原生实现、CMakeLists 与头文件
│ └── src/main/ets/ # ArkTS/ETS 层(模块导出、页面、工具类)
├── js/ # JS/TS 层:原生模块桥接实现(NativeRNCImageCropPicker)
├── README.md # 中文说明文档
├── README_en.md # 英文说明文档
├── package.json # npm 包配置与依赖
├── index.d.ts # TypeScript 类型声明文件
├── LICENSE # 开源许可证(MIT)
├── CHANGELOG.md # 发布日志
└── ... # 其他配置文件(.gitignore、OAT.xml、脚本等)
代码贡献
在使用过程中发现任何问题,都可以提交 Issue,也欢迎提交 PR。
开源协议
本项目基于 The MIT License (MIT),请自由地使用并参与开源。