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

184 lines
7.0 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* Copyright (C) 2024 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 { BaseDownsampling } from './BaseDownsampling';
import { highestOneBit, SampleSizeRounding } from './DownsampleUtils';
export class FitCenter implements BaseDownsampling {
getName() {
return "FitCenter"
}
getScaleFactor(sourceWidth: number, sourceHeight: number, requestedWidth: number, requestedHeight: number,downsampType:DownsampleStrategy
): number {
if (downsampType===DownsampleStrategy.FIT_CENTER_QUALITY) {
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;
}
}
//实现 getSampleSizeRounding 方法
getSampleSizeRounding(sourceWidth: number, sourceHeight: number, requestedWidth: number, requestedHeight: number,downsampType:DownsampleStrategy
): number {
if (downsampType===DownsampleStrategy.FIT_CENTER_QUALITY) {
return SampleSizeRounding.QUALITY;
} else {
return SampleSizeRounding.MEMORY;
}
}
}
export class None implements BaseDownsampling {
getName(): string {
return "DownsampleNone"
}
public getScaleFactor(sourceWidth: number, sourceHeight: number, requestedWidth: number,
requestedHeight: number): number {
//不进行任何下采样,缩放因子为 1
return 1;
}
//实现 getSampleSizeRounding 方法
public getSampleSizeRounding(sourceWidth: number, sourceHeight: number, requestedWidth: number,
requestedHeight: number): SampleSizeRounding {
return SampleSizeRounding.QUALITY
}
}
/*宽高进行等比缩放宽高里面最小的比例先放进去
然后再更据原图的缩放比去适配另一边*/
export class CenterOutside implements BaseDownsampling {
getName() {
return "CenterOutside"
}
getScaleFactor(sourceWidth: number, sourceHeight: number, requestedWidth: number, requestedHeight: number): number {
const widthPercentage = requestedWidth / sourceWidth;
const heightPercentage = requestedHeight / sourceHeight;
//返回宽度和高度比例中最大的值
return Math.max(widthPercentage, heightPercentage);
}
getSampleSizeRounding(sourceWidth: number, sourceHeight: number, requestedWidth: number,
requestedHeight: number): SampleSizeRounding {
//根据 CenterOutside 的逻辑,总是返回 QUALITY
return SampleSizeRounding.QUALITY;
}
}
/*请求尺寸大于实际尺寸不进行放大,按照原图展示*/
export class AtMost implements BaseDownsampling {
getName() {
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));
let greaterOrEqualSampleSize = lesserOrEqualSampleSize
if (lesserOrEqualSampleSize < maxIntegerFactor) {
greaterOrEqualSampleSize = lesserOrEqualSampleSize <<= 1;
}
greaterOrEqualSampleSize = lesserOrEqualSampleSize << (lesserOrEqualSampleSize < maxIntegerFactor ? 1 : 0)
//返回缩放因子
return 1 / greaterOrEqualSampleSize
}
getSampleSizeRounding(sourceWidth: number, sourceHeight: number, requestedWidth: number,
requestHeight: number): SampleSizeRounding {
//根据 AtMost 的逻辑,总是返回 MEMORY
return SampleSizeRounding.MEMORY
}
}
/*宽高进行等比缩放宽高里面最大的比例先放进去
然后再更据原图的缩放比去适配另一边*/
export class CenterInside implements BaseDownsampling {
getName() {
return "CenterInside"
}
getScaleFactor(sourceWidth: number, sourceHeight: number, requestedWidth: number, requestedHeight: number,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
): number {
if (downsampType===DownsampleStrategy.FIT_CENTER_QUALITY) {
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);
}
}
getSampleSizeRounding(sourceWidth: number, sourceHeight: number, requestedWidth: number, requestedHeight: number,downsampType:DownsampleStrategy
): SampleSizeRounding {
//如果缩放因子为 1表示没有缩放优先选择质量
if (this.getScaleFactor(sourceWidth, sourceHeight, requestedWidth, requestedHeight, downsampType) === 1) {
return SampleSizeRounding.QUALITY
}
//否则,使用 FIL_CENTER 的 SampleSizeRounding 值
return this.getSampleSize(sourceWidth, sourceHeight, requestedWidth, requestedHeight,downsampType);
}
getSampleSize(sourceWidth: number, sourceHeight: number, requestedWidth: number, requestedHeight: number,downsampType:DownsampleStrategy
): SampleSizeRounding {
if (downsampType===DownsampleStrategy.CENTER_INSIDE_QUALITY) {
return SampleSizeRounding.QUALITY;
} else {
return SampleSizeRounding.MEMORY;
}
}
}
export enum DownsampleStrategy {
//请求尺寸大于实际尺寸不进行放大
AT_MOST,
//两边自适应内存优先
FIT_CENTER_MEMORY ,
//两边自适应质量优先
FIT_CENTER_QUALITY,
//按照宽高比的最大比进行适配内存优先
CENTER_INSIDE_MEMORY ,
//按照宽高比的最大比进行适配质量优先
CENTER_INSIDE_QUALITY,
//宽高进行等比缩放宽高里面最小的比例先放进去,然后再根据原图的缩放比去适配
CENTER_OUTSIDE,
//不进行降采样
NONE,
}