当前仓库属于关闭状态,部分功能使用受限,详情请查阅 仓库状态说明
27 Star 232 Fork 144

OpenHarmony-TPC/ImageKnife
关闭

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README
Apache-2.0

🚨 重要提示 | IMPORTANT

⚠️ 此代码仓已归档。新地址请访问 ImageKnife。| ⚠️ This repository has been archived. For the new address, please visit ImageKnife.


ImageKnife

专门为OpenHarmony打造的一款图像加载缓存库,致力于更高效、更轻便、更简单。

简介

本项目参考开源库 Glide 进行OpenHarmony的自研版本:

  • 支持自定义内存缓存策略,支持设置内存缓存的大小(默认LRU策略)。
  • 支持磁盘二级缓存,对于下载图片会保存一份至磁盘当中。
  • 支持自定义实现图片获取/网络下载
  • 支持监听网络下载回调进度
  • 继承Image的能力,支持option传入border,设置边框,圆角
  • 继承Image的能力,支持option传入objectFit设置图片缩放,包括objectFit为auto时根据图片自适应高度
  • 支持通过设置transform缩放图片
  • 并发请求数量,支持请求排队队列的优先级
  • 支持生命周期已销毁的图片,不再发起请求
  • 自定义缓存key
  • 自定义http网络请求头
  • 支持writeCacheStrategy控制缓存的存入策略(只存入内存或文件缓存)
  • 支持preLoadCache预加载图片
  • 支持onlyRetrieveFromCache仅用缓存加载
  • 支持使用一个或多个图片变换,如模糊,高亮等

待实现特性

  • 内存降采样优化,节约内存的占用
  • 支持自定义图片解码

注意:3.x版本相对2.x版本做了重大的重构,主要体现在:

  • 使用Image组件代替Canvas组件渲染
  • 重构Dispatch分发逻辑,支持控制并发请求数,支持请求排队队列的优先级
  • 支持通过initMemoryCache自定义策略内存缓存策略和大小
  • 支持option自定义实现图片获取/网络下载

因此API及能力上,目前有部分差异,主要体现在:

  • 不支持drawLifeCycle接口,通过canvas自会图片
  • mainScaleType,border等参数,新版本与系统Image保持一致
  • gif/webp动图播放与控制(ImageAnimator实现)
  • 抗锯齿相关参数

下载安装

ohpm install @ohos/imageknife

// 如果需要用文件缓存,需要提前初始化文件缓存
await ImageKnife.getInstance().initFileCache(context, 256, 256 * 1024 * 1024)

使用说明

1.显示本地资源图片

ImageKnifeComponent({
  ImageKnifeOption: {
    loadSrc: $r("app.media.app_icon"),
    placeholderSrc: $r("app.media.loading"),
    errorholderSrc: $r("app.media.app_icon"),
    objectFit: ImageFit.Auto
  }
}).width(100).height(100)

2.显示本地context files下文件

ImageKnifeComponent({
  ImageKnifeOption: {
    loadSrc: this.localFile,
    placeholderSrc: $r("app.media.loading"),
    errorholderSrc: $r("app.media.app_icon"),
    objectFit: ImageFit.Auto
  }
}).width(100).height(100)

3.显示网络图片

ImageKnifeComponent({
  ImageKnifeOption: {
    loadSrc:"https://www.openharmony.cn/_nuxt/img/logo.dcf95b3.png",
    placeholderSrc: $r("app.media.loading"),
    errorholderSrc: $r("app.media.app_icon"),
    objectFit: ImageFit.Auto
  }
}).width(100).height(100)

4.自定义下载图片

ImageKnifeComponent({
  ImageKnifeOption: {
    loadSrc: "https://file.atomgit.com/uploads/user/1704857786989_8994.jpeg",
    placeholderSrc: $r("app.media.loading"),
    errorholderSrc: $r("app.media.app_icon"),
    objectFit: ImageFit.Auto,
    customGetImage: custom
 }
}).width(100).height(100)

// 自定义实现图片获取方法,如自定义网络下载
@Concurrent
async function custom(context: Context, src: string | PixelMap | Resource): Promise<ArrayBuffer | undefined> {
  console.info("ImageKnife::  custom download:" + src)
  // 举例写死从本地文件读取,也可以自己请求网络图片
  return context.resourceManager.getMediaContentSync($r("app.media.bb").id).buffer as ArrayBuffer
}

5.监听网络下载进度

ImageKnifeComponent({
  ImageKnifeOption: {
    loadSrc:"https://www.openharmony.cn/_nuxt/img/logo.dcf95b3.png",
    progressListener:(progress:number)=>{console.info("ImageKinfe:: call back progress = " + progress)}
  }
}).width(100).height(100)

6.支持option传入border,设置边框,圆角

ImageKnifeComponent({ ImageKnifeOption: 
{
   loadSrc: $r("app.media.rabbit"),
   border: {radius:50}
  }
}).width(100).height(100)

7.支持option图片变换

ImageKnifeComponent({ ImageKnifeOption: 
{
   loadSrc: $r("app.media.rabbit"),
   border: {radius:50},
   transformation: new BlurTransformation(3)
  }
}).width(100).height(100)

多种组合变换用法

let transformations: collections.Array<PixelMapTransformation> = new collections.Array<PixelMapTransformation>();
transformations.push(new BlurTransformation(5));
transformations.push(new BrightnessTransformation(0.2));
ImageKnifeComponent({
  imageKnifeOption: {
  loadSrc: $r('app.media.pngSample'),
  placeholderSrc: $r("app.media.loading"),
  errorholderSrc: $r("app.media.app_icon"),
  objectFit: ImageFit.Contain,
  border: { radius: { topLeft: 50, bottomRight: 50 } }, // 圆角设置
  transformation: transformations.length > 0 ? new MultiTransTransformation(transformations) : undefined // 图形变换组
}
}).width(300)
  .height(300)
  .rotate({ angle: 90 }) // 旋转90度
  .contrast(12) // 对比度滤波器

其它变换相关属性,可叠加实现组合变换效果

圆形裁剪变换示例

ImageKnifeComponent({ ImageKnifeOption: 
  {
  loadSrc: $r('app.media.pngSample'),
  objectFit: ImageFit.Cover,
  border: { radius: 150 }
}
}).width(300)
  .height(300)

圆形裁剪带边框变换示例

ImageKnifeComponent({ ImageKnifeOption: 
  {
  loadSrc: $r('app.media.pngSample'),
  objectFit: ImageFit.Cover,
  border: { radius: 150, color: Color.Red, width: 5 }
}
}).width(300)
  .height(300)

对比度滤波变换示例

ImageKnifeComponent({
  imageKnifeOption: {
    loadSrc: $r('app.media.pngSample')
  }
}).width(300)
  .height(300)
  .contrast(12)

旋转变换示例

ImageKnifeComponent({
  imageKnifeOption:  {
    loadSrc: $r('app.media.pngSample')
  }
}).width(300)
  .height(300)
  .rotate({angle:90})
  .backgroundColor(Color.Pink)

8.监听图片加载成功与失败

ImageKnifeComponent({ ImageKnifeOption: 
{
   loadSrc: $r("app.media.rabbit"),
   onLoadListener:{
    onLoadStart:()=>{
     this.starTime = new Date().getTime()
     console.info("Load start: ");
    },
    onLoadFailed: (err) => {
     console.error("Load Failed Reason: " + err + "  cost " + (new Date().getTime() - this.starTime) + " milliseconds");
    },
    onLoadSuccess: (data, imageData) => {
     console.info("Load Successful: cost " + (new Date().getTime() - this.starTime) + " milliseconds");
     return data;
    },
    onLoadCancel(err){
      console.info(err)
    }
   }
 }
}).width(100).height(100)

9.ImageKnifeComponent - syncLoad

设置是否同步加载图片,默认是异步加载。建议加载尺寸较小的Resource图片时将syncLoad设为true,因为耗时较短,在主线程上执行即可

ImageKnifeComponent({
        imageKnifeOption:{
          loadSrc:$r("app.media.pngSample"),
          placeholderSrc:$r("app.media.loading")
        },syncLoad:true
      })

10.ImageKnifeAnimatorComponent 示例

ImageKnifeAnimatorComponent({
        imageKnifeOption: {
          loadSrc:"https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658",
          placeholderSrc:$r('app.media.loading'),
          errorholderSrc:$r('app.media.failed')
        },animatorOption:this.animatorOption
      }).width(300).height(300).backgroundColor(Color.Orange).margin({top:30})

11.加载图片回调信息数据 示例

ImageKnifeComponent({ ImageKnifeOption: = {
                loadSrc: $r('app.media.pngSample'),
                objectFit: ImageFit.Contain,
                onLoadListener: {
                  onLoadStart: (req) => {
                    let startCallBackData = JSON.stringify(req?.imageKnifeData);
                  },
                  onLoadFailed: (res, req) => {
                    let failedBackData = res + ";" + JSON.stringify(req?.imageKnifeData);
                  },
                  onLoadSuccess: (data, imageData, req) => {
                    let successBackData = JSON.stringify(req?.imageKnifeData);
                  },
                  onLoadCancel: (res, req) => {
                    let cancelBackData = res + ";" + JSON.stringify(req?.imageKnifeData);
                  }
                },
                border: { radius: 50 },
                onComplete: (event) => {
                  if (event && event.loadingStatus == 0) {
                    let render_success = JSON.stringify(Date.now())
                  }
                }
              }
}).width(100).height(100)

12.图片降采样 示例

ImageKnifeComponent({
        imageKnifeOption:{
          loadSrc:$r("app.media.pngSample"),
          placeholderSrc:$r('app.media.loading'),
          errorholderSrc:$r('app.media.failed'),
          downsampleOf: DownsampleStrategy.NONE
        }
      }).width(300).height(300)

13.rcp自定义网络请求

ImageKnifeComponent({
    loadSrc:"http//xx.xx",
    customGetImage:custom
})
// 自定义下载方法
@Concurrent
async function custom(context: Context, src: string | PixelMap | Resource,headers?: Record<string,Object>): Promise<ArrayBuffer | undefined> {
  return new Promise((resolve,reject)=>{
    if (typeof src == "string") {
      let session = GetSession.session
      let req = new rcp.Request(src,"GET");
      session.fetch(req).then((response)=>{
        if(response.statusCode == 200) {
          let buffer = response.body
          resolve(buffer)
        } else {
          reject("rcp code:"+response.statusCode)
        }
      }).catch((err:BusinessError)=>{
        reject("error rcp src:"+src+",err:"+JSON.stringify(err))
      })
    }
  })
}

复用场景

在aboutToRecycle生命周期清空组件内容;通过watch监听触发图片的加载。

接口说明

ImageKnife组件

组件名称 入参内容 功能简介
ImageKnifeComponent ImageKnifeOption 图片显示组件
ImageKnifeAnimatorComponent ImageKnifeOption、AnimatorOption 动图控制组件

AnimatorOption参数列表

参数名称 入参内容 功能简介
state AnimationStatus 播放状态(可选)
iterations number 播放次数(可选)
reverse boolean 播放顺序(可选)
onStart ()=>void 动画开始播放时触发(可选)
onFinish ()=>void 动画播放完成时或者停止播放时触发(可选)
onPause ()=>void 动画暂停播放时触发(可选)
onCancel ()=>void 动画返回最初状态时触发(可选)
onRepeat ()=>void 动画重复播放时触发(可选)

ImageKnifeOption参数列表

参数名称 入参内容 功能简介
loadSrc string、PixelMap、Resource 主图展示
placeholderSrc PixelMap、Resource 占位图图展示(可选)
errorholderSrc PixelMap、Resource 错误图展示(可选)
objectFit ImageFit 主图填充效果(可选)
placeholderObjectFit ImageFit 占位图填充效果(可选)
errorholderObjectFit ImageFit 错误图填充效果(可选)
writeCacheStrategy CacheStrategyType 写入缓存策略(可选)
onlyRetrieveFromCache boolean 是否跳过网络和本地请求(可选)
customGetImage customGetImage?:(context: Context, src: string、PixelMap、Resource ,headers?: Record<string, Object>) => Promise<ArrayBuffer、undefined> 自定义下载图片(可选)
border BorderOptions 边框圆角(可选)
priority taskpool.Priority 加载优先级(可选)
context common.UIAbilityContext 上下文(可选)
progressListener (progress: number)=>void 进度(可选)
signature String 自定义缓存关键字(可选)
headerOption Array 设置请求头(可选)
transformation PixelMapTransformation 图片变换(可选)
drawingColorFilter ColorFilter、drawing.ColorFilter 颜色滤镜效果(可选)
onComplete (event:EventImage、undefined) => void 图片成功回调事件(可选)
onLoadListener onLoadStart?: (req?: ImageKnifeRequest) => void,onLoadSuccess?: (data: string | PixelMap | undefined, imageData: ImageKnifeData, req?: ImageKnifeRequest) => void,onLoadFailed?: (err: string, req?: ImageKnifeRequest) => void,onLoadCancel?: (res: string, req?: ImageKnifeRequest) => void 监听图片加载成功与失败
downsampleOf DownsampleStrategy 降采样(可选)
httpOption HttpRequestOption 网络请求配置(可选)

降采样类型

类型 相关描述
NONE 不进行降采样
AT_MOST 请求尺寸大于实际尺寸不进行放大
FIT_CENTER_MEMORY 两边自适应内存优先
FIT_CENTER_QUALITY 两边自适应质量优先
CENTER_INSIDE_MEMORY 宽高缩放比最大的比例,进行缩放适配内存优先
CENTER_INSIDE_QUALITY 宽高缩放比最大的比例,进行缩放适配质量优先
AT_LEAST 根据宽高的最小的比例,进行适配

ImageKnife接口

参数名称 入参内容 功能简介
initMemoryCache newMemoryCache: IMemoryCache 自定义内存缓存策略
initFileCache context: Context, size: number, memory: number 初始化文件缓存数量和大小
reload request: ImageKnifeRequest 图片重新加载
preLoad loadSrc: string I ImageKnifeOption 预加载返回图片请求request
cancel request: ImageKnifeRequest 取消图片请求
preLoadCache loadSrc: string I ImageKnifeOption 预加载并返回文件缓存路径
getCacheImage loadSrc: string, cacheType: CacheStrategy = CacheStrategy.Default, signature?: string) 从内存或文件缓存中获取资源
addHeader key: string, value: Object 全局添加http请求头
setHeaderOptions Array 全局设置http请求头
deleteHeader key: string 全局删除http请求头
setCustomGetImage customGetImage?: (context: Context, src: string、PixelMap、Resource ,headers?: Record<string, Object>) => Promise<ArrayBuffer、undefined> 全局设置自定义下载
setEngineKeyImpl IEngineKey 全局配置缓存key生成策略
putCacheImage url: string, pixelMap: PixelMap, cacheType: CacheStrategy = CacheStrategy.Default, signature?: string 写入内存磁盘缓存
removeMemoryCache url: string、ImageKnifeOption 清理指定内存缓存
removeFileCache url: string、ImageKnifeOption 清理指定磁盘缓存
getCacheLimitSize cacheType?: CacheStrategy 获取指定缓存的上限大小
getCurrentCacheNum cacheType?: CacheStrategy 获取指定缓存的当前缓存图片个数
getCurrentCacheSize cacheType?: CacheStrategy 获取指定缓存的当前大小
getCurrentCacheSize cacheType?: CacheStrategy 获取指定缓存的当前大小

回调接口说明

回调接口 回调字段 回调描述
onLoadStart req: ImageKnifeRequest req返回字段中包含了图片请求的信息,如图片的url及其组件的宽高,同时ImageKnifeRequest包含了ImageKnifeData,其中包含此次请求的开始及其检查内存缓存的时间点
onLoadSuccess data: string、PixelMap、undefined, imageData: ImageKnifeData, req?: ImageKnifeRequest data:加载成功的结果数据;imageData:图片的存入缓存中的信息 ,req:图片请求的信息,同时其中的ImageKnifeData,包含此次请求中图片的原始大小、图片的解码大小、格式、图片帧、请求结束时间、磁盘检查时间、网络请求开始结束、图片解码开始结束等时间点
onLoadFailed err: string, req?: ImageKnifeRequest err:错误信息描述;req:图片请求的信息,同时其中的ImageKnifeData,包含此次请求错误信息(ErrorInfo,TimeInfo),ErrorInfo其中包含了,错误阶段、错误码及其网络请求的错误码;TimeInfo中包含请求结束时间、磁盘检查时间、网络请求开始结束、图片解码开始结束等时间点
onLoadCancel reason: string, req?: ImageKnifeRequest reason:取消回调原因;req:图片请求的信息,同时其中的ImageKnifeData,包含此次请求错误信息(ErrorInfo,TimeInfo),ErrorInfo其中包含了,错误阶段、错误码及其网络请求的错误码;TimeInfo中包含请求结束时间、磁盘检查时间、网络请求开始结束、图片解码开始结束及其请求取消等时间点

图形变换类型(需要为GPUImage添加依赖项)

类型 相关描述
BlurTransformation 模糊处理
BrightnessTransformation 亮度滤波器
CropSquareTransformation 正方形剪裁
CropTransformation 自定义矩形剪裁
GrayScaleTransformation 灰度级滤波器
InvertTransformation 反转滤波器
KuwaharaTransformation 桑原滤波器(使用GPUIImage)
MaskTransformation 遮罩
PixelationTransformation 像素化滤波器(使用GPUIImage)
SepiaTransformation 乌墨色滤波器(使用GPUIImage)
SketchTransformation 素描滤波器(使用GPUIImage)
SwirlTransformation 扭曲滤波器(使用GPUIImage)
ToonTransformation 动画滤波器(使用GPUIImage)
VignetterTransformation 装饰滤波器(使用GPUIImage)

下载安装GPUImage依赖

方法一:在Terminal窗口中,执行如下命令安装三方包,DevEco Studio会自动在工程的oh-package.json5中自动添加三方包依赖。

    ohpm install @ohos/gpu_transform

方法二: 在工程的oh-package.json5中设置三方包依赖,配置示例如下:

    "dependencies": {
      "@ohos/gpu_transform": "^1.0.2"
    }

约束与限制

在下述版本验证通过:
DevEco Studio: NEXT Beta1-5.0.3.806, SDK: API12 Release(5.0.0.66)

关于混淆

  • 代码混淆,请查看代码混淆简介
  • 如果希望imageknife库在代码混淆过程中不会被混淆,需要在混淆规则配置文件obfuscation-rules.txt中添加相应的排除规则:
-keep
./oh_modules/@ohos/imageknife

贡献代码

使用过程中发现任何问题都可以提 issue ,当然,也非常欢迎发 PR 共建。

开源协议

本项目基于 Apache License 2.0 ,请自由的享受和参与开源。

遗留问题

  • ImageKnifeAnimator组件无法设置ImageFit属性

空文件

简介

专门为OpenHarmony打造的一款图像加载缓存库,致力于更高效、更轻便、更简单 展开 收起
README
Apache-2.0
取消

发行版 (75)

全部
3个月前

贡献者

全部

近期动态

不能加载更多了
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/openharmony-tpc/ImageKnife.git
git@gitee.com:openharmony-tpc/ImageKnife.git
openharmony-tpc
ImageKnife
ImageKnife
master

搜索帮助