{"_id":"@bingtang-rn/faster-image","_rev":"3-ca7cc632081e233fd94dd2274c837647","name":"@bingtang-rn/faster-image","dist-tags":{"latest":"1.0.2"},"versions":{"1.0.0":{"name":"@bingtang-rn/faster-image","version":"1.0.0","keywords":["react-native","harmony","harmonyos","faster-image"],"license":"MIT","_id":"@bingtang-rn/faster-image@1.0.0","maintainers":[{"name":"luyizouyuan","email":"189605613@qq.com"}],"homepage":"https://gitcode.com/rn_ohos_plugin/faster_image","dist":{"shasum":"ba3a9a014066eb925c4f10615260925a7a87cb1e","tarball":"https://registry.npmjs.org/@bingtang-rn/faster-image/-/faster-image-1.0.0.tgz","fileCount":42,"integrity":"sha512-xWDAoJrV9y+jydZydqAMDmUvkDAUzsMUbg16/BaRinXjJn9sGoCKn7fLPRepF/z5IoVTLJgkNI25eeyTPFcPtQ==","signatures":[{"sig":"MEUCIQDF38kOVqFa3GkyOSWatNe75n1e7vMquioPbpGx88mhqQIgb5msHHUee+You54T+x2UP07794EqpLu/FXbH3yPqipk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":112717},"main":"./src/index.tsx","module":"./src/index.tsx","engines":{"node":">=18"},"gitHead":"9f8515d04ded7ec2577329e8f95a1526e467bf14","harmony":{"alias":"@candlefinance/faster-image","autolinking":{"ohPackageName":"@oh-rn/faster-image","cppPackageClassName":"FasterImagePackage","etsPackageClassName":"FasterImagePackage","cmakeLibraryTargetName":"faster_image"},"codegenConfig":[{"version":1,"specPaths":["./src/specs/v1"]}]},"private":false,"scripts":{"prepare":"echo skip","codegen-lib":"react-native codegen-harmony --cpp-output-path ./harmony/faster_image/src/main/cpp/generated --ets-output-path ./harmony/faster_image/src/main/ets/generated"},"_npmUser":{"name":"luyizouyuan","email":"189605613@qq.com"},"repository":{"url":"https://gitcode.com/rn_ohos_plugin/faster_image","type":"git"},"_npmVersion":"11.12.1","description":"适配鸿蒙版本，提供faster_image组件。","directories":{},"_nodeVersion":"24.15.0","react-native":"./src/index.tsx","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.6.3","metro":"^0.81.0","react":"18.2.0","typescript":"5.0.4","@types/react":"18.2.79","react-native":"0.72.5","@react-native/typescript-config":"0.79.5","@react-native-oh/react-native-harmony-cli":"^0.77.50"},"peerDependencies":{"react-native":">=0.72"},"_npmOperationalInternal":{"tmp":"tmp/faster-image_1.0.0_1785999745227_0.10463765494929311","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@bingtang-rn/faster-image","version":"1.0.1","keywords":["react-native","harmony","harmonyos","faster-image"],"license":"MIT","_id":"@bingtang-rn/faster-image@1.0.1","maintainers":[{"name":"luyizouyuan","email":"189605613@qq.com"}],"homepage":"https://gitcode.com/rn_ohos_plugin/faster_image","dist":{"shasum":"994be18b33379ab2f0a1b09fe8b5c3262f4735a2","tarball":"https://registry.npmjs.org/@bingtang-rn/faster-image/-/faster-image-1.0.1.tgz","fileCount":42,"integrity":"sha512-PTRXU3twmBrGhGR/k5UdU6gClzQj2zc9I2YjVGSXZv5dlFm0UTOrCw9fQM86agbhXyKBKkej+cqrhR2AMv48LQ==","signatures":[{"sig":"MEUCIQCxEseRS16yZT8c63uI6mkylKDJQ/P2sFXXU8S90xdYXQIgUD/PRGbTs50wpYvnByq9vqq+Xm4fv2gxUwhrS9SDI4Q=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIGqV2tCLePVZes0Ca2Wn0vyzKnyX4CzzZP7XiNsduVa5AiEApxdjeycB1WKkckOBOrJdbdMXsrX1NBSLVFBa/hqWuOc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":112325},"main":"./src/index.tsx","_from":"file:bingtang-rn-faster-image-1.0.1.tgz","module":"./src/index.tsx","engines":{"node":">=18"},"harmony":{"alias":"@candlefinance/faster-image","autolinking":{"ohPackageName":"@bingtang-rn/faster-image","cppPackageClassName":"FasterImagePackage","etsPackageClassName":"FasterImagePackage","cmakeLibraryTargetName":"faster_image"},"codegenConfig":[{"version":1,"specPaths":["./src/specs/v1"]}]},"private":false,"scripts":{"prepare":"echo skip","codegen-lib":"react-native codegen-harmony --cpp-output-path ./harmony/faster_image/src/main/cpp/generated --ets-output-path ./harmony/faster_image/src/main/ets/generated"},"_npmUser":{"name":"luyizouyuan","email":"189605613@qq.com"},"_resolved":"D:\\code\\rn\\npm\\batch\\faster_image\\bingtang-rn-faster-image-1.0.1.tgz","_integrity":"sha512-PTRXU3twmBrGhGR/k5UdU6gClzQj2zc9I2YjVGSXZv5dlFm0UTOrCw9fQM86agbhXyKBKkej+cqrhR2AMv48LQ==","repository":{"url":"https://gitcode.com/rn_ohos_plugin/faster_image","type":"git"},"_npmVersion":"11.12.1","description":"适配鸿蒙版本，提供faster_image组件。","directories":{},"_nodeVersion":"24.15.0","react-native":"./src/index.tsx","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.6.3","metro":"^0.81.0","react":"18.2.0","typescript":"5.0.4","@types/react":"18.2.79","react-native":"0.72.5","@react-native/typescript-config":"0.79.5","@react-native-oh/react-native-harmony-cli":"^0.77.50"},"peerDependencies":{"react-native":">=0.72"},"_npmOperationalInternal":{"tmp":"tmp/faster-image_1.0.1_1790566071568_0.2866559232269317","host":"s3://npm-registry-packages-npm-production"}},"1.0.2":{"_id":"@bingtang-rn/faster-image@1.0.2","dist":{"shasum":"ed307de6b7e597858defd2cbee4aa9ea2426f20e","tarball":"https://registry.npmjs.org/@bingtang-rn/faster-image/-/faster-image-1.0.2.tgz","fileCount":42,"integrity":"sha512-q0EKALZCWbKsbeu18xMPakrnt9iDxCDm24YTEfvCXUtpDFgfoNlgdbn/4KG5wBEdLCXqZL6rOKWQIxcSmq6hrw==","signatures":[{"sig":"MEQCIAdcdY15BZnbYNOToZIzisknAcKvrUgtNuyTUtGuaHDkAiAOb9UAGl/MPC9dEceJqTUZizLwUevOOJgxj673Y8/gvA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCYJXoXBwmXxPOcjRFvkINEkcE0+zdLlXvCfNN1+cuvGwIgFA0T5f/P20hMVTDgEesPfJjRDxYDVba9SbAYJ5fcXag="}],"unpackedSize":112324},"main":"./src/index.tsx","name":"@bingtang-rn/faster-image","_from":"file:bingtang-rn-faster-image-1.0.2.tgz","module":"./src/index.tsx","engines":{"node":">=18"},"harmony":{"alias":"@candlefinance/faster-image","autolinking":{"ohPackageName":"@bingtang-rn/faster-image","cppPackageClassName":"FasterImagePackage","etsPackageClassName":"FasterImagePackage","cmakeLibraryTargetName":"faster_image"},"codegenConfig":[{"version":1,"specPaths":["./src/specs/v1"]}]},"license":"MIT","private":false,"scripts":{"prepare":"echo skip","codegen-lib":"react-native codegen-harmony --cpp-output-path ./harmony/faster_image/src/main/cpp/generated --ets-output-path ./harmony/faster_image/src/main/ets/generated"},"version":"1.0.2","_npmUser":{"name":"luyizouyuan","email":"189605613@qq.com"},"homepage":"https://gitcode.com/rn_ohos_plugin/faster_image","keywords":["react-native","harmony","harmonyos","faster-image"],"_resolved":"D:\\code\\rn\\npm\\batch\\faster_image\\bingtang-rn-faster-image-1.0.2.tgz","_integrity":"sha512-q0EKALZCWbKsbeu18xMPakrnt9iDxCDm24YTEfvCXUtpDFgfoNlgdbn/4KG5wBEdLCXqZL6rOKWQIxcSmq6hrw==","repository":{"url":"https://gitcode.com/rn_ohos_plugin/faster_image","type":"git"},"_npmVersion":"11.12.1","description":"适配鸿蒙版本，提供faster_image组件。","directories":{},"maintainers":[{"name":"luyizouyuan","email":"189605613@qq.com"}],"_nodeVersion":"24.15.0","react-native":"./src/index.tsx","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.6.3","metro":"^0.81.0","react":"18.2.0","typescript":"5.0.4","@types/react":"18.2.79","react-native":"0.72.5","@react-native/typescript-config":"0.79.5","@react-native-oh/react-native-harmony-cli":"^0.77.50"},"peerDependencies":{"react-native":">=0.72"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/faster-image_1.0.2_1790567613684_0.8016459666696756"}}},"time":{"created":"2026-08-06T07:02:25.039Z","modified":"2026-09-28T03:53:33.916Z","1.0.0":"2026-08-06T07:02:25.396Z","1.0.1":"2026-09-28T03:27:51.658Z","1.0.2":"2026-09-28T03:53:33.770Z"},"license":"MIT","homepage":"https://gitcode.com/rn_ohos_plugin/faster_image","keywords":["react-native","harmony","harmonyos","faster-image"],"repository":{"url":"https://gitcode.com/rn_ohos_plugin/faster_image","type":"git"},"description":"适配鸿蒙版本，提供faster_image组件。","maintainers":[{"name":"luyizouyuan","email":"189605613@qq.com"}],"readme":"# @bingtang-rn/faster-image for HarmonyOS\r\n\r\n本项目基于 [@candlefinance/faster-image](https://github.com/candlefinance/faster-image) 开发，为 React Native 鸿蒙（OpenHarmony）适配版本。如果在使用过程中有任何问题，可以在GitCode提Issue，会及时跟进。issue地址：[issues](https://gitcode.com/rn_ohos_plugin/faster_image/issues)。\r\n\r\n## 版本对应关系\r\n\r\n| 鸿蒙适配包版本 | 原始库版本 | 支持 RN 版本 | Autolink | 编译 API 版本 |\r\n| ------------ | ---------- | ------------ | -------- | ------------- |\r\n| 见发布记录 | 1.7.2 | 0.72+ | 是 | API17+ |\r\n\r\n## 安装\r\n\r\n```bash\r\nnpm install @bingtang-rn/faster-image\r\n```\r\n\r\n## 使用\r\n\r\n```tsx\r\nimport { FasterImageView, clearCache, prefetch } from '@candlefinance/faster-image';\r\n\r\n// 渲染图片（支持灰度、圆角、缓存策略、blurhash 占位等）\r\nconst style = { width: 200, height: 200 };\r\nconst source = {\r\n  transitionDuration: 300,\r\n  cachePolicy: 'discWithCacheControl' as const,\r\n  showActivityIndicator: true,\r\n  grayscale: 1,\r\n  blurhash: 'LFE,@D9F01_4Sg#*0;1S_NIW9F',\r\n  url: 'https://picsum.photos/200/200?random=1',\r\n};\r\n\r\n<FasterImageView\r\n  onError={(e) => console.warn(e.nativeEvent.error)}\r\n  onSuccess={(e) => console.log(e.nativeEvent.width, e.nativeEvent.height)}\r\n  style={style}\r\n  source={source}\r\n/>\r\n\r\n// 清空缓存\r\nconst result = await clearCache();\r\n\r\n// 预取图片\r\nawait prefetch(['https://picsum.photos/200/200?random=0'], {\r\n  headers: { Authorization: 'Bearer token' },\r\n});\r\n```\r\n\r\n> import 时使用原库名 `'@candlefinance/faster-image'`，RNOH alias 自动映射到鸿蒙包 `@bingtang-rn/faster-image`。\r\n\r\n**平台差异**：\r\n- `transitionDuration`：原库 iOS 用秒、Android 用毫秒；鸿蒙端归一化为毫秒（< 1 视为秒 × 1000，默认 100ms）。\r\n- `contentPosition`：ArkUI 用 `ImageFit` 对齐变体定位，位置正确；图片小于容器时不放大填充（与原库 Android `Matrix.setRectToRect` 缩放行为略有差异）。\r\n- `priority`（iOS only）/ `progressiveLoadingEnabled`（iOS only）：原库 Android 端也无此特性，鸿蒙端降级为忽略 / 一次性解码，行为对齐 Android。\r\n\r\n**权限要求**：\r\n- 需在 `module.json5` 声明 `ohos.permission.INTERNET`（网络下载图片）。normal 权限安装时授予，无需运行时动态申请。\r\n- 磁盘缓存写入应用沙箱 `cacheDir` 目录，无需额外权限。\r\n\r\n## Link\r\n\r\n| 版本 | 是否支持 Autolink |\r\n|------|------------------|\r\n| 当前版本 | 是 |\r\n\r\n如使用版本支持 Autolink 且工程已接入，可跳过手动配置。\r\n\r\n<details>\r\n<summary>Manual Link 配置</summary>\r\n\r\n> **说明**：本模块需要同时在 C++ 侧和 ETS 侧注册 Package。\r\n\r\n### 1. Overrides RN SDK\r\n\r\n在工程根目录 `oh-package.json5` 添加：\r\n\r\n```json\r\n{\r\n  \"overrides\": {\r\n    \"@rnoh/react-native-openharmony\": \"./react_native_openharmony\"\r\n  }\r\n}\r\n```\r\n\r\n### 2. 引入原生端依赖\r\n\r\n打开 `entry/oh-package.json5`，添加：\r\n\r\n```json\r\n\"dependencies\": {\r\n  \"@bingtang-rn/faster-image\": \"file:../../node_modules/@bingtang-rn/faster-image/harmony/faster_image.har\"\r\n}\r\n```\r\n\r\n执行 `ohpm install`。\r\n\r\n### 3. 配置 CMakeLists\r\n\r\n打开 `entry/src/main/cpp/CMakeLists.txt`，添加：\r\n\r\n```cmake\r\nset(OH_MODULES \"${CMAKE_CURRENT_SOURCE_DIR}/../../../oh_modules\")\r\n\r\nadd_subdirectory(\"${OH_MODULES}/@bingtang-rn/faster-image/src/main/cpp\" ./faster_image)\r\n\r\ntarget_link_libraries(rnoh_app PUBLIC faster_image)\r\n```\r\n\r\n### 4. 注册 Package（C++ 侧）\r\n\r\n打开 `entry/src/main/cpp/PackageProvider.cpp`，添加：\r\n\r\n```cpp\r\n#include \"FasterImagePackage.h\"\r\n\r\nstd::vector<std::shared_ptr<Package>> PackageProvider::getPackages(Package::Context ctx) {\r\n    return {\r\n        std::make_shared<FasterImagePackage>(ctx),\r\n    };\r\n}\r\n```\r\n\r\n### 5. 注册 Package（ETS 侧）\r\n\r\n打开 `entry/src/main/ets/RNPackagesFactory.ets`，添加：\r\n\r\n```typescript\r\nimport { FasterImagePackage } from '@bingtang-rn/faster-image/ts';\r\n\r\nexport function createRNPackages(ctx: RNPackageContext): RNPackage[] {\r\n  return [\r\n    new FasterImagePackage(ctx),\r\n  ];\r\n}\r\n```\r\n\r\n</details>\r\n\r\n## 属性 / API\r\n\r\n| API | 描述 | 参数 | 返回值 | HarmonyOS 支持 |\r\n|-----|------|------|--------|----------------|\r\n| FasterImageView (source.url) | 图片 URL | string | — | ✅ 完全支持 |\r\n| FasterImageView (source.base64Placeholder) | Base64 占位图 | string | — | ✅ 完全支持 |\r\n| FasterImageView (source.blurhash) | Blurhash 占位图 | string | — | ✅ 完全支持 |\r\n| FasterImageView (source.thumbhash) | Thumbhash 占位图 | string | — | ✅ 完全支持 |\r\n| FasterImageView (source.resizeMode) | 缩放模式 | 'fill'\\|'contain'\\|'cover'\\|'center'\\|'top'\\|'bottom' | — | ✅ 完全支持 |\r\n| FasterImageView (source.contentPosition) | 内容定位 | 'top'\\|'bottom'\\|'left'\\|'right'\\|'topLeft'\\|'topRight'\\|'bottomLeft'\\|'bottomRight' | — | ⚠️ 部分支持（位置对齐正确，缩放行为与原库略有差异） |\r\n| FasterImageView (source.borderRadius) | 圆角 | number | — | ✅ 完全支持 |\r\n| FasterImageView (source.borderTopLeftRadius 等) | 四角独立圆角 | number | — | ✅ 完全支持 |\r\n| FasterImageView (source.grayscale) | 灰度滤镜 (0-1) | number | — | ✅ 完全支持 |\r\n| FasterImageView (source.colorMatrix) | 颜色矩阵 (4×5) | number[][] | — | ✅ 完全支持 |\r\n| FasterImageView (source.cachePolicy) | 缓存策略 | 'memory'\\|'discWithCacheControl'\\|'discNoCacheControl'\\|'memoryAndDisc' | — | ✅ 完全支持 |\r\n| FasterImageView (source.transitionDuration) | 淡入动画时长 | number | — | ✅ 完全支持 |\r\n| FasterImageView (source.failureImage) | 失败图 | string | — | ✅ 完全支持 |\r\n| FasterImageView (source.showActivityIndicator) | 加载指示器 | boolean | — | ✅ 完全支持 |\r\n| FasterImageView (source.activityColor) | 指示器颜色 | ColorValue | — | ✅ 完全支持 |\r\n| FasterImageView (source.headers) | 请求头 | Record\\<string,string\\> | — | ✅ 完全支持 |\r\n| FasterImageView (source.allowHardware) | 硬件渲染 | boolean | — | ✅ 完全支持 |\r\n| FasterImageView (source.ignoreQueryParamsForCacheKey) | 忽略 query 参数 | boolean | — | ✅ 完全支持 |\r\n| FasterImageView (source.priority) | 加载优先级 | 'veryLow'\\|'low'\\|'normal'\\|'high'\\|'veryHigh' | — | ⚠️ 部分支持（降级为忽略，对齐 Android） |\r\n| FasterImageView (source.progressiveLoadingEnabled) | 渐进式加载 | boolean | — | ⚠️ 部分支持（降级为一次性解码，对齐 Android） |\r\n| FasterImageView (onSuccess) | 加载成功回调 | — | { width, height, source } | ✅ 完全支持 |\r\n| FasterImageView (onError) | 加载失败回调 | — | { error } | ✅ 完全支持 |\r\n| clearCache | 清空缓存 | — | Promise\\<boolean\\> | ✅ 完全支持 |\r\n| prefetch | 预取图片 | sources: string[], options?: { headers? } | Promise\\<void\\> | ✅ 完全支持 |\r\n\r\n### 平台差异\r\n- `transitionDuration` 单位归一化：iOS 用秒（如 0.3），Android 用毫秒（如 300）；鸿蒙端统一为毫秒（< 1 视为秒 × 1000，默认 100ms）。\r\n- `contentPosition` 缩放：原库 Android 用 `Matrix.setRectToRect` 缩放后定位；鸿蒙端用 `ImageFit.TOP_START` 等对齐变体以原始尺寸定位，图片小于容器时不放大填充。位置语义正确，缩放行为略有差异。\r\n- `colorMatrix` 展平：公开 API 为 `number[][]`（4×5），JS wrapper 展平为 `number[20]` 传入 ArkUI `ColorFilter`。\r\n\r\n### 未实现功能\r\n| API | 原因 |\r\n|-----|------|\r\n| source.priority | iOS only 特性，原库 Android 无此能力，鸿蒙 `@ohos.net.http` 无内置请求优先级枚举，降级为忽略 |\r\n| source.progressiveLoadingEnabled | iOS only 特性，原库 Android 无此能力，鸿蒙 `@ohos.multimedia.image` 增量解码与 Nuke 渐进式渲染不等价，降级为一次性解码 |\r\n| source.accessible / accessibilityLabel | 原库仅类型声明，无原生实现 |\r\n\r\n### 使用限制\r\n- `cachePolicy: 'discWithCacheControl'` 的 Cache-Control 过期判断：鸿蒙端简化为命中即用（与 Android Coil `CachePolicy.ENABLED` 行为一致），不解析 HTTP 过期头。\r\n\r\n## 快速验证（运行 Example）\r\n\r\n### 前置条件\r\n\r\n| 依赖 | 版本要求 |\r\n|------|----------|\r\n| Node.js | >= 18 |\r\n| DevEco Studio | 5.0+ / 6.0+ |\r\n| HarmonyOS SDK | API 17+ |\r\n\r\n### 运行步骤\r\n\r\n**1. 克隆仓库**\r\n\r\n```bash\r\ngit clone <仓库地址>\r\ncd <仓库目录>\r\n```\r\n\r\n**2. 安装依赖并构建**\r\n\r\n```bash\r\nnpm install --legacy-peer-deps\r\nnpm pack           # 生成 tgz 包（会自动触发 prepare 构建 JS 产物）\r\n```\r\n\r\n**3. 进入 example 目录，安装依赖**\r\n\r\n```bash\r\ncd example\r\nnpm install --legacy-peer-deps\r\n```\r\n\r\n**4. 生成 JS Bundle**\r\n\r\n```bash\r\nnpm run dev\r\n```\r\n\r\n产物：`harmony/entry/src/main/resources/rawfile/bundle.harmony.js`\r\n\r\n**5. 用 DevEco Studio 打开鸿蒙工程**\r\n\r\n- 打开 DevEco Studio\r\n- 选择 `example/harmony` 目录\r\n- 等待 Sync 完成\r\n\r\n**6. 编译并运行 HAP**\r\n\r\n在 DevEco Studio 中点击运行按钮，将 HAP 安装到设备/模拟器。\r\n\r\n> **注意**：Example 中已预置插件依赖和 Package 注册，无需手动配置 Link。\r\n\r\n## 约束与限制\r\n\r\n### 兼容性\r\n\r\n- RNOH: 0.72+\r\n- HarmonyOS SDK: API 17+\r\n- DevEco Studio: 5.0+\r\n\r\n## 遗留问题\r\n\r\n无（或列出已知问题）\r\n\r\n## 开源协议\r\n\r\n本项目基于 [MIT 协议](https://github.com/candlefinance/faster-image/blob/main/LICENSE)，详见 [LICENSE](./LICENSE) 文件。\r\n","readmeFilename":"README.md"}