Pre Merge pull request !306 from zgf/3.x
This commit is contained in:
commit
7ffeb53721
|
@ -1,3 +1,8 @@
|
|||
## 3.0.0-rc.8
|
||||
- svg解码单位改为px
|
||||
- 修复预加载接口preLoadCache传ImageKnifeOption失效
|
||||
- 新增改变文件缓存目录接口reCacheFolder和设置文件缓存最大数接口reSize
|
||||
|
||||
## 3.0.0-rc.7
|
||||
- 修复成功回调获取不到宽高
|
||||
- 新增svg图片解码
|
||||
|
|
|
@ -310,6 +310,13 @@ ImageKnifeComponent({
|
|||
| ToonTransformation | 动画滤波器(使用GPUIImage) |
|
||||
| VignetterTransformation | 装饰滤波器(使用GPUIImage) |
|
||||
|
||||
### 文件缓存FileCache接口
|
||||
|
||||
| 参数名称 | 入参内容 | 功能简介 |
|
||||
|--------------|---------------------------------------------|------------------|
|
||||
| reFileFolder | path: string | 切换文件缓存目录(不存在则创建) |
|
||||
| reSize | size: number | 设置最大缓存数 |
|
||||
|
||||
## 下载安装GPUImage依赖
|
||||
方法一:在Terminal窗口中,执行如下命令安装三方包,DevEco Studio会自动在工程的oh-package.json5中自动添加三方包依赖。
|
||||
```
|
||||
|
|
|
@ -74,6 +74,11 @@ struct Index {
|
|||
|
||||
});
|
||||
})
|
||||
Button('测试切换文件缓存目录').margin({top:10}).onClick(()=>{
|
||||
router.push({
|
||||
uri: 'pages/TestReCacheFolderPage',
|
||||
});
|
||||
})
|
||||
Button("预加载图片到文件缓存").margin({top:10}).onClick(()=>{
|
||||
router.push({
|
||||
uri: 'pages/TestPrefetchToFileCache',
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { ImageKnifeComponent,ImageKnife,ImageKnifeOption } from '@ohos/libraryimageknife'
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
struct TestReCacheFolderPage {
|
||||
@State imageKnifeOption: ImageKnifeOption = {
|
||||
loadSrc:$r('app.media.startIcon'),
|
||||
placeholderSrc:$r('app.media.loading'),
|
||||
errorholderSrc:$r('app.media.failed')
|
||||
}
|
||||
@State message: string = ""
|
||||
private bol: boolean = true
|
||||
private url: string = 'https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp'
|
||||
build() {
|
||||
Column() {
|
||||
Button("切换缓存目录").margin({top:10}).onClick(async ()=>{
|
||||
ImageKnife.getInstance()
|
||||
.removeMemoryCache(this.url)
|
||||
this.bol = !this.bol
|
||||
ImageKnife.getInstance().getFileCache().reCacheFolder(this.bol ? "ImageKnife" : "ZFileCache")
|
||||
})
|
||||
Button("预加载并返回文件缓存路径").margin({top:10}).onClick(()=>{
|
||||
ImageKnife.getInstance().preLoadCache(this.url)
|
||||
.then((data)=>{
|
||||
this.imageKnifeOption.loadSrc = data
|
||||
this.message = data
|
||||
})
|
||||
})
|
||||
ImageKnifeComponent({
|
||||
imageKnifeOption: this.imageKnifeOption
|
||||
}).width(300).height(300).margin({top:30})
|
||||
Text(this.message)
|
||||
}
|
||||
.height('100%') .width('100%')
|
||||
}
|
||||
}
|
|
@ -18,6 +18,7 @@
|
|||
"pages/LoadStatePage",
|
||||
"pages/TestHspPreLoadImage",
|
||||
"pages/TestRemoveCache",
|
||||
"pages/dataShareUriLoadPage"
|
||||
"pages/dataShareUriLoadPage",
|
||||
"pages/TestReCacheFolderPage"
|
||||
]
|
||||
}
|
|
@ -149,6 +149,31 @@ export default function FileLruCacheTest() {
|
|||
fileCache.put(JSON.stringify("xxxxx"),buf)
|
||||
expect(fileCache.get(JSON.stringify("xxxxx"))?.byteLength).assertEqual(1024 * 1024)
|
||||
});
|
||||
it('testReSize', 0, async () => {
|
||||
const buf1: ArrayBuffer = new ArrayBuffer(1 * 1024 * 1024);
|
||||
const buf2: ArrayBuffer = new ArrayBuffer(2 * 1024 * 1024);
|
||||
const buf3: ArrayBuffer = new ArrayBuffer(3 * 1024 * 1024);
|
||||
const buf4: ArrayBuffer = new ArrayBuffer(4 * 1024 * 1024);
|
||||
|
||||
let fileCache: FileCache = new FileCache(GlobalContext.getContext()
|
||||
.getObject("context") as Context, 5, 20 * 1024 * 1024)
|
||||
await fileCache.initFileCache()
|
||||
|
||||
console.info(Constants.TAG + JSON.stringify("xxxxx"))
|
||||
fileCache.put("aaa",buf1)
|
||||
fileCache.put("bbb",buf2)
|
||||
fileCache.put("ccc",buf3)
|
||||
fileCache.put("ddd",buf4)
|
||||
expect(fileCache.get("aaa")?.byteLength).assertEqual(1 * 1024 * 1024)
|
||||
expect(fileCache.get("bbb")?.byteLength).assertEqual(2 * 1024 * 1024)
|
||||
expect(fileCache.get("ccc")?.byteLength).assertEqual(3 * 1024 * 1024)
|
||||
expect(fileCache.get("ddd")?.byteLength).assertEqual(4 * 1024 * 1024)
|
||||
fileCache.reSize(3)
|
||||
expect(fileCache.get("aaa")?.byteLength).assertEqual(undefined)
|
||||
expect(fileCache.get("bbb")?.byteLength).assertEqual(2 * 1024 * 1024)
|
||||
expect(fileCache.get("ccc")?.byteLength).assertEqual(3 * 1024 * 1024)
|
||||
expect(fileCache.get("ddd")?.byteLength).assertEqual(4 * 1024 * 1024)
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
"main": "index.ets",
|
||||
"repository": "https://gitee.com/openharmony-tpc/ImageKnife",
|
||||
"type": "module",
|
||||
"version": "3.0.0-rc.7",
|
||||
"version": "3.0.0-rc.8",
|
||||
"dependencies": {
|
||||
"@ohos/gpu_transform": "^1.0.2"
|
||||
},
|
||||
|
|
|
@ -166,10 +166,10 @@ export class ImageKnife {
|
|||
preLoadCache(loadSrc: string | ImageKnifeOption): Promise<string> {
|
||||
return new Promise((resolve, reject) => {
|
||||
let imageKnifeOption = new ImageKnifeOption()
|
||||
if (loadSrc instanceof ImageKnifeOption) {
|
||||
imageKnifeOption = loadSrc
|
||||
if (typeof loadSrc == "string") {
|
||||
imageKnifeOption.loadSrc = loadSrc
|
||||
} else {
|
||||
imageKnifeOption.loadSrc = loadSrc;
|
||||
imageKnifeOption = loadSrc;
|
||||
}
|
||||
LogUtil.log("ImageKnife_DataTime_preLoadCache-imageKnifeOption:"+loadSrc)
|
||||
let fileKey = this.getEngineKeyImpl().generateFileKey(imageKnifeOption.loadSrc, imageKnifeOption.signature)
|
||||
|
|
|
@ -171,7 +171,8 @@ export class ImageKnifeDispatcher {
|
|||
signature: currentRequest.imageKnifeOption.signature,
|
||||
requestSource: requestSource,
|
||||
isWatchProgress: isWatchProgress,
|
||||
memoryKey: memoryKey
|
||||
memoryKey: memoryKey,
|
||||
fileCacheFolder: ImageKnife.getInstance().getFileCache().getCacheFolder()
|
||||
}
|
||||
|
||||
|
||||
|
@ -373,7 +374,7 @@ async function requestJob(request: RequestJobRequest, requestList?: List<ImageKn
|
|||
// 判断自定义下载
|
||||
if (request.customGetImage !== undefined && typeof request.src === 'string' && (request.src.indexOf("http://") == 0 || request.src.indexOf("https://") == 0)) {
|
||||
// 先从文件缓存获取
|
||||
resBuf = FileCache.getFileCacheByFile(request.context, fileKey)
|
||||
resBuf = FileCache.getFileCacheByFile(request.context, fileKey , request.fileCacheFolder)
|
||||
if (resBuf === undefined) {
|
||||
LogUtil.log("customGetImage customGetImage");
|
||||
resBuf = await request.customGetImage(request.context, request.src)
|
||||
|
@ -381,7 +382,7 @@ async function requestJob(request: RequestJobRequest, requestList?: List<ImageKn
|
|||
if (resBuf !== undefined && request.writeCacheStrategy !== CacheStrategy.Memory) {
|
||||
let copyBuf = buffer.concat([buffer.from(resBuf)]).buffer; // IDE有bug,不能直接获取resBuf.byteLength
|
||||
bufferSize = copyBuf.byteLength
|
||||
FileCache.saveFileCacheOnlyFile(request.context, fileKey, resBuf)
|
||||
FileCache.saveFileCacheOnlyFile(request.context, fileKey, resBuf , request.fileCacheFolder)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -389,7 +390,7 @@ async function requestJob(request: RequestJobRequest, requestList?: List<ImageKn
|
|||
if (typeof request.src === 'string') {
|
||||
if (request.src.indexOf("http://") == 0 || request.src.indexOf("https://") == 0) { //从网络下载
|
||||
// 先从文件缓存获取
|
||||
resBuf = FileCache.getFileCacheByFile(request.context, fileKey)
|
||||
resBuf = FileCache.getFileCacheByFile(request.context, fileKey, request.fileCacheFolder)
|
||||
if (resBuf === undefined && request.onlyRetrieveFromCache != true) {
|
||||
LogUtil.log("ImageKnife_DataTime_requestJob_httpRequest.start:"+request.src)
|
||||
let httpRequest = http.createHttp();
|
||||
|
@ -454,7 +455,7 @@ async function requestJob(request: RequestJobRequest, requestList?: List<ImageKn
|
|||
LogUtil.log("ImageKnife_DataTime_requestJob_saveFileCacheOnlyFile.start:"+request.src)
|
||||
let copyBuf = combineArrayBuffers(arrayBuffers); // IDE有bug,不能直接获取resBuf.byteLength
|
||||
bufferSize = copyBuf.byteLength
|
||||
FileCache.saveFileCacheOnlyFile(request.context, fileKey, resBuf)
|
||||
FileCache.saveFileCacheOnlyFile(request.context, fileKey, resBuf, request.fileCacheFolder)
|
||||
LogUtil.log("ImageKnife_DataTime_requestJob_saveFileCacheOnlyFile.end:"+request.src)
|
||||
}
|
||||
}
|
||||
|
@ -545,8 +546,8 @@ async function requestJob(request: RequestJobRequest, requestList?: List<ImageKn
|
|||
let hValue = Math.round(request.componentHeight);
|
||||
let wValue = Math.round(request.componentWidth);
|
||||
let defaultSize: image.Size = {
|
||||
height: hValue,
|
||||
width: wValue
|
||||
height: vp2px(hValue),
|
||||
width: vp2px(wValue)
|
||||
};
|
||||
let opts: image.DecodingOptions = {
|
||||
editable: true,
|
||||
|
|
|
@ -82,5 +82,6 @@ export interface RequestJobRequest {
|
|||
engineKey: IEngineKey
|
||||
isWatchProgress: boolean
|
||||
memoryKey: string
|
||||
fileCacheFolder: string
|
||||
}
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ import { SparkMD5 } from '../3rd_party/sparkmd5/spark-md5';
|
|||
* 子线程直接读写文件
|
||||
*/
|
||||
export class FileCache {
|
||||
static readonly CACHE_FOLDER: string = "ImageKnife" // context cacheDir 的缓存文件目录
|
||||
static CACHE_FOLDER: string = "ImageKnife" // context cacheDir 的缓存文件目录
|
||||
maxMemory: number = 0
|
||||
currentMemory: number = 0
|
||||
maxSize: number = 0
|
||||
|
@ -56,11 +56,11 @@ export class FileCache {
|
|||
/**
|
||||
* 遍历缓存文件目录,初始化缓存
|
||||
*/
|
||||
public async initFileCache() {
|
||||
public async initFileCache(path: string = FileCache.CACHE_FOLDER) {
|
||||
if (this.isInited) {
|
||||
return
|
||||
}
|
||||
|
||||
FileCache.CACHE_FOLDER = path
|
||||
this.path = this.context?.cacheDir + FileUtils.SEPARATOR + FileCache.CACHE_FOLDER + FileUtils.SEPARATOR
|
||||
await FileUtils.getInstance().createFolder(this.path)
|
||||
// 遍历缓存目录下的文件,按照时间顺序加入缓存
|
||||
|
@ -102,7 +102,48 @@ export class FileCache {
|
|||
this.trimToSize();
|
||||
this.isInited = true
|
||||
}
|
||||
/**
|
||||
* 切换文件缓存目录
|
||||
* @param path 文件缓存目录
|
||||
*/
|
||||
public reCacheFolder(path: string) {
|
||||
if(FileUtils.getInstance().existFolder(this.context?.cacheDir + FileUtils.SEPARATOR + path)) {
|
||||
FileCache.CACHE_FOLDER = path
|
||||
this.path = this.context?.cacheDir + FileUtils.SEPARATOR + FileCache.CACHE_FOLDER + FileUtils.SEPARATOR
|
||||
LogUtil.log(`ImageKnife FileCache The directory:${path} has been created`)
|
||||
} else {
|
||||
LogUtil.log(`ImageKnife FileCache The directory:${path} has not been created yet`)
|
||||
this.isInited = false
|
||||
this.initFileCache(path)
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 改变文件缓存最大缓存数
|
||||
* @param size 最大缓存数
|
||||
*/
|
||||
public reSize(size: number){
|
||||
this.maxSize = size
|
||||
this.trimToMemory()
|
||||
}
|
||||
|
||||
trimToMemory(){
|
||||
while (true) {
|
||||
if (this.lruCache.length <= this.maxSize || this.lruCache.isEmpty()) {
|
||||
break
|
||||
}
|
||||
let delkey = this.lruCache.keys()[0]
|
||||
let remove: number | undefined = this.lruCache.remove(delkey)
|
||||
if (remove !== undefined) {
|
||||
FileUtils.getInstance().deleteFile(this.path + delkey)
|
||||
this.removeMemorySize(remove)
|
||||
}
|
||||
this.lruCache.remove(delkey)
|
||||
}
|
||||
}
|
||||
|
||||
getCacheFolder(): string {
|
||||
return FileCache.CACHE_FOLDER
|
||||
}
|
||||
public isFileCacheInit():boolean {
|
||||
return this.isInited
|
||||
}
|
||||
|
@ -245,10 +286,10 @@ export class FileCache {
|
|||
* @param key
|
||||
* @param value
|
||||
*/
|
||||
static saveFileCacheOnlyFile(context: Context, key: string, value: ArrayBuffer): boolean {
|
||||
static saveFileCacheOnlyFile(context: Context, key: string, value: ArrayBuffer , folder: string = FileCache.CACHE_FOLDER): boolean {
|
||||
// 写文件
|
||||
FileUtils.getInstance()
|
||||
.writeFileSync(context.cacheDir + FileUtils.SEPARATOR + FileCache.CACHE_FOLDER + FileUtils.SEPARATOR + key, value)
|
||||
.writeFileSync(context.cacheDir + FileUtils.SEPARATOR + folder + FileUtils.SEPARATOR + key, value)
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -258,10 +299,10 @@ export class FileCache {
|
|||
* @param key
|
||||
* @returns
|
||||
*/
|
||||
static getFileCacheByFile(context: Context, key: string): ArrayBuffer | undefined {
|
||||
static getFileCacheByFile(context: Context, key: string, folder: string = FileCache.CACHE_FOLDER): ArrayBuffer | undefined {
|
||||
// 从文件获取查看是否有缓存
|
||||
return FileUtils.getInstance()
|
||||
.readFileSync(context.cacheDir + FileUtils.SEPARATOR + FileCache.CACHE_FOLDER + FileUtils.SEPARATOR + key)
|
||||
.readFileSync(context.cacheDir + FileUtils.SEPARATOR + folder + FileUtils.SEPARATOR + key)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue