From 6e708e1c177f44955870a76d1eb888491bebaae6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=94=B0=E5=8F=8C=E6=98=8E?= Date: Wed, 9 Oct 2024 08:39:28 +0000 Subject: [PATCH] update library/src/main/ets/downsampling/DownsampleStartegy.ets. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 田双明 --- .../ets/downsampling/DownsampleStartegy.ets | 133 +++++++++++------- 1 file changed, 79 insertions(+), 54 deletions(-) diff --git a/library/src/main/ets/downsampling/DownsampleStartegy.ets b/library/src/main/ets/downsampling/DownsampleStartegy.ets index 05a3610..50387f0 100644 --- a/library/src/main/ets/downsampling/DownsampleStartegy.ets +++ b/library/src/main/ets/downsampling/DownsampleStartegy.ets @@ -13,30 +13,36 @@ * limitations under the License. */ import { BaseDownsampling } from './BaseDownsampling'; -import { highestOneBit, SampleSizeRounding } from './DownsampleUtils'; +import { getScale, highestOneBit, round, SampleSizeRounding } from './DownsampleUtils'; export class FitCenter implements BaseDownsampling { getName() { return "FitCenter" } - getScaleFactor(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 { - const maxIntegerFactor = Math.max(sourceHeight / requestedHeight, sourceWidth / requestedWidth); - const a = maxIntegerFactor === 0 ? 1 : 1 / highestOneBit(maxIntegerFactor) - return a; + getScaleFactor(sourceWidth: number, sourceHeight: number, requestedWidth: number, requestedHeight: number, + downsampType: DownsampleStrategy + ): number { + //重新计算宽高比; + let outSize: Size = { + width: round(getScale(sourceWidth, sourceHeight, requestedWidth, requestedHeight, downsampType) * sourceWidth), + height:round(getScale(sourceWidth, sourceHeight, requestedWidth, requestedHeight, downsampType) * sourceHeight) } + let scaleFactor = this.getSampleSizeType(sourceWidth, sourceHeight, requestedWidth, requestedHeight, downsampType)=== + SampleSizeRounding.QUALITY? Math.max(1, highestOneBit(Math.max(sourceWidth / outSize.width, sourceHeight / outSize.height))) : + Math.max(1, highestOneBit(Math.min(sourceWidth / outSize.width, sourceHeight / outSize.height)))//将整型的缩放因子转换为2的次幂采样大小 + + if (this.getSampleSizeType(sourceWidth, sourceHeight, requestedWidth, requestedHeight, downsampType)=== + SampleSizeRounding.MEMORY && (scaleFactor < (1 / getScale(sourceWidth, sourceHeight, requestedWidth, requestedHeight, downsampType)))) { + scaleFactor = scaleFactor << 1; + } + return scaleFactor } - //实现 getSampleSizeRounding 方法 - getSampleSizeRounding(sourceWidth: number, sourceHeight: number, requestedWidth: number, requestedHeight: number,downsampType:DownsampleStrategy|undefined - ): number { - if (downsampType===DownsampleStrategy.FIT_CENTER_QUALITY) { + getSampleSizeType(sourceWidth: number, sourceHeight: number, requestedWidth: number, requestedHeight: number, + downsampType: DownsampleStrategy + ): number { + if (downsampType === DownsampleStrategy.FIT_CENTER_QUALITY) { return SampleSizeRounding.QUALITY; } else { return SampleSizeRounding.MEMORY; @@ -52,15 +58,19 @@ export class None implements BaseDownsampling { public getScaleFactor(sourceWidth: number, sourceHeight: number, requestedWidth: number, requestedHeight: number): number { - //不进行任何下采样,缩放因子为 1 - return 1; + let outSize: Size = { + width: round(sourceWidth), + height:round(sourceHeight) + } + let scaleFactor = + Math.max(1, highestOneBit(Math.max(sourceWidth / outSize.width, sourceHeight / outSize.height))) + return scaleFactor } - //实现 getSampleSizeRounding 方法 - public getSampleSizeRounding(sourceWidth: number, sourceHeight: number, requestedWidth: number, + //实现 getSampleSizeType 方法 + public getSampleSizeType(sourceWidth: number, sourceHeight: number, requestedWidth: number, requestedHeight: number): SampleSizeRounding { return SampleSizeRounding.QUALITY - } } @@ -77,10 +87,16 @@ export class CenterOutside implements BaseDownsampling { const widthPercentage = requestedWidth / sourceWidth; const heightPercentage = requestedHeight / sourceHeight; //返回宽度和高度比例中最大的值 - return Math.max(widthPercentage, heightPercentage); + let outSize: Size = { + width: round(Math.max(widthPercentage, heightPercentage) * sourceWidth), + height:round(Math.max(widthPercentage, heightPercentage) * sourceHeight) + } + let scaleFactor = Math.max(1, highestOneBit(Math.max(sourceWidth / outSize.width, sourceHeight / outSize.height))) + + return scaleFactor } - getSampleSizeRounding(sourceWidth: number, sourceHeight: number, requestedWidth: number, + getSampleSizeType(sourceWidth: number, sourceHeight: number, requestedWidth: number, requestedHeight: number): SampleSizeRounding { return SampleSizeRounding.QUALITY; } @@ -93,7 +109,7 @@ export class AtMost implements BaseDownsampling { return "AtMost" } - //实现 getScaleFactor 方法 + getScaleFactor(sourceWidth: number, sourceHeight: number, requestedWidth: number, requestedHeight: number): number { const maxIntegerFactor = Math.ceil(Math.max(sourceHeight / requestedHeight, sourceWidth / requestedWidth)); let lesserOrEqualSampleSize = Math.max(1, highestOneBit(maxIntegerFactor)); @@ -103,11 +119,19 @@ export class AtMost implements BaseDownsampling { } greaterOrEqualSampleSize = lesserOrEqualSampleSize << (lesserOrEqualSampleSize < maxIntegerFactor ? 1 : 0) //返回缩放因子 - return 1 / greaterOrEqualSampleSize + let outSize: Size = { + width: round((1 / greaterOrEqualSampleSize) * sourceWidth), + height:round((1 / greaterOrEqualSampleSize) * sourceHeight) + } + let scaleFactor = Math.max(1, highestOneBit(Math.min(sourceWidth / outSize.width, sourceHeight / outSize.height))) + if ((scaleFactor < greaterOrEqualSampleSize)) { + scaleFactor = scaleFactor << 1; + } + return scaleFactor } - getSampleSizeRounding(sourceWidth: number, sourceHeight: number, requestedWidth: number, + getSampleSizeType(sourceWidth: number, sourceHeight: number, requestedWidth: number, requestHeight: number): SampleSizeRounding { //根据 AtMost 的逻辑,总是返回 MEMORY return SampleSizeRounding.MEMORY @@ -120,43 +144,44 @@ export class CenterInside implements BaseDownsampling { getName() { return "CenterInside" } - - getScaleFactor(sourceWidth: number, sourceHeight: number, requestedWidth: number, requestedHeight: number,downsampType:DownsampleStrategy|undefined - ): number { - //获取 FIT_CENTER 的缩放因子 - const fitCenterScaleFactor: ESObject = - this.getScale(sourceWidth, sourceHeight, requestedWidth, requestedHeight, downsampType); - //返回不超过 1 的缩放因子,即尽量缩小图像以适应目标尺寸,但不会放大 - return Math.min(1, fitCenterScaleFactor); - - } - - getScale(sourceWidth: number, sourceHeight: number, requestedWidth: number, requestedHeight: number,downsampType:DownsampleStrategy|undefined + getScaleFactor(sourceWidth: number, sourceHeight: number, requestedWidth: number, requestedHeight: number, + downsampType: DownsampleStrategy ): number { - if (downsampType===DownsampleStrategy.FIT_CENTER_MEMORY) { - const widthPercentage = requestedWidth / sourceWidth - const heightPercentage = requestedHeight / sourceHeight - return Math.min(widthPercentage, heightPercentage) - } else { - const maxIntegerFactor = Math.max(sourceHeight / requestedHeight, sourceWidth / requestedWidth); - const a = maxIntegerFactor === 0 ? 1 : 1 / highestOneBit(maxIntegerFactor) - return a; + + let outSize: Size = { + width: round(Math.min(1, getScale(sourceWidth, sourceHeight, requestedWidth, requestedHeight, downsampType)) * sourceWidth), + height:round(Math.min(1, getScale(sourceWidth, sourceHeight, requestedWidth, requestedHeight, downsampType)) * sourceHeight) } + let scaleFactor = this.getSampleSizeType(sourceWidth, sourceHeight, requestedWidth, requestedHeight, + downsampType) == SampleSizeRounding.QUALITY ? + Math.max(sourceWidth / outSize.width, sourceHeight / outSize.height) : + Math.min(sourceWidth / outSize.width, sourceHeight / outSize.height) //重新计算宽高比 + + scaleFactor = Math.max(1, highestOneBit(scaleFactor))//将整型的缩放因子转换为2的次幂采样大小 + + if (this.getSampleSizeType(sourceWidth, sourceHeight, requestedWidth, requestedHeight, downsampType) + == SampleSizeRounding.MEMORY && (scaleFactor < (1 / Math.min(1, getScale(sourceWidth, sourceHeight, requestedWidth, requestedHeight, downsampType))))) { + scaleFactor = scaleFactor << 1; + } + return scaleFactor + } - getSampleSizeRounding(sourceWidth: number, sourceHeight: number, requestedWidth: number, requestedHeight: number,downsampType:DownsampleStrategy|undefined - ): SampleSizeRounding { + getSampleSizeType(sourceWidth: number, sourceHeight: number, requestedWidth: number, requestedHeight: number, + downsampType: DownsampleStrategy + ): SampleSizeRounding { //如果缩放因子为 1,表示没有缩放,优先选择质量 - if (this.getScaleFactor(sourceWidth, sourceHeight, requestedWidth, requestedHeight, downsampType) === 1) { + if (Math.min(1, getScale(sourceWidth, sourceHeight, requestedWidth, requestedHeight, downsampType)) === 1) { return SampleSizeRounding.QUALITY } //否则,使用 FIL_CENTER 的 SampleSizeRounding 值 - return this.getSampleSize(sourceWidth, sourceHeight, requestedWidth, requestedHeight,downsampType); + return this.getSampleSize(sourceWidth, sourceHeight, requestedWidth, requestedHeight, downsampType); } - getSampleSize(sourceWidth: number, sourceHeight: number, requestedWidth: number, requestedHeight: number,downsampType:DownsampleStrategy|undefined - ): SampleSizeRounding { - if (downsampType===DownsampleStrategy.CENTER_INSIDE_MEMORY) { + getSampleSize(sourceWidth: number, sourceHeight: number, requestedWidth: number, requestedHeight: number, + downsampType: DownsampleStrategy + ): SampleSizeRounding { + if (downsampType === DownsampleStrategy.CENTER_INSIDE_MEMORY) { return SampleSizeRounding.MEMORY; } else { return SampleSizeRounding.QUALITY; @@ -168,11 +193,11 @@ export enum DownsampleStrategy { //请求尺寸大于实际尺寸不进行放大 AT_MOST, //两边自适应内存优先 - FIT_CENTER_MEMORY , + FIT_CENTER_MEMORY, //两边自适应质量优先 FIT_CENTER_QUALITY, //按照宽高比的最大比进行适配内存优先 - CENTER_INSIDE_MEMORY , + CENTER_INSIDE_MEMORY, //按照宽高比的最大比进行适配质量优先 CENTER_INSIDE_QUALITY, //宽高进行等比缩放宽高里面最小的比例先放进去,然后再根据原图的缩放比去适配