rntpc_react-native-image-crop-picker:基于 React Native 的 HarmonyOS 图片选择与裁剪适配项目

基于 react-native-image-crop-picker 的 OpenHarmony 适配版,图片选择与裁剪(支持多选、相机)

分支5Tags14
文件最后提交记录最后更新时间
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) 或更高版本中编译。

已在以下版本中验证通过:

  1. 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),请自由地使用并参与开源。

项目介绍

基于 react-native-image-crop-picker 的 OpenHarmony 适配版,图片选择与裁剪(支持多选、相机)

定制我的领域