From 9b44746094cc685e56b6b09a85d1363af5bbc138 Mon Sep 17 00:00:00 2001 From: tsm Date: Thu, 5 Sep 2024 18:34:07 +0800 Subject: [PATCH] =?UTF-8?q?=E9=99=8D=E9=87=87=E6=A0=B7=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: tsm --- library/src/main/ets/ImageKnifeDispatcher.ets | 12 +- .../ets/downsampling/DownsampleStartegy.ets | 21 ++- .../src/main/ets/downsampling/Downsampler.ets | 122 ++++++------------ 3 files changed, 57 insertions(+), 98 deletions(-) diff --git a/library/src/main/ets/ImageKnifeDispatcher.ets b/library/src/main/ets/ImageKnifeDispatcher.ets index 5eb2026..5ed08df 100644 --- a/library/src/main/ets/ImageKnifeDispatcher.ets +++ b/library/src/main/ets/ImageKnifeDispatcher.ets @@ -656,11 +656,11 @@ async function requestJob(request: RequestJobRequest, requestList?: List { resPixelmap = pixelmap diff --git a/library/src/main/ets/downsampling/DownsampleStartegy.ets b/library/src/main/ets/downsampling/DownsampleStartegy.ets index 0e43320..05a3610 100644 --- a/library/src/main/ets/downsampling/DownsampleStartegy.ets +++ b/library/src/main/ets/downsampling/DownsampleStartegy.ets @@ -20,7 +20,7 @@ export class FitCenter implements BaseDownsampling { return "FitCenter" } - getScaleFactor(sourceWidth: number, sourceHeight: number, requestedWidth: number, requestedHeight: number,downsampType:DownsampleStrategy + getScaleFactor(sourceWidth: number, sourceHeight: number, requestedWidth: number, requestedHeight: number,downsampType:DownsampleStrategy |undefined ): number { if (downsampType===DownsampleStrategy.FIT_CENTER_MEMORY) { const widthPercentage = requestedWidth / sourceWidth @@ -34,7 +34,7 @@ export class FitCenter implements BaseDownsampling { } //实现 getSampleSizeRounding 方法 - getSampleSizeRounding(sourceWidth: number, sourceHeight: number, requestedWidth: number, requestedHeight: number,downsampType:DownsampleStrategy + getSampleSizeRounding(sourceWidth: number, sourceHeight: number, requestedWidth: number, requestedHeight: number,downsampType:DownsampleStrategy|undefined ): number { if (downsampType===DownsampleStrategy.FIT_CENTER_QUALITY) { return SampleSizeRounding.QUALITY; @@ -121,7 +121,7 @@ export class CenterInside implements BaseDownsampling { return "CenterInside" } - getScaleFactor(sourceWidth: number, sourceHeight: number, requestedWidth: number, requestedHeight: number,downsampType:DownsampleStrategy + getScaleFactor(sourceWidth: number, sourceHeight: number, requestedWidth: number, requestedHeight: number,downsampType:DownsampleStrategy|undefined ): number { //获取 FIT_CENTER 的缩放因子 const fitCenterScaleFactor: ESObject = @@ -131,21 +131,20 @@ export class CenterInside implements BaseDownsampling { } - getScale(sourceWidth: number, sourceHeight: number, requestedWidth: number, requestedHeight: number,downsampType:DownsampleStrategy - ): number { - if (downsampType===DownsampleStrategy.FIT_CENTER_QUALITY) { + getScale(sourceWidth: number, sourceHeight: number, requestedWidth: number, requestedHeight: number,downsampType:DownsampleStrategy|undefined + ): number { + if (downsampType===DownsampleStrategy.FIT_CENTER_MEMORY) { const widthPercentage = requestedWidth / sourceWidth const heightPercentage = requestedHeight / sourceHeight return Math.min(widthPercentage, heightPercentage) } else { - //类似 AT_LEAST,但只要求一个维度或另一个维度大于等于请求的尺寸 const maxIntegerFactor = Math.max(sourceHeight / requestedHeight, sourceWidth / requestedWidth); - return maxIntegerFactor === 0 ? 1 : 1 / highestOneBit(maxIntegerFactor); - + const a = maxIntegerFactor === 0 ? 1 : 1 / highestOneBit(maxIntegerFactor) + return a; } } - getSampleSizeRounding(sourceWidth: number, sourceHeight: number, requestedWidth: number, requestedHeight: number,downsampType:DownsampleStrategy + getSampleSizeRounding(sourceWidth: number, sourceHeight: number, requestedWidth: number, requestedHeight: number,downsampType:DownsampleStrategy|undefined ): SampleSizeRounding { //如果缩放因子为 1,表示没有缩放,优先选择质量 if (this.getScaleFactor(sourceWidth, sourceHeight, requestedWidth, requestedHeight, downsampType) === 1) { @@ -155,7 +154,7 @@ export class CenterInside implements BaseDownsampling { return this.getSampleSize(sourceWidth, sourceHeight, requestedWidth, requestedHeight,downsampType); } - getSampleSize(sourceWidth: number, sourceHeight: number, requestedWidth: number, requestedHeight: number,downsampType:DownsampleStrategy + getSampleSize(sourceWidth: number, sourceHeight: number, requestedWidth: number, requestedHeight: number,downsampType:DownsampleStrategy|undefined ): SampleSizeRounding { if (downsampType===DownsampleStrategy.CENTER_INSIDE_MEMORY) { return SampleSizeRounding.MEMORY; diff --git a/library/src/main/ets/downsampling/Downsampler.ets b/library/src/main/ets/downsampling/Downsampler.ets index 9be34b5..c320404 100644 --- a/library/src/main/ets/downsampling/Downsampler.ets +++ b/library/src/main/ets/downsampling/Downsampler.ets @@ -30,82 +30,33 @@ export interface calculateScaleType { export class Downsampler { calculateScaling( typeValue: string | null, - sourceHeight: number, //原始宽高 + // TODO 宽高调整 sourceWidth: number | undefined, //原始宽高 - requestHeight: number, //请求宽高 + sourceHeight: number, //原始宽高 requestWidth: number, //请求宽高 + requestHeight: number, //请求宽高 downsampType: DownsampleStrategy | undefined, - ): calculateScaleType { - let degreesToRotate: ESObject = 90; const fileType = typeValue //获取图片类型 - let powerOfTwoWidth: number | null = null; - let powerOfTwoHeight: number | null = null; - let targetWidth: number = 0 - let targetHeight: number = 0 - + // TODO 命名修改 powerOfTwoWidth改为targetWidth + let targetWidth: number | null = null; + let targetHeight: number | null = null; if (sourceHeight <= 0 || sourceWidth == undefined || sourceWidth == null || sourceWidth <= 0) { - throw new Error("Cannot found width or height"); + throw new Error("Cannot found width or height"); // TODO catch } - let orientedSourceWidth = sourceWidth; - let orientedSourceHeight = sourceHeight; - if (this.isRotationRequired(degreesToRotate)) { - orientedSourceWidth = sourceHeight; - orientedSourceHeight = sourceWidth; - } - if (requestWidth && !requestHeight) { - targetWidth = this.round((requestHeight) * orientedSourceWidth / orientedSourceHeight) - } else if (requestHeight && !requestWidth) { - targetHeight = this.round((requestWidth) * orientedSourceHeight / orientedSourceWidth) - } else if (requestHeight && requestWidth) { - targetWidth = - requestHeight == sourceWidth ? (this.isRotationRequired(degreesToRotate) ? sourceHeight : sourceWidth) : - requestWidth; - targetHeight = - requestHeight == sourceHeight ? (this.isRotationRequired(degreesToRotate) ? sourceWidth : sourceHeight) : - requestWidth; - } else { - throw new Error("Cannot found width or height"); - } - let exactScaleFactor: number | undefined - let rounding: SampleSizeRounding | undefined - if(downsampType===DownsampleStrategy.FIT_CENTER_MEMORY || downsampType===DownsampleStrategy.FIT_CENTER_QUALITY){ - exactScaleFactor = new FitCenter() - .getScaleFactor(orientedSourceWidth, orientedSourceHeight, targetWidth, targetHeight,downsampType) - rounding = new FitCenter() - .getSampleSizeRounding(orientedSourceWidth, orientedSourceHeight, targetWidth, targetHeight,downsampType) - - }else if(downsampType===DownsampleStrategy.NONE){ - exactScaleFactor = new None() - .getScaleFactor(orientedSourceWidth, orientedSourceHeight, targetWidth, targetHeight) - rounding = new None() - .getSampleSizeRounding(orientedSourceWidth, orientedSourceHeight, targetWidth, targetHeight) - }else if( downsampType===DownsampleStrategy.AT_MOST){ - exactScaleFactor = new AtMost() - .getScaleFactor(orientedSourceWidth, orientedSourceHeight, targetWidth, targetHeight) - rounding = new AtMost() - .getSampleSizeRounding(orientedSourceWidth, orientedSourceHeight, targetWidth, targetHeight) - }else if(downsampType===DownsampleStrategy.CENTER_INSIDE_MEMORY || downsampType===DownsampleStrategy.CENTER_INSIDE_QUALITY){ - exactScaleFactor = new CenterInside() - .getScaleFactor(orientedSourceWidth, orientedSourceHeight, targetWidth, targetHeight,downsampType) - rounding = new CenterInside() - .getSampleSizeRounding(orientedSourceWidth, orientedSourceHeight, targetWidth, targetHeight,downsampType) - }else if(downsampType===DownsampleStrategy.CENTER_OUTSIDE){ - exactScaleFactor = new CenterOutside() - .getScaleFactor(orientedSourceWidth, orientedSourceHeight, targetWidth, targetHeight) - rounding = new CenterOutside() - .getSampleSizeRounding(orientedSourceWidth, orientedSourceHeight, targetWidth, targetHeight) + if(downsampType===undefined){ + throw new Error("Cannot found downsampType"); } + let downsampler = this.getDownsampler(downsampType); + let exactScaleFactor : number = downsampler.getScaleFactor(sourceWidth, sourceHeight, requestWidth, requestHeight, downsampType); + let rounding: SampleSizeRounding= downsampler.getSampleSizeRounding(sourceWidth, sourceHeight, requestWidth, requestHeight, downsampType); if (exactScaleFactor==undefined|| exactScaleFactor <= 0 ) { throw new Error("Cannot round with exactScaleFactor"); } - if (rounding == undefined) { - throw new Error("Cannot round with null rounding"); - } - let outWidth: number = this.round(exactScaleFactor * orientedSourceWidth); - let outHeight: number = this.round(exactScaleFactor * orientedSourceHeight); - let widthScaleFactor = orientedSourceWidth / outWidth; - let heightScaleFactor = orientedSourceHeight / outHeight; + let outWidth: number = this.round(exactScaleFactor * sourceWidth); + let outHeight: number = this.round(exactScaleFactor * sourceHeight); + let widthScaleFactor = sourceWidth / outWidth; + let heightScaleFactor = sourceHeight / outHeight; let scaleFactor = rounding ==SampleSizeRounding.QUALITY ? Math.max(widthScaleFactor, heightScaleFactor) : Math.min(widthScaleFactor, heightScaleFactor) //将整型的缩放因子转换为2的次幂采样大小 let powerOfTwoSampleSize: number = scaleFactor; @@ -115,27 +66,36 @@ export class Downsampler { } //基于上一步得出的采样大小,根据不同的图片类型,计算采样后的图片尺寸 if (fileType === "png") { - powerOfTwoWidth = Math.floor(orientedSourceWidth / powerOfTwoSampleSize); - powerOfTwoHeight = Math.floor(orientedSourceHeight / powerOfTwoSampleSize); + targetWidth = Math.floor(sourceWidth / powerOfTwoSampleSize); + targetHeight = Math.floor(sourceHeight / powerOfTwoSampleSize); } else if (fileType === "webp") { - powerOfTwoWidth = Math.round(orientedSourceWidth / powerOfTwoSampleSize); - powerOfTwoHeight = Math.round(orientedSourceHeight / powerOfTwoSampleSize); + targetWidth = Math.round(sourceWidth / powerOfTwoSampleSize); + targetHeight = Math.round(sourceHeight / powerOfTwoSampleSize); } else { - powerOfTwoWidth = orientedSourceWidth / powerOfTwoSampleSize; - powerOfTwoHeight = orientedSourceHeight / powerOfTwoSampleSize; + targetWidth = sourceWidth / powerOfTwoSampleSize; + targetHeight = sourceHeight / powerOfTwoSampleSize; + } + return { targetWidth, targetHeight } + } + getDownsampler(downsampType:DownsampleStrategy) { + switch (downsampType) { + case DownsampleStrategy.FIT_CENTER_MEMORY: + case DownsampleStrategy.FIT_CENTER_QUALITY: + return new FitCenter(); + case DownsampleStrategy.NONE: + return new None(); + case DownsampleStrategy.AT_MOST: + return new AtMost(); + case DownsampleStrategy.CENTER_INSIDE_MEMORY: + case DownsampleStrategy.CENTER_INSIDE_QUALITY: + return new CenterInside(); + case DownsampleStrategy.CENTER_OUTSIDE: + return new CenterOutside(); + default: + throw new Error('Unsupported downsampling strategy'); } - let a: calculateScaleType = { - "targetWidth": powerOfTwoWidth, - "targetHeight": powerOfTwoHeight - } - return a } - round(value: number): number { return Math.floor(value + 0.5); } - - isRotationRequired(degreesToRotate: number): boolean { - return degreesToRotate == 90 || degreesToRotate == 270; - } }