跳过网络,从内存中取图片,md文档

This commit is contained in:
‘593378212@qq.com’ 2024-04-01 14:20:45 +08:00
parent 90dca0464e
commit 8eb51716b9
4 changed files with 379 additions and 9 deletions

File diff suppressed because one or more lines are too long

View File

@ -46,6 +46,7 @@
"pages/testImageKnifeAutoWidthPage", "pages/testImageKnifeAutoWidthPage",
"pages/testImageKnifeAutoHeightPage", "pages/testImageKnifeAutoHeightPage",
"pages/testPriorityComponent", "pages/testPriorityComponent",
"pages/testReusePhotoPage" "pages/testReusePhotoPage",
"pages/testImageKnifeCache"
] ]
} }

View File

@ -16,7 +16,7 @@
import { DiskLruCache } from "../cache/DiskLruCache" import { DiskLruCache } from "../cache/DiskLruCache"
import { EngineKeyFactories } from "../cache/key/EngineKeyFactories" import { EngineKeyFactories } from "../cache/key/EngineKeyFactories"
import { EngineKeyInterface } from "../cache/key/EngineKeyInterface" import { EngineKeyInterface } from "../cache/key/EngineKeyInterface"
import { RequestOption, Size } from "../imageknife/RequestOption" import { CacheType, RequestOption, Size } from "../imageknife/RequestOption"
import { AsyncCallback } from "../imageknife/interface/AsyncCallback" import { AsyncCallback } from "../imageknife/interface/AsyncCallback"
import { PlaceHolderManager } from "../imageknife/holder/PlaceHolderManager" import { PlaceHolderManager } from "../imageknife/holder/PlaceHolderManager"
import { RetryHolderManager } from "../imageknife/holder/RetryHolderManager" import { RetryHolderManager } from "../imageknife/holder/RetryHolderManager"
@ -49,6 +49,10 @@ import { ObjectKey } from './ObjectKey'
import { TaskParams } from './TaskParams' import { TaskParams } from './TaskParams'
import { Constants } from './constants/Constants' import { Constants } from './constants/Constants'
import { TransformUtils } from './transform/TransformUtils' import { TransformUtils } from './transform/TransformUtils'
import { GIFParseImpl } from './utils/gif/GIFParseImpl'
import { IParseImage } from './interface/IParseImage'
import { ParseImageUtil } from './utils/ParseImageUtil'
import { SVGParseImpl } from './utils/svg/SVGParseImpl'
export class ImageKnife { export class ImageKnife {
static readonly SEPARATOR: string = '/' static readonly SEPARATOR: string = '/'
@ -78,8 +82,10 @@ export class ImageKnife {
defaultLifeCycle: IDrawLifeCycle | undefined = undefined; defaultLifeCycle: IDrawLifeCycle | undefined = undefined;
// 开发者可配置全局缓存 // 开发者可配置全局缓存
engineKeyImpl: EngineKeyInterface; engineKeyImpl: EngineKeyInterface;
private mParseImageUtil: IParseImage<PixelMap>;
private constructor() { private constructor() {
this.mParseImageUtil = new ParseImageUtil();
this.runningMaps = new EasyLinkedHashMap(); this.runningMaps = new EasyLinkedHashMap();
this.pendingMaps = new EasyLinkedHashMap(); this.pendingMaps = new EasyLinkedHashMap();
@ -322,6 +328,91 @@ export class ImageKnife {
return this.parseSource(request); return this.parseSource(request);
} }
public isUrlExist(request: RequestOption): Promise<ImageKnifeData> {
return new Promise((resolve, reject) => {
this.generateDataCacheKey(request);
let loadComplete = (imageKnifeData: ImageKnifeData) => {
resolve(imageKnifeData);
}
let loadError = (err ?: BusinessError | string) => {
reject(undefined);
}
this.loadMemoryCacheAndDiskFrom(request, loadComplete, loadError);
})
}
loadMemoryCacheAndDiskFrom(request: RequestOption, onComplete: (imageKnifeData: ImageKnifeData) => void | PromiseLike<ImageKnifeData>, onError: (err?: BusinessError | string) => void) {
if (request.cacheType == CacheType.Cache) {
let cache = this.memoryCacheProxy.loadMemoryCache(request.generateCacheKey, true);
if (cache == null || typeof cache == 'undefined') {
onError("No data in cache!")
}else {
cache.waitSaveDisk = false;
//2.网络缓存有数据,返回
onComplete(cache);
}
}else if (request.cacheType == CacheType.Disk){
let cached: ArrayBuffer = DiskLruCache.getFileCacheByFile((ImageKnifeGlobal.getInstance()
.getHapContext() as common.UIAbilityContext).filesDir as string, request.generateDataKey) as ArrayBuffer;
if (cached != null) {
let filetype: string | null = this.fileTypeUtil.getFileType(cached);
if (filetype == null) {
onError('请检查数据源');
return;
}
if (!this.fileTypeUtil.isImage(cached)) {
onError('暂不支持的类型!类型=' + filetype);
}
if (ImageKnifeData.GIF == filetype && !request.dontAnimateFlag) {
let gifParseImpl = new GIFParseImpl()
gifParseImpl.parseGifs(cached, (data?: GIFFrame[], err?: BusinessError | string) => {
if (err) {
onError(err)
}
LogUtil.log("gifProcess data is null:" + (data == null));
if (!!data) {
let imageKnifeData = ImageKnifeData.createImageGIFFrame(ImageKnifeType.GIFFRAME, data);
LogUtil.log('gifProcess 生成gif 返回数据类型')
onComplete(imageKnifeData)
} else {
onError('Parse GIF callback data is null, you need check callback data!')
}
})
} else if (ImageKnifeData.SVG == filetype) {
let svgParseImpl = new SVGParseImpl()
let success = (value: PixelMap) => {
let imageKnifeData = ImageKnifeData.createImagePixelMap(ImageKnifeType.PIXELMAP, value);
onComplete(imageKnifeData);
}
svgParseImpl.parseSvg(request, cached, success, onError)
} else {
//5.磁盘有数据解析错误返回onError
let success = (value: PixelMap) => {
let imageKnifeData = ImageKnifeData.createImagePixelMap(ImageKnifeType.PIXELMAP, value);
onComplete(imageKnifeData);
}
this.mParseImageUtil.parseImage(cached, success, onError)
}
} else {
//6.磁盘无数据返回onError
onError("No data in disk cache!")
}
}
}
generateDataCacheKey(request: RequestOption) { generateDataCacheKey(request: RequestOption) {
let factories: EngineKeyInterface; let factories: EngineKeyInterface;
let cacheKey: string; let cacheKey: string;

View File

@ -64,14 +64,23 @@ export interface Size {
height: number height: number
} }
export enum CacheType {
//缓存
Cache,
//磁盘
Disk
}
export interface DetachFromLayout { export interface DetachFromLayout {
detach: () => void detach: () => void
} }
export enum Priority { export enum Priority {
HIGH = 0, HIGH = 0,
MEDIUM = 1, MEDIUM = 1,
LOW = 2 LOW = 2
} }
export class RequestOption { export class RequestOption {
// 遍历添加图片http请求头 // 遍历添加图片http请求头
headers: Map<string, Object> = new Map<string, Object>(); headers: Map<string, Object> = new Map<string, Object>();
@ -85,6 +94,8 @@ export class RequestOption {
addHeaderMap(map: Map<string, Object>) { addHeaderMap(map: Map<string, Object>) {
this.headers = map; this.headers = map;
} }
cacheType: CacheType = CacheType.Disk;
// 优先级 // 优先级
priority: Priority = Priority.MEDIUM; priority: Priority = Priority.MEDIUM;
uuid: string = '' // 唯一标识 uuid: string = '' // 唯一标识
@ -129,7 +140,7 @@ export class RequestOption {
// 下载原始文件地址 // 下载原始文件地址
downloadFilePath: string = ""; downloadFilePath: string = "";
//磁盘缓存文件路径 //磁盘缓存文件路径
diskMemoryCachePath: string =""; diskMemoryCachePath: string = "";
// 网络文件下载统一存放 // 网络文件下载统一存放
networkCacheFolder: string = "ImageKnifeNetworkFolder" networkCacheFolder: string = "ImageKnifeNetworkFolder"
// 主线图片 状态变化 是否加载完成 // 主线图片 状态变化 是否加载完成
@ -164,12 +175,15 @@ export class RequestOption {
this.moduleContext = ctx; this.moduleContext = ctx;
} }
} }
setPriority(priority: Priority) { setPriority(priority: Priority) {
this.priority = priority this.priority = priority
} }
setTransformations( array:Array<BaseTransform<PixelMap>>){
setTransformations(array: Array<BaseTransform<PixelMap>>) {
this.transformations = array; this.transformations = array;
} }
generateUUID(): string { generateUUID(): string {
let d = new Date().getTime(); let d = new Date().getTime();
const uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(new RegExp("[xy]", "g"), (c) => { const uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(new RegExp("[xy]", "g"), (c) => {
@ -197,6 +211,11 @@ export class RequestOption {
return this; return this;
} }
setCacheType(cacheType: CacheType) {
this.cacheType = cacheType;
return this;
}
getFilesPath() { getFilesPath() {
return this.filesPath; return this.filesPath;
} }
@ -477,7 +496,7 @@ export class RequestOption {
} }
// 占位图解析成功 // 占位图解析成功
placeholderOnComplete = (imageKnifeData:ImageKnifeData) => { placeholderOnComplete = (imageKnifeData: ImageKnifeData) => {
LogUtil.log("placeholderOnComplete has called!"); LogUtil.log("placeholderOnComplete has called!");
LogUtil.log("Main Image is Ready:" + this.loadMainReady); LogUtil.log("Main Image is Ready:" + this.loadMainReady);
if (!this.loadMainReady && !(this.loadErrorReady || this.loadRetryReady) && !this.loadThumbnailReady) { if (!this.loadMainReady && !(this.loadErrorReady || this.loadRetryReady) && !this.loadThumbnailReady) {
@ -511,7 +530,7 @@ export class RequestOption {
LogUtil.log("缩略图解析失败 error =" + error) LogUtil.log("缩略图解析失败 error =" + error)
} }
// 加载失败 占位图解析成功 // 加载失败 占位图解析成功
errorholderOnComplete = (imageKnifeData:ImageKnifeData) => { errorholderOnComplete = (imageKnifeData: ImageKnifeData) => {
// 如果有错误占位图 先解析并保存在RequestOption中 等到加载失败时候进行调用 // 如果有错误占位图 先解析并保存在RequestOption中 等到加载失败时候进行调用
this.errorholderData = imageKnifeData; this.errorholderData = imageKnifeData;
if (this.loadErrorReady) { if (this.loadErrorReady) {
@ -524,7 +543,7 @@ export class RequestOption {
errorholderOnError = (error: BusinessError | string) => { errorholderOnError = (error: BusinessError | string) => {
LogUtil.log("失败占位图解析失败 error =" + error) LogUtil.log("失败占位图解析失败 error =" + error)
} }
retryholderOnComplete = (imageKnifeData:ImageKnifeData) => { retryholderOnComplete = (imageKnifeData: ImageKnifeData) => {
this.retryholderData = imageKnifeData; this.retryholderData = imageKnifeData;
if (this.loadRetryReady) { if (this.loadRetryReady) {
if (this.retryholderFunc != undefined) { if (this.retryholderFunc != undefined) {
@ -535,7 +554,6 @@ export class RequestOption {
retryholderOnError = (error: BusinessError | string) => { retryholderOnError = (error: BusinessError | string) => {
LogUtil.log("重试占位图解析失败 error =" + error) LogUtil.log("重试占位图解析失败 error =" + error)
} }
loadComplete = (imageKnifeData: ImageKnifeData) => { loadComplete = (imageKnifeData: ImageKnifeData) => {
this.loadMainReady = true; this.loadMainReady = true;
// 三级缓存数据加载成功 // 三级缓存数据加载成功
@ -586,7 +604,6 @@ export class RequestOption {
} }
} }
} }
// 图片文件落盘之后会自动去寻找下一个数据加载 // 图片文件落盘之后会自动去寻找下一个数据加载
removeCurrentAndSearchNext = () => { removeCurrentAndSearchNext = () => {
if (ImageKnifeGlobal.getInstance().getImageKnife() != undefined) { if (ImageKnifeGlobal.getInstance().getImageKnife() != undefined) {