update library/src/main/ets/downsampling/DownsampleStartegy.ets.

Signed-off-by: 田双明 <tianshuangming@h-partners.com>
This commit is contained in:
田双明 2024-10-09 08:39:28 +00:00 committed by Gitee
parent f80dd101d0
commit 6e708e1c17
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
1 changed files with 79 additions and 54 deletions

View File

@ -13,30 +13,36 @@
* limitations under the License. * limitations under the License.
*/ */
import { BaseDownsampling } from './BaseDownsampling'; import { BaseDownsampling } from './BaseDownsampling';
import { highestOneBit, SampleSizeRounding } from './DownsampleUtils'; import { getScale, highestOneBit, round, SampleSizeRounding } from './DownsampleUtils';
export class FitCenter implements BaseDownsampling { export class FitCenter implements BaseDownsampling {
getName() { getName() {
return "FitCenter" return "FitCenter"
} }
getScaleFactor(sourceWidth: number, sourceHeight: number, requestedWidth: number, requestedHeight: number,downsampType:DownsampleStrategy |undefined getScaleFactor(sourceWidth: number, sourceHeight: number, requestedWidth: number, requestedHeight: number,
): number { downsampType: DownsampleStrategy
if (downsampType===DownsampleStrategy.FIT_CENTER_MEMORY) { ): number {
const widthPercentage = requestedWidth / sourceWidth //重新计算宽高比;
const heightPercentage = requestedHeight / sourceHeight let outSize: Size = {
return Math.min(widthPercentage, heightPercentage) width: round(getScale(sourceWidth, sourceHeight, requestedWidth, requestedHeight, downsampType) * sourceWidth),
} else { height:round(getScale(sourceWidth, sourceHeight, requestedWidth, requestedHeight, downsampType) * sourceHeight)
const maxIntegerFactor = Math.max(sourceHeight / requestedHeight, sourceWidth / requestedWidth);
const a = maxIntegerFactor === 0 ? 1 : 1 / highestOneBit(maxIntegerFactor)
return a;
} }
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 方法 getSampleSizeType(sourceWidth: number, sourceHeight: number, requestedWidth: number, requestedHeight: number,
getSampleSizeRounding(sourceWidth: number, sourceHeight: number, requestedWidth: number, requestedHeight: number,downsampType:DownsampleStrategy|undefined downsampType: DownsampleStrategy
): number { ): number {
if (downsampType===DownsampleStrategy.FIT_CENTER_QUALITY) { if (downsampType === DownsampleStrategy.FIT_CENTER_QUALITY) {
return SampleSizeRounding.QUALITY; return SampleSizeRounding.QUALITY;
} else { } else {
return SampleSizeRounding.MEMORY; return SampleSizeRounding.MEMORY;
@ -52,15 +58,19 @@ export class None implements BaseDownsampling {
public getScaleFactor(sourceWidth: number, sourceHeight: number, requestedWidth: number, public getScaleFactor(sourceWidth: number, sourceHeight: number, requestedWidth: number,
requestedHeight: number): number { requestedHeight: number): number {
//不进行任何下采样,缩放因子为 1 let outSize: Size = {
return 1; width: round(sourceWidth),
height:round(sourceHeight)
}
let scaleFactor =
Math.max(1, highestOneBit(Math.max(sourceWidth / outSize.width, sourceHeight / outSize.height)))
return scaleFactor
} }
//实现 getSampleSizeRounding 方法 //实现 getSampleSizeType 方法
public getSampleSizeRounding(sourceWidth: number, sourceHeight: number, requestedWidth: number, public getSampleSizeType(sourceWidth: number, sourceHeight: number, requestedWidth: number,
requestedHeight: number): SampleSizeRounding { requestedHeight: number): SampleSizeRounding {
return SampleSizeRounding.QUALITY return SampleSizeRounding.QUALITY
} }
} }
@ -77,10 +87,16 @@ export class CenterOutside implements BaseDownsampling {
const widthPercentage = requestedWidth / sourceWidth; const widthPercentage = requestedWidth / sourceWidth;
const heightPercentage = requestedHeight / sourceHeight; 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 { requestedHeight: number): SampleSizeRounding {
return SampleSizeRounding.QUALITY; return SampleSizeRounding.QUALITY;
} }
@ -93,7 +109,7 @@ export class AtMost implements BaseDownsampling {
return "AtMost" return "AtMost"
} }
//实现 getScaleFactor 方法
getScaleFactor(sourceWidth: number, sourceHeight: number, requestedWidth: number, requestedHeight: number): number { getScaleFactor(sourceWidth: number, sourceHeight: number, requestedWidth: number, requestedHeight: number): number {
const maxIntegerFactor = Math.ceil(Math.max(sourceHeight / requestedHeight, sourceWidth / requestedWidth)); const maxIntegerFactor = Math.ceil(Math.max(sourceHeight / requestedHeight, sourceWidth / requestedWidth));
let lesserOrEqualSampleSize = Math.max(1, highestOneBit(maxIntegerFactor)); let lesserOrEqualSampleSize = Math.max(1, highestOneBit(maxIntegerFactor));
@ -103,11 +119,19 @@ export class AtMost implements BaseDownsampling {
} }
greaterOrEqualSampleSize = lesserOrEqualSampleSize << (lesserOrEqualSampleSize < maxIntegerFactor ? 1 : 0) 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 { requestHeight: number): SampleSizeRounding {
//根据 AtMost 的逻辑,总是返回 MEMORY //根据 AtMost 的逻辑,总是返回 MEMORY
return SampleSizeRounding.MEMORY return SampleSizeRounding.MEMORY
@ -120,43 +144,44 @@ export class CenterInside implements BaseDownsampling {
getName() { getName() {
return "CenterInside" return "CenterInside"
} }
getScaleFactor(sourceWidth: number, sourceHeight: number, requestedWidth: number, requestedHeight: number,
getScaleFactor(sourceWidth: number, sourceHeight: number, requestedWidth: number, requestedHeight: number,downsampType:DownsampleStrategy|undefined downsampType: DownsampleStrategy
): 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
): number { ): number {
if (downsampType===DownsampleStrategy.FIT_CENTER_MEMORY) {
const widthPercentage = requestedWidth / sourceWidth let outSize: Size = {
const heightPercentage = requestedHeight / sourceHeight width: round(Math.min(1, getScale(sourceWidth, sourceHeight, requestedWidth, requestedHeight, downsampType)) * sourceWidth),
return Math.min(widthPercentage, heightPercentage) height:round(Math.min(1, getScale(sourceWidth, sourceHeight, requestedWidth, requestedHeight, downsampType)) * sourceHeight)
} else {
const maxIntegerFactor = Math.max(sourceHeight / requestedHeight, sourceWidth / requestedWidth);
const a = maxIntegerFactor === 0 ? 1 : 1 / highestOneBit(maxIntegerFactor)
return a;
} }
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 getSampleSizeType(sourceWidth: number, sourceHeight: number, requestedWidth: number, requestedHeight: number,
): SampleSizeRounding { downsampType: DownsampleStrategy
): SampleSizeRounding {
//如果缩放因子为 1表示没有缩放优先选择质量 //如果缩放因子为 1表示没有缩放优先选择质量
if (this.getScaleFactor(sourceWidth, sourceHeight, requestedWidth, requestedHeight, downsampType) === 1) { if (Math.min(1, getScale(sourceWidth, sourceHeight, requestedWidth, requestedHeight, downsampType)) === 1) {
return SampleSizeRounding.QUALITY return SampleSizeRounding.QUALITY
} }
//否则,使用 FIL_CENTER 的 SampleSizeRounding 值 //否则,使用 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 getSampleSize(sourceWidth: number, sourceHeight: number, requestedWidth: number, requestedHeight: number,
): SampleSizeRounding { downsampType: DownsampleStrategy
if (downsampType===DownsampleStrategy.CENTER_INSIDE_MEMORY) { ): SampleSizeRounding {
if (downsampType === DownsampleStrategy.CENTER_INSIDE_MEMORY) {
return SampleSizeRounding.MEMORY; return SampleSizeRounding.MEMORY;
} else { } else {
return SampleSizeRounding.QUALITY; return SampleSizeRounding.QUALITY;
@ -168,11 +193,11 @@ export enum DownsampleStrategy {
//请求尺寸大于实际尺寸不进行放大 //请求尺寸大于实际尺寸不进行放大
AT_MOST, AT_MOST,
//两边自适应内存优先 //两边自适应内存优先
FIT_CENTER_MEMORY , FIT_CENTER_MEMORY,
//两边自适应质量优先 //两边自适应质量优先
FIT_CENTER_QUALITY, FIT_CENTER_QUALITY,
//按照宽高比的最大比进行适配内存优先 //按照宽高比的最大比进行适配内存优先
CENTER_INSIDE_MEMORY , CENTER_INSIDE_MEMORY,
//按照宽高比的最大比进行适配质量优先 //按照宽高比的最大比进行适配质量优先
CENTER_INSIDE_QUALITY, CENTER_INSIDE_QUALITY,
//宽高进行等比缩放宽高里面最小的比例先放进去,然后再根据原图的缩放比去适配 //宽高进行等比缩放宽高里面最小的比例先放进去,然后再根据原图的缩放比去适配