forked from floraachy/ImageKnife
473 lines
14 KiB
Plaintext
473 lines
14 KiB
Plaintext
/*
|
||
* Copyright (C) 2021 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 { DiskStrategy } from "../cache/diskstrategy/DiskStrategy"
|
||
import type { AsyncCallback } from "../imageknife/interface/asynccallback"
|
||
import type { AsyncSuccess } from "../imageknife/interface/AsyncSuccess"
|
||
import type { IAllCacheInfoCallback } from "../imageknife/interface/IAllCacheInfoCallback"
|
||
import { AUTOMATIC } from "../cache/diskstrategy/enum/AUTOMATIC"
|
||
import { BaseTransform } from "../imageknife/transform/BaseTransform"
|
||
import { RotateImageTransformation } from "../imageknife/transform/RotateImageTransformation"
|
||
import { ImageKnifeData } from "../imageknife/ImageKnifeData"
|
||
import { CenterCrop } from '../imageknife/transform/pixelmap/CenterCrop'
|
||
import { CenterInside } from '../imageknife/transform/pixelmap/CenterInside'
|
||
import { FitCenter } from '../imageknife/transform/pixelmap/FitCenter'
|
||
import { RoundedCornersTransformation } from '../imageknife/transform/RoundedCornersTransformation'
|
||
|
||
import { CropCircleTransformation } from '../imageknife/transform/CropCircleTransformation'
|
||
|
||
import { CropCircleWithBorderTransformation } from '../imageknife/transform/CropCircleWithBorderTransformation'
|
||
import { CropSquareTransformation } from '../imageknife/transform/CropSquareTransformation'
|
||
import { CropTransformation } from '../imageknife/transform/CropTransformation'
|
||
import { CropType } from '../imageknife/transform/CropTransformation'
|
||
import { GrayscaleTransformation } from '../imageknife/transform/GrayscaleTransformation'
|
||
import { BrightnessFilterTransformation } from '../imageknife/transform/BrightnessFilterTransformation'
|
||
import { ContrastFilterTransformation } from '../imageknife/transform/ContrastFilterTransformation'
|
||
import { InvertFilterTransformation } from '../imageknife/transform/InvertFilterTransformation'
|
||
import { SepiaFilterTransformation } from '../imageknife/transform/SepiaFilterTransformation'
|
||
import { SketchFilterTransformation } from '../imageknife/transform/SketchFilterTransformation'
|
||
import { BlurTransformation } from '../imageknife/transform/BlurTransformation'
|
||
import { PixelationFilterTransformation } from '../imageknife/transform/PixelationFilterTransformation'
|
||
import { MaskTransformation } from '../imageknife/transform/MaskTransformation'
|
||
import { SwirlFilterTransformation } from '../imageknife/transform/SwirlFilterTransformation'
|
||
import { KuwaharaFilterTransform } from '../imageknife/transform/KuwaharaFilterTransform'
|
||
import { ToonFilterTransform } from '../imageknife/transform/ToonFilterTransform'
|
||
import { VignetteFilterTransform } from '../imageknife/transform/VignetteFilterTransform'
|
||
import { LogUtil } from '../imageknife/utils/LogUtil'
|
||
|
||
export class RequestOption {
|
||
loadSrc: string | PixelMap | Resource;
|
||
strategy: DiskStrategy = new AUTOMATIC();
|
||
dontAnimateFlag = false;
|
||
placeholderSrc: PixelMap | Resource;
|
||
placeholderFunc: AsyncSuccess<ImageKnifeData>;
|
||
errorholderSrc: PixelMap | Resource;
|
||
errorholderFunc: AsyncSuccess<ImageKnifeData>;
|
||
errorholderData: ImageKnifeData;
|
||
thumbSizeMultiplier: number;
|
||
|
||
// 如果存在缩略图,则主图延时1s加载
|
||
thumbDelayTime: number = 1000
|
||
thumbHolderFunc: AsyncSuccess<ImageKnifeData>;
|
||
requestListeners: Array<AsyncCallback<ImageKnifeData>>;
|
||
|
||
// 进度条
|
||
progressFunc: AsyncSuccess<number>;
|
||
|
||
// 重试图层
|
||
retryholderSrc: PixelMap | Resource;
|
||
retryholderFunc: AsyncSuccess<ImageKnifeData>
|
||
retryholderData: ImageKnifeData
|
||
size: {
|
||
width: number,
|
||
height: number
|
||
} = { width: -1, height: -1 };
|
||
|
||
// 网络下载数据回调
|
||
allCacheInfoCallback: IAllCacheInfoCallback;
|
||
onlyRetrieveFromCache: boolean = false;
|
||
isCacheable: boolean = true;
|
||
|
||
//开启GPU变换绘制
|
||
gpuEnabled: boolean = false;
|
||
// 变换相关
|
||
transformations: Array<BaseTransform<PixelMap>> = new Array();
|
||
generateCacheKey: string = "";
|
||
generateResourceKey: string = "";
|
||
generateDataKey: string = "";
|
||
private filesPath: string = ""; // data/data/包名/files目录
|
||
private cachesPath: string = ""; // 网络下载默认存储在data/data/包名/cache/ImageKnifeNetworkFolder/目标md5.img下面
|
||
|
||
// 下载原始文件地址
|
||
downloadFilePath: string = "";
|
||
|
||
// 网络文件下载统一存放
|
||
networkCacheFolder: string = "ImageKnifeNetworkFolder"
|
||
|
||
|
||
// 主线图片 状态变化 是否加载完成
|
||
// 主图未加载成功 显示占位图 主图加载成功不展示占位图
|
||
loadMainReady = false;
|
||
|
||
// 失败占位图展示状态 当true 表示主图加载失败需要展示失败占位图
|
||
loadErrorReady = false;
|
||
|
||
// 重试占位图展示状态 当true 表示主图加载失败需要展示失败占位图
|
||
loadRetryReady = false;
|
||
|
||
// 缩略图展示
|
||
loadThumbnailReady = false;
|
||
|
||
constructor() {
|
||
// 初始化全局监听
|
||
this.requestListeners = new Array();
|
||
}
|
||
|
||
/**
|
||
* set image Component size
|
||
*/
|
||
setImageViewSize(imageSize: {
|
||
width: number,
|
||
height: number
|
||
}) {
|
||
this.size.width = imageSize.width;
|
||
this.size.height = imageSize.height;
|
||
return this;
|
||
}
|
||
|
||
getFilesPath() {
|
||
return this.filesPath;
|
||
}
|
||
|
||
setFilesPath(path: string) {
|
||
this.filesPath = path;
|
||
}
|
||
|
||
getCachesPath() {
|
||
return this.cachesPath;
|
||
}
|
||
|
||
setCachesPath(path: string) {
|
||
this.cachesPath = path;
|
||
}
|
||
|
||
load(src: string | PixelMap | Resource) {
|
||
this.loadSrc = src;
|
||
return this;
|
||
}
|
||
|
||
diskCacheStrategy(strategy: DiskStrategy) {
|
||
this.strategy = strategy;
|
||
return this;
|
||
}
|
||
|
||
dontAnimate() {
|
||
this.dontAnimateFlag = true;
|
||
return this;
|
||
}
|
||
|
||
// 仅支持 本地图片
|
||
placeholder(src: PixelMap | Resource, func?: AsyncSuccess<ImageKnifeData>) {
|
||
this.placeholderSrc = src;
|
||
this.placeholderFunc = func;
|
||
return this;
|
||
}
|
||
|
||
errorholder(src: PixelMap | Resource, func?: AsyncSuccess<ImageKnifeData>) {
|
||
this.errorholderSrc = src;
|
||
this.errorholderFunc = func;
|
||
return this;
|
||
}
|
||
|
||
retryholder(src: PixelMap | Resource, func?: AsyncSuccess<ImageKnifeData>) {
|
||
this.retryholderSrc = src;
|
||
this.retryholderFunc = func;
|
||
return this;
|
||
}
|
||
|
||
thumbnail(sizeMultiplier: number, func?: AsyncSuccess<ImageKnifeData>, displayTime?: number) {
|
||
this.thumbSizeMultiplier = sizeMultiplier;
|
||
this.thumbHolderFunc = func;
|
||
if (displayTime) {
|
||
this.thumbDelayTime = displayTime;
|
||
}
|
||
return this;
|
||
}
|
||
|
||
addProgressListener(func?: AsyncSuccess<number>) {
|
||
this.progressFunc = func;
|
||
return this;
|
||
}
|
||
|
||
addListener(func: AsyncCallback<ImageKnifeData>) {
|
||
this.requestListeners.push(func);
|
||
return this;
|
||
}
|
||
|
||
addAllCacheInfoCallback(func: IAllCacheInfoCallback) {
|
||
this.allCacheInfoCallback = func;
|
||
return this;
|
||
}
|
||
|
||
skipMemoryCache(skip: boolean) {
|
||
this.isCacheable = !skip;
|
||
return this;
|
||
}
|
||
|
||
retrieveDataFromCache(flag: boolean) {
|
||
this.onlyRetrieveFromCache = flag;
|
||
}
|
||
|
||
rotateImage(degreesToRotate: number) {
|
||
let rotateImage = new RotateImageTransformation(degreesToRotate);
|
||
this.transformations.push(rotateImage);
|
||
return this;
|
||
}
|
||
|
||
centerCrop() {
|
||
this.transformations.push(new CenterCrop());
|
||
return this;
|
||
}
|
||
|
||
centerInside() {
|
||
this.transformations.push(new CenterInside());
|
||
return this;
|
||
}
|
||
|
||
fitCenter() {
|
||
this.transformations.push(new FitCenter());
|
||
return this;
|
||
}
|
||
|
||
roundedCorners(obj: {
|
||
top_left: number,
|
||
top_right: number,
|
||
bottom_left: number,
|
||
bottom_right: number
|
||
}) {
|
||
let transformation = new RoundedCornersTransformation({
|
||
top_left: obj.top_left,
|
||
top_right: obj.top_right,
|
||
bottom_left: obj.bottom_left,
|
||
bottom_right: obj.bottom_right
|
||
})
|
||
this.transformations.push(transformation);
|
||
return this;
|
||
}
|
||
|
||
cropCircle() {
|
||
let transformation = new CropCircleTransformation()
|
||
this.transformations.push(transformation);
|
||
return this;
|
||
}
|
||
|
||
cropCircleWithBorder(border: number, obj: {
|
||
r_color: number,
|
||
g_color: number,
|
||
b_color: number
|
||
}) {
|
||
let transformation = new CropCircleWithBorderTransformation(border, obj)
|
||
this.transformations.push(transformation);
|
||
return this;
|
||
}
|
||
|
||
cropSquare() {
|
||
let transformation = new CropSquareTransformation()
|
||
this.transformations.push(transformation);
|
||
return this;
|
||
}
|
||
|
||
crop(width: number, height: number, cropType: CropType) {
|
||
let transformation = new CropTransformation(width, height, cropType)
|
||
this.transformations.push(transformation);
|
||
return this;
|
||
}
|
||
|
||
grayscale() {
|
||
let transformation = new GrayscaleTransformation()
|
||
this.transformations.push(transformation);
|
||
return this;
|
||
}
|
||
|
||
brightnessFilter(brightness: number) {
|
||
let transformation = new BrightnessFilterTransformation(brightness)
|
||
this.transformations.push(transformation);
|
||
return this;
|
||
}
|
||
|
||
contrastFilter(contrast: number) {
|
||
let transformation = new ContrastFilterTransformation(contrast)
|
||
this.transformations.push(transformation);
|
||
return this;
|
||
}
|
||
|
||
invertFilter() {
|
||
let transformation = new InvertFilterTransformation()
|
||
this.transformations.push(transformation);
|
||
return this;
|
||
}
|
||
|
||
sepiaFilter() {
|
||
let transformation = new SepiaFilterTransformation()
|
||
this.transformations.push(transformation);
|
||
return this;
|
||
}
|
||
|
||
sketchFilter() {
|
||
let transformation = new SketchFilterTransformation()
|
||
this.transformations.push(transformation);
|
||
return this;
|
||
}
|
||
|
||
blur(radius: number) {
|
||
let transformation = new BlurTransformation(radius)
|
||
this.transformations.push(transformation);
|
||
return this;
|
||
}
|
||
|
||
pixelationFilter(pixel: number) {
|
||
let transformation = new PixelationFilterTransformation(pixel)
|
||
this.transformations.push(transformation);
|
||
return this;
|
||
}
|
||
|
||
swirlFilter(degree: number) {
|
||
let transformation = new SwirlFilterTransformation(degree)
|
||
this.transformations.push(transformation);
|
||
return this;
|
||
}
|
||
|
||
mask(maskResource: Resource) {
|
||
let transformation = new MaskTransformation(maskResource)
|
||
this.transformations.push(transformation);
|
||
return this;
|
||
}
|
||
|
||
kuwaharaFilter(radius: number) {
|
||
let transformation = new KuwaharaFilterTransform(radius);
|
||
this.transformations.push(transformation);
|
||
return this;
|
||
}
|
||
|
||
toonFilter(threshold: number, quantizationLevels: number) {
|
||
let transformation = new ToonFilterTransform(threshold, quantizationLevels);
|
||
this.transformations.push(transformation);
|
||
return this;
|
||
}
|
||
|
||
vignetteFilter(centerPoint: Array<number>, vignetteColor: Array<number>, vignetteSpace: Array<number>) {
|
||
let transformation = new VignetteFilterTransform(centerPoint, vignetteColor, vignetteSpace);
|
||
this.transformations.push(transformation);
|
||
return this;
|
||
}
|
||
|
||
transform(input: BaseTransform<PixelMap>) {
|
||
this.transformations.push(input);
|
||
return this;
|
||
}
|
||
|
||
transforms(inputs: BaseTransform<PixelMap>[]) {
|
||
this.transformations = inputs;
|
||
return this;
|
||
}
|
||
//开启GPU变换绘制
|
||
enableGPU() {
|
||
this.gpuEnabled = true;
|
||
return this;
|
||
}
|
||
|
||
// 占位图解析成功
|
||
placeholderOnComplete(imageKnifeData: ImageKnifeData) {
|
||
LogUtil.log("placeholderOnComplete has called!");
|
||
LogUtil.log("Main Image is Ready:" + this.loadMainReady);
|
||
if (!this.loadMainReady && !(this.loadErrorReady || this.loadRetryReady) && !this.loadThumbnailReady) {
|
||
// 主图未加载成功,并且未加载失败 显示占位图 主图加载成功或者加载失败后=>不展示占位图
|
||
this.placeholderFunc(imageKnifeData)
|
||
}
|
||
}
|
||
|
||
// 占位图解析失败
|
||
placeholderOnError(error) {
|
||
LogUtil.log("占位图解析失败 error =" + error)
|
||
}
|
||
|
||
|
||
// 缩略图解析成功
|
||
thumbholderOnComplete(imageKnifeData: ImageKnifeData) {
|
||
if (!this.loadMainReady && !(this.loadErrorReady || this.loadRetryReady)) {
|
||
//主图未加载成功,并且未加载失败 显示占位图 主图加载成功或者加载失败后=>不展示占位图
|
||
this.thumbHolderFunc(imageKnifeData)
|
||
}
|
||
}
|
||
|
||
// 缩略图解析失败
|
||
thumbholderOnError(error) {
|
||
LogUtil.log("缩略图解析失败 error =" + error)
|
||
}
|
||
|
||
// 加载失败 占位图解析成功
|
||
errorholderOnComplete(imageKnifeData: ImageKnifeData) {
|
||
// 如果有错误占位图 先解析并保存在RequestOption中 等到加载失败时候进行调用
|
||
this.errorholderData = imageKnifeData;
|
||
if (this.loadErrorReady) {
|
||
this.errorholderFunc(imageKnifeData)
|
||
}
|
||
}
|
||
|
||
//加载失败 占位图解析失败
|
||
errorholderOnError(error) {
|
||
LogUtil.log("失败占位图解析失败 error =" + error)
|
||
}
|
||
|
||
retryholderOnComplete(imageKnifeData: ImageKnifeData) {
|
||
this.retryholderData = imageKnifeData;
|
||
if (this.loadRetryReady) {
|
||
this.retryholderFunc(imageKnifeData)
|
||
}
|
||
}
|
||
|
||
retryholderOnError(error) {
|
||
LogUtil.log("重试占位图解析失败 error =" + error)
|
||
}
|
||
|
||
loadComplete(imageKnifeData: ImageKnifeData) {
|
||
this.loadMainReady = true;
|
||
// 三级缓存数据加载成功
|
||
for (let requestListener of this.requestListeners) {
|
||
var ret = requestListener("", imageKnifeData);
|
||
if (ret) {
|
||
break;
|
||
}
|
||
}
|
||
|
||
if(imageKnifeData.waitSaveDisk){
|
||
// 等落盘结束后主动调用#removeCurrentAndSearchNext方法
|
||
}else{
|
||
// 非落盘情况,直接进行寻找下一个加载
|
||
globalThis.ImageKnife.removeRunning(this);
|
||
}
|
||
|
||
// 加载成功之后
|
||
globalThis.ImageKnife.removeRunning(this);
|
||
}
|
||
|
||
// 图片文件落盘之后会自动去寻找下一个数据加载
|
||
removeCurrentAndSearchNext(){
|
||
globalThis.ImageKnife.removeRunning(this);
|
||
}
|
||
|
||
loadError(err) {
|
||
LogUtil.log("loadError:" + err);
|
||
//失败占位图展示规则
|
||
if (this.retryholderFunc) {
|
||
// 重试图层优先于加载失败展示
|
||
this.loadRetryReady = true;
|
||
if (this.retryholderData != null) {
|
||
this.retryholderFunc(this.retryholderData)
|
||
}
|
||
} else {
|
||
// 失败图层标记,如果已经有数据直接展示失败图层
|
||
this.loadErrorReady = true;
|
||
if (this.errorholderData != null) {
|
||
this.errorholderFunc(this.errorholderData)
|
||
}
|
||
}
|
||
// 加载失败之后
|
||
globalThis.ImageKnife.removeRunning(this);
|
||
}
|
||
}
|
||
|
||
|