降采样优化

Signed-off-by: tsm <tianshuangming@h-partners.com>
This commit is contained in:
tsm 2024-09-05 11:37:17 +08:00
parent 483803a302
commit 60df15c3ea
6 changed files with 52 additions and 54 deletions

View File

@ -12,6 +12,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import { DownsampleStrategy } from '@ohos/imageknife';
import { IEngineKey, ImageKnifeOption, PixelMapTransformation,SparkMD5 ,ImageKnifeRequestSource} from '@ohos/libraryimageknife'; import { IEngineKey, ImageKnifeOption, PixelMapTransformation,SparkMD5 ,ImageKnifeRequestSource} from '@ohos/libraryimageknife';
//全局自定义key demo //全局自定义key demo
@ -35,6 +36,10 @@ export class CustomEngineKeyImpl implements IEngineKey {
if (imageKnifeOption.transformation) { if (imageKnifeOption.transformation) {
key += "transformation=" + this.getTransformation(imageKnifeOption.transformation) + ";" key += "transformation=" + this.getTransformation(imageKnifeOption.transformation) + ";"
} }
if ((imageKnifeOption.downsampleOf !== DownsampleStrategy.NONE && imageKnifeOption.downsampleOf !== undefined)) {
key += "downsampleOf" + imageKnifeOption.downsampleOf +"width="+width+"height="+ height
}
} }
return key return key
} }

View File

@ -45,24 +45,24 @@ struct DownSamplePage {
updateImageKnifeOption(value: string) { updateImageKnifeOption(value: string) {
if (value === 'NONE') { if (value === 'NONE') {
this.imageKnifeOption =new ImageKnifeOption( { this.imageKnifeOption =new ImageKnifeOption( {
loadSrc: $r('app.media.jpgSample'), loadSrc: $r('app.media.pngSample'),
placeholderSrc: $r("app.media.loading"), placeholderSrc: $r("app.media.loading"),
errorholderSrc: $r("app.media.app_icon"), errorholderSrc: $r("app.media.app_icon"),
objectFit: ImageFit.Contain, objectFit: ImageFit.Contain,
downsampleOf: DownsampleStrategy.NONE downsampleOf: DownsampleStrategy.NONE
}) })
this.originalPixMap($r('app.media.jpgSample')) this.originalPixMap($r('app.media.pngSample'))
this.afterSamplingFunc($r('app.media.jpgSample')) this.afterSamplingFunc($r('app.media.pngSample'))
} else if (value === 'AT_MOST') { } else if (value === 'AT_MOST') {
this.imageKnifeOption =new ImageKnifeOption( { this.imageKnifeOption =new ImageKnifeOption( {
loadSrc: $r('app.media.svgSample'), loadSrc: $r('app.media.pngSample'),
placeholderSrc: $r("app.media.loading"), placeholderSrc: $r("app.media.loading"),
errorholderSrc: $r("app.media.app_icon"), errorholderSrc: $r("app.media.app_icon"),
objectFit: ImageFit.Contain, objectFit: ImageFit.Contain,
downsampleOf: DownsampleStrategy.AT_MOST downsampleOf: DownsampleStrategy.AT_MOST
}) })
this.originalPixMap($r('app.media.svgSample')) this.originalPixMap($r('app.media.pngSample'))
this.afterSamplingFunc($r('app.media.svgSample')) this.afterSamplingFunc($r('app.media.pngSample'))
} else if (value === 'FIT_CENTER_MEMORY') { } else if (value === 'FIT_CENTER_MEMORY') {
this.imageKnifeOption =new ImageKnifeOption( { this.imageKnifeOption =new ImageKnifeOption( {
loadSrc: $r('app.media.pngSample'), loadSrc: $r('app.media.pngSample'),
@ -87,35 +87,35 @@ struct DownSamplePage {
} }
else if (value === 'CENTER_INSIDE_MEMORY') { else if (value === 'CENTER_INSIDE_MEMORY') {
this.imageKnifeOption = new ImageKnifeOption({ this.imageKnifeOption = new ImageKnifeOption({
loadSrc: $r('app.media.jpgSample1'), loadSrc: $r('app.media.pngSample'),
placeholderSrc: $r("app.media.loading"), placeholderSrc: $r("app.media.loading"),
errorholderSrc: $r("app.media.app_icon"), errorholderSrc: $r("app.media.app_icon"),
objectFit: ImageFit.Contain, objectFit: ImageFit.Contain,
downsampleOf: DownsampleStrategy.CENTER_INSIDE_MEMORY downsampleOf: DownsampleStrategy.CENTER_INSIDE_MEMORY
}) })
this.originalPixMap($r('app.media.jpgSample1')) this.originalPixMap($r('app.media.pngSample'))
this.afterSamplingFunc($r('app.media.jpgSample1')) this.afterSamplingFunc($r('app.media.pngSample'))
} else if (value === 'CENTER_INSIDE_QUALITY') { } else if (value === 'CENTER_INSIDE_QUALITY') {
this.imageKnifeOption = new ImageKnifeOption({ this.imageKnifeOption = new ImageKnifeOption({
loadSrc: $r('app.media.jpgSample1'), loadSrc: $r('app.media.pngSample'),
placeholderSrc: $r("app.media.loading"), placeholderSrc: $r("app.media.loading"),
errorholderSrc: $r("app.media.app_icon"), errorholderSrc: $r("app.media.app_icon"),
objectFit: ImageFit.Contain, objectFit: ImageFit.Contain,
downsampleOf: DownsampleStrategy.CENTER_INSIDE_QUALITY downsampleOf: DownsampleStrategy.CENTER_INSIDE_QUALITY
}) })
this.originalPixMap($r('app.media.jpgSample1')) this.originalPixMap($r('app.media.pngSample'))
this.afterSamplingFunc($r('app.media.jpgSample1')) this.afterSamplingFunc($r('app.media.pngSample'))
} }
else { else {
this.imageKnifeOption = new ImageKnifeOption({ this.imageKnifeOption = new ImageKnifeOption({
loadSrc: $r('app.media.jpgSample2'), loadSrc: $r('app.media.pngSample'),
placeholderSrc: $r("app.media.loading"), placeholderSrc: $r("app.media.loading"),
errorholderSrc: $r("app.media.app_icon"), errorholderSrc: $r("app.media.app_icon"),
objectFit: ImageFit.Contain, objectFit: ImageFit.Contain,
downsampleOf: DownsampleStrategy.CENTER_OUTSIDE downsampleOf: DownsampleStrategy.CENTER_OUTSIDE
}) })
this.originalPixMap($r('app.media.jpgSample2')) this.originalPixMap($r('app.media.pngSample'))
this.afterSamplingFunc($r('app.media.jpgSample2')) this.afterSamplingFunc($r('app.media.pngSample'))
} }
} }

View File

@ -125,7 +125,7 @@ export class ImageKnifeOption {
onComplete?:(event:EventImage | undefined) => void onComplete?:(event:EventImage | undefined) => void
drawingColorFilter?: ColorFilter | drawing.ColorFilter drawingColorFilter?: ColorFilter | drawing.ColorFilter
// 下采样 // 下采样
downsampleOf?: DownsampleStrategy = DownsampleStrategy.NONE @Trace downsampleOf?: DownsampleStrategy = DownsampleStrategy.NONE
constructor(option?:ImageOption) { constructor(option?:ImageOption) {
this.loadSrc = option?.loadSrc == undefined ? "" : option?.loadSrc this.loadSrc = option?.loadSrc == undefined ? "" : option?.loadSrc

View File

@ -38,7 +38,7 @@ export struct ImageKnifeComponent {
@Param imageKnifeOption: ImageKnifeOption = new ImageKnifeOption(); @Param imageKnifeOption: ImageKnifeOption = new ImageKnifeOption();
@Monitor('imageKnifeOption', @Monitor('imageKnifeOption',
"imageKnifeOption.loadSrc","imageKnifeOption.signature","imageKnifeOption.transformation","imageKnifeOption.border","imageKnifeOption.objectFit") "imageKnifeOption.loadSrc","imageKnifeOption.signature","imageKnifeOption.transformation","imageKnifeOption.border","imageKnifeOption.objectFit",'imageKnifeOption.downsampleOf')
watchImageKnifeOption() { watchImageKnifeOption() {
this.clearLastRequest() this.clearLastRequest()
this.componentVersion++ this.componentVersion++

View File

@ -22,7 +22,7 @@ export class FitCenter implements BaseDownsampling {
getScaleFactor(sourceWidth: number, sourceHeight: number, requestedWidth: number, requestedHeight: number,downsampType:DownsampleStrategy getScaleFactor(sourceWidth: number, sourceHeight: number, requestedWidth: number, requestedHeight: number,downsampType:DownsampleStrategy
): number { ): number {
if (downsampType===DownsampleStrategy.FIT_CENTER_QUALITY) { if (downsampType===DownsampleStrategy.FIT_CENTER_MEMORY) {
const widthPercentage = requestedWidth / sourceWidth const widthPercentage = requestedWidth / sourceWidth
const heightPercentage = requestedHeight / sourceHeight const heightPercentage = requestedHeight / sourceHeight
return Math.min(widthPercentage, heightPercentage) return Math.min(widthPercentage, heightPercentage)
@ -82,7 +82,6 @@ export class CenterOutside implements BaseDownsampling {
getSampleSizeRounding(sourceWidth: number, sourceHeight: number, requestedWidth: number, getSampleSizeRounding(sourceWidth: number, sourceHeight: number, requestedWidth: number,
requestedHeight: number): SampleSizeRounding { requestedHeight: number): SampleSizeRounding {
//根据 CenterOutside 的逻辑,总是返回 QUALITY
return SampleSizeRounding.QUALITY; return SampleSizeRounding.QUALITY;
} }
} }
@ -158,10 +157,10 @@ export class CenterInside implements BaseDownsampling {
getSampleSize(sourceWidth: number, sourceHeight: number, requestedWidth: number, requestedHeight: number,downsampType:DownsampleStrategy getSampleSize(sourceWidth: number, sourceHeight: number, requestedWidth: number, requestedHeight: number,downsampType:DownsampleStrategy
): SampleSizeRounding { ): SampleSizeRounding {
if (downsampType===DownsampleStrategy.CENTER_INSIDE_QUALITY) { if (downsampType===DownsampleStrategy.CENTER_INSIDE_MEMORY) {
return SampleSizeRounding.QUALITY;
} else {
return SampleSizeRounding.MEMORY; return SampleSizeRounding.MEMORY;
} else {
return SampleSizeRounding.QUALITY;
} }
} }
} }

View File

@ -69,38 +69,32 @@ export class Downsampler {
} }
let exactScaleFactor: number | undefined let exactScaleFactor: number | undefined
let rounding: SampleSizeRounding | undefined let rounding: SampleSizeRounding | undefined
switch (downsampType) { if(downsampType===DownsampleStrategy.FIT_CENTER_MEMORY || downsampType===DownsampleStrategy.FIT_CENTER_QUALITY){
case DownsampleStrategy.FIT_CENTER_MEMORY || DownsampleStrategy.FIT_CENTER_QUALITY:
exactScaleFactor = new FitCenter() exactScaleFactor = new FitCenter()
.getScaleFactor(orientedSourceWidth, orientedSourceHeight, targetWidth, targetHeight,downsampType) .getScaleFactor(orientedSourceWidth, orientedSourceHeight, targetWidth, targetHeight,downsampType)
rounding = new FitCenter() rounding = new FitCenter()
.getSampleSizeRounding(orientedSourceWidth, orientedSourceHeight, targetWidth, targetHeight,downsampType) .getSampleSizeRounding(orientedSourceWidth, orientedSourceHeight, targetWidth, targetHeight,downsampType)
break;
case DownsampleStrategy.NONE: }else if(downsampType===DownsampleStrategy.NONE){
exactScaleFactor = new None() exactScaleFactor = new None()
.getScaleFactor(orientedSourceWidth, orientedSourceHeight, targetWidth, targetHeight) .getScaleFactor(orientedSourceWidth, orientedSourceHeight, targetWidth, targetHeight)
rounding = new None() rounding = new None()
.getSampleSizeRounding(orientedSourceWidth, orientedSourceHeight, targetWidth, targetHeight) .getSampleSizeRounding(orientedSourceWidth, orientedSourceHeight, targetWidth, targetHeight)
break }else if( downsampType===DownsampleStrategy.AT_MOST){
case DownsampleStrategy.AT_MOST:
exactScaleFactor = new AtMost() exactScaleFactor = new AtMost()
.getScaleFactor(orientedSourceWidth, orientedSourceHeight, targetWidth, targetHeight) .getScaleFactor(orientedSourceWidth, orientedSourceHeight, targetWidth, targetHeight)
rounding = new AtMost() rounding = new AtMost()
.getSampleSizeRounding(orientedSourceWidth, orientedSourceHeight, targetWidth, targetHeight) .getSampleSizeRounding(orientedSourceWidth, orientedSourceHeight, targetWidth, targetHeight)
break }else if(downsampType===DownsampleStrategy.CENTER_INSIDE_MEMORY || downsampType===DownsampleStrategy.CENTER_INSIDE_QUALITY){
case DownsampleStrategy.CENTER_INSIDE_MEMORY || DownsampleStrategy.CENTER_INSIDE_QUALITY:
exactScaleFactor = new CenterInside() exactScaleFactor = new CenterInside()
.getScaleFactor(orientedSourceWidth, orientedSourceHeight, targetWidth, targetHeight,downsampType) .getScaleFactor(orientedSourceWidth, orientedSourceHeight, targetWidth, targetHeight,downsampType)
rounding = new CenterInside() rounding = new CenterInside()
.getSampleSizeRounding(orientedSourceWidth, orientedSourceHeight, targetWidth, targetHeight,downsampType) .getSampleSizeRounding(orientedSourceWidth, orientedSourceHeight, targetWidth, targetHeight,downsampType)
break }else if(downsampType===DownsampleStrategy.CENTER_OUTSIDE){
case DownsampleStrategy.CENTER_OUTSIDE:
exactScaleFactor = new CenterOutside() exactScaleFactor = new CenterOutside()
.getScaleFactor(orientedSourceWidth, orientedSourceHeight, targetWidth, targetHeight) .getScaleFactor(orientedSourceWidth, orientedSourceHeight, targetWidth, targetHeight)
rounding = new CenterOutside() rounding = new CenterOutside()
.getSampleSizeRounding(orientedSourceWidth, orientedSourceHeight, targetWidth, targetHeight) .getSampleSizeRounding(orientedSourceWidth, orientedSourceHeight, targetWidth, targetHeight)
break
} }
if (exactScaleFactor==undefined|| exactScaleFactor <= 0 ) { if (exactScaleFactor==undefined|| exactScaleFactor <= 0 ) {
throw new Error("Cannot round with exactScaleFactor"); throw new Error("Cannot round with exactScaleFactor");
@ -116,7 +110,7 @@ export class Downsampler {
Math.min(widthScaleFactor, heightScaleFactor) //将整型的缩放因子转换为2的次幂采样大小 Math.min(widthScaleFactor, heightScaleFactor) //将整型的缩放因子转换为2的次幂采样大小
let powerOfTwoSampleSize: number = scaleFactor; let powerOfTwoSampleSize: number = scaleFactor;
powerOfTwoSampleSize = Math.max(1, highestOneBit(scaleFactor)) powerOfTwoSampleSize = Math.max(1, highestOneBit(scaleFactor))
if (rounding == 1 && (powerOfTwoSampleSize < (1 / exactScaleFactor))) { if (rounding == 0 && (powerOfTwoSampleSize < (1 / exactScaleFactor))) {
powerOfTwoSampleSize = powerOfTwoSampleSize << 1; powerOfTwoSampleSize = powerOfTwoSampleSize << 1;
} }
//基于上一步得出的采样大小,根据不同的图片类型,计算采样后的图片尺寸 //基于上一步得出的采样大小,根据不同的图片类型,计算采样后的图片尺寸