Compare commits

...

8 Commits

Author SHA1 Message Date
tsm b0e0f97022 修改demo 2024-10-10 20:10:26 +08:00
tsm 122c01a166 修改demo 2024-10-10 20:08:32 +08:00
tsm e79557cf7c 修改demo 2024-10-10 19:57:59 +08:00
田双明 d2646b5ad4
update library/src/main/ets/downsampling/DownsampleStartegy.ets.
Signed-off-by: 田双明 <tianshuangming@h-partners.com>
2024-10-10 09:07:38 +00:00
田双明 c79046f005
update library/src/main/ets/ImageKnifeLoader.ets.
Signed-off-by: 田双明 <tianshuangming@h-partners.com>
2024-10-10 08:25:10 +00:00
田双明 5a9b251e87
update library/src/main/ets/downsampling/BaseDownsampling.ets.
Signed-off-by: 田双明 <tianshuangming@h-partners.com>
2024-10-10 08:20:28 +00:00
田双明 647b2dc1f8
update library/src/main/ets/downsampling/Downsampler.ets.
Signed-off-by: 田双明 <tianshuangming@h-partners.com>
2024-10-10 08:19:15 +00:00
田双明 ba95318b57
update library/src/main/ets/downsampling/DownsampleStartegy.ets.
Signed-off-by: 田双明 <tianshuangming@h-partners.com>
2024-10-10 08:18:16 +00:00
7 changed files with 81 additions and 163 deletions

View File

@ -126,16 +126,20 @@ struct DownSamplePage {
desiredPixelFormat: 3, desiredPixelFormat: 3,
} }
let imageInfo = await imageSource.getImageInfo() let imageInfo = await imageSource.getImageInfo()
let reqSize =
new Downsampler().calculateScaling(typeValue, imageInfo.size.width, imageInfo.size.height, 300, if (this.imageKnifeOption.downsampleOf !== DownsampleStrategy.NONE){
300, this.imageKnifeOption.downsampleOf) let reqSize =
decodingOptions = { new Downsampler().calculateScaling(typeValue, imageInfo.size.width, imageInfo.size.height, 300,
editable: true, 300, this.imageKnifeOption.downsampleOf)
desiredSize: { decodingOptions = {
width: reqSize.width, editable: true,
height: reqSize.height desiredSize: {
width: reqSize.width,
height: reqSize.height
}
} }
} }
// 创建pixelMap // 创建pixelMap
imageSource.createPixelMap(decodingOptions).then((pixelMap: image.PixelMap) => { imageSource.createPixelMap(decodingOptions).then((pixelMap: image.PixelMap) => {
this.afterSampling = pixelMap.getPixelBytesNumber() this.afterSampling = pixelMap.getPixelBytesNumber()

View File

@ -40,19 +40,9 @@ struct Index {
uri: 'pages/TestCommonImage', uri: 'pages/TestCommonImage',
}); });
}) })
Button($r('app.string.Image_Downsampling_Functionality')).margin({top:10}).onClick(()=>{ Button(this.getResourceString($r('app.string.Multiple_images')) + " + reuse + LazyForeach").margin({top:10}).onClick(()=>{
router.push({ router.push({
uri: 'pages/DownSamplePage', uri: 'pages/UserPage',
});
})
Button($r('app.string.Test_Task_error')).margin({top:10}).onClick(()=>{
router.push({
uri: 'pages/TestTaskResourcePage',
});
})
Button($r('app.string.Test_HSP')).margin({top:10}).onClick(()=>{
router.push({
uri: 'pages/TestHspPreLoadImage',
}); });
}) })
@ -62,22 +52,9 @@ struct Index {
}); });
}) })
Button($r('app.string.Test_custom_download')).margin({top:10}).onClick(()=>{ Button($r('app.string.Image_Downsampling_Functionality')).margin({top:10}).onClick(()=>{
router.push({ router.push({
uri: 'pages/TestSetCustomImagePage', uri: 'pages/DownSamplePage',
});
})
Button(this.getResourceString($r('app.string.Multiple_images')) + " + LazyForEach").margin({top:10}).onClick(()=>{
router.push({
uri: 'pages/ManyPhotoShowPage',
});
})
Button(this.getResourceString($r('app.string.Multiple_images')) + " + reuse + LazyForeach").margin({top:10}).onClick(()=>{
router.push({
uri: 'pages/UserPage',
}); });
}) })
Button($r('app.string.Display_long_image')).margin({top:10}).onClick(()=>{ Button($r('app.string.Display_long_image')).margin({top:10}).onClick(()=>{
@ -86,17 +63,25 @@ struct Index {
}); });
}) })
Button($r('app.string.Image_scaling')).margin({top:10}).onClick(()=>{ Button($r('app.string.Image_Transformation')).margin({top:10}).onClick(()=>{
router.push({ router.push({
uri: 'pages/TransformPage', uri: 'pages/ImageTransformation',
});
})
Button($r('app.string.Test_media_URL')).margin({top:10}).onClick(()=>{
router.push({
uri: 'pages/dataShareUriLoadPage',
}); });
}) })
Button(this.getResourceString($r('app.string.Message_list')) + " + List").margin({top:10}).onClick(()=>{ Button($r('app.string.Different_ObjectFit')).margin({top:10}).onClick(()=>{
router.push({ router.push({
uri: 'pages/TestImageFlash', uri: 'pages/ObjectFitPage',
}); });
}) })
Button($r('app.string.Custom_cache_key')).margin({top:10}).onClick(()=>{ Button($r('app.string.Custom_cache_key')).margin({top:10}).onClick(()=>{
router.push({ router.push({
@ -104,6 +89,39 @@ struct Index {
}); });
}) })
Button($r('app.string.Test_image_loading_success_or_failure_events')).margin({top:10}).onClick(()=>{
router.push({
uri: 'pages/LoadStatePage',
})
})
Button($r('app.string.Image_scaling')).margin({top:10}).onClick(()=>{
router.push({
uri: 'pages/TransformPage',
});
})
Button($r('app.string.Test_HSP')).margin({top:10}).onClick(()=>{
router.push({
uri: 'pages/TestHspPreLoadImage',
});
})
Button($r('app.string.Test_custom_download')).margin({top:10}).onClick(()=>{
router.push({
uri: 'pages/TestSetCustomImagePage',
});
})
Button(this.getResourceString($r('app.string.Message_list')) + " + List").margin({top:10}).onClick(()=>{
router.push({
uri: 'pages/TestImageFlash',
});
})
Button($r('app.string.Preloading_images_to_cache')).margin({top:10}).onClick(()=>{ Button($r('app.string.Preloading_images_to_cache')).margin({top:10}).onClick(()=>{
router.push({ router.push({
uri: 'pages/TestPrefetchToFileCache', uri: 'pages/TestPrefetchToFileCache',
@ -128,27 +146,7 @@ struct Index {
}); });
}) })
Button($r('app.string.Image_Transformation')).margin({top:10}).onClick(()=>{
router.push({
uri: 'pages/ImageTransformation',
});
})
Button($r('app.string.Different_ObjectFit')).margin({top:10}).onClick(()=>{
router.push({
uri: 'pages/ObjectFitPage',
});
})
Button($r('app.string.Test_image_loading_success_or_failure_events')).margin({top:10}).onClick(()=>{
router.push({
uri: 'pages/LoadStatePage',
})
})
Button($r('app.string.Test_removing_image_cache_interface')).margin({top:10}).onClick(()=>{ Button($r('app.string.Test_removing_image_cache_interface')).margin({top:10}).onClick(()=>{
router.push({ router.push({
@ -161,13 +159,11 @@ struct Index {
}); });
}) })
Button($r('app.string.Test_media_URL')).margin({top:10}).onClick(()=>{ Button($r('app.string.Test_Task_error')).margin({top:10}).onClick(()=>{
router.push({ router.push({
uri: 'pages/dataShareUriLoadPage', uri: 'pages/TestTaskResourcePage',
}); });
}) })
} }
} .width('100%') } .width('100%')
.height('100%') .height('100%')

View File

@ -388,28 +388,28 @@ export class ImageKnifeLoader {
return resBuf return resBuf
} }
static downsamplerReqSize(typeValue: string, request: RequestJobRequest, size: Size, static downsamplerReqSize(typeValue: string, request: RequestJobRequest, size: Size,
SRC?: ImageKnifeRequestSource) { SRC?: ImageKnifeRequestSource):image.DecodingOptions {
let reqSize = let reqSize =
new Downsampler().calculateScaling(typeValue, size.width, size.height, request.targetWidth, request.targetHeight, new Downsampler().calculateScaling(typeValue, size.width, size.height, request.targetWidth, request.targetHeight,
request.downsampType) request.downsampType)
if (typeValue == "svg") { if (typeValue == "svg") {
return ({ return {
editable: true, editable: true,
desiredSize: ({ desiredSize: {
height: vp2px(reqSize.height), height: vp2px(reqSize.height),
width: vp2px(reqSize.width) width: vp2px(reqSize.width)
} as Size) }
} as image.DecodingOptions) }
} else { } else {
return ({ return {
editable: request.requestSource === SRC && request.transformation !== undefined ? true : false, editable: request.requestSource === SRC && request.transformation !== undefined ? true : false,
desiredSize: ({ desiredSize:{
width: reqSize.width, width: reqSize.width,
height: reqSize.height height: reqSize.height
} as Size) }
} as image.DecodingOptions) }
} }
} }
} }

View File

@ -20,7 +20,4 @@ export interface BaseDownsampling {
getName(): string getName(): string
getScaleFactor(sourceWidth: number, sourceHeight: number, requestWidth: number, requestHeight: number,downsampType?:DownsampleStrategy): number getScaleFactor(sourceWidth: number, sourceHeight: number, requestWidth: number, requestHeight: number,downsampType?:DownsampleStrategy): number
//
getSampleSizeType(sourceWidth: number, sourceHeight: number, requestWidth: number,
requestHeight: number,downsampType?:DownsampleStrategy): SampleSizeRounding
} }

View File

@ -28,50 +28,16 @@ export class FitCenter implements BaseDownsampling {
width: round(getScale(sourceWidth, sourceHeight, requestedWidth, requestedHeight, downsampType) * sourceWidth), width: round(getScale(sourceWidth, sourceHeight, requestedWidth, requestedHeight, downsampType) * sourceWidth),
height:round(getScale(sourceWidth, sourceHeight, requestedWidth, requestedHeight, downsampType) * sourceHeight) height:round(getScale(sourceWidth, sourceHeight, requestedWidth, requestedHeight, downsampType) * sourceHeight)
} }
let scaleFactor = this.getSampleSizeType(sourceWidth, sourceHeight, requestedWidth, requestedHeight, downsampType)=== let scaleFactor = downsampType === DownsampleStrategy.FIT_CENTER_QUALITY?
SampleSizeRounding.QUALITY? Math.max(1, highestOneBit(Math.max(sourceWidth / outSize.width, sourceHeight / outSize.height))) : 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的次幂采样大小 Math.max(1, highestOneBit(Math.min(sourceWidth / outSize.width, sourceHeight / outSize.height)))//将整型的缩放因子转换为2的次幂采样大小
if (this.getSampleSizeType(sourceWidth, sourceHeight, requestedWidth, requestedHeight, downsampType)=== if (downsampType === DownsampleStrategy.FIT_CENTER_MEMORY
SampleSizeRounding.MEMORY && (scaleFactor < (1 / getScale(sourceWidth, sourceHeight, requestedWidth, requestedHeight, downsampType)))) { && (scaleFactor < (1 / getScale(sourceWidth, sourceHeight, requestedWidth, requestedHeight, downsampType)))) {
scaleFactor = scaleFactor << 1; scaleFactor = scaleFactor << 1;
} }
return scaleFactor return scaleFactor
} }
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;
}
}
}
export class None implements BaseDownsampling {
getName(): string {
return "DownsampleNone"
}
public getScaleFactor(sourceWidth: number, sourceHeight: number, requestedWidth: number,
requestedHeight: number): number {
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
}
//实现 getSampleSizeType 方法
public getSampleSizeType(sourceWidth: number, sourceHeight: number, requestedWidth: number,
requestedHeight: number): SampleSizeRounding {
return SampleSizeRounding.QUALITY
}
} }
@ -95,11 +61,6 @@ export class CenterOutside implements BaseDownsampling {
return scaleFactor return scaleFactor
} }
getSampleSizeType(sourceWidth: number, sourceHeight: number, requestedWidth: number,
requestedHeight: number): SampleSizeRounding {
return SampleSizeRounding.QUALITY;
}
} }
/*请求尺寸大于实际尺寸不进行放大,按照原图展示*/ /*请求尺寸大于实际尺寸不进行放大,按照原图展示*/
@ -118,7 +79,7 @@ export class AtMost implements BaseDownsampling {
greaterOrEqualSampleSize = lesserOrEqualSampleSize <<= 1; greaterOrEqualSampleSize = lesserOrEqualSampleSize <<= 1;
} }
greaterOrEqualSampleSize = lesserOrEqualSampleSize << (lesserOrEqualSampleSize < maxIntegerFactor ? 1 : 0) greaterOrEqualSampleSize = lesserOrEqualSampleSize << (lesserOrEqualSampleSize < maxIntegerFactor ? 1 : 0)
//返回缩放因子
let outSize: Size = { let outSize: Size = {
width: round((1 / greaterOrEqualSampleSize) * sourceWidth), width: round((1 / greaterOrEqualSampleSize) * sourceWidth),
height:round((1 / greaterOrEqualSampleSize) * sourceHeight) height:round((1 / greaterOrEqualSampleSize) * sourceHeight)
@ -129,13 +90,6 @@ export class AtMost implements BaseDownsampling {
} }
return scaleFactor return scaleFactor
} }
getSampleSizeType(sourceWidth: number, sourceHeight: number, requestedWidth: number,
requestHeight: number): SampleSizeRounding {
//根据 AtMost 的逻辑,总是返回 MEMORY
return SampleSizeRounding.MEMORY
}
} }
/*宽高进行等比缩放宽高里面最大的比例先放进去 /*宽高进行等比缩放宽高里面最大的比例先放进去
@ -147,7 +101,6 @@ export class CenterInside implements BaseDownsampling {
getScaleFactor(sourceWidth: number, sourceHeight: number, requestedWidth: number, requestedHeight: number, getScaleFactor(sourceWidth: number, sourceHeight: number, requestedWidth: number, requestedHeight: number,
downsampType: DownsampleStrategy downsampType: DownsampleStrategy
): number { ): number {
let outSize: Size = { let outSize: Size = {
width: round(Math.min(1, getScale(sourceWidth, sourceHeight, requestedWidth, requestedHeight, downsampType)) * sourceWidth), width: round(Math.min(1, getScale(sourceWidth, sourceHeight, requestedWidth, requestedHeight, downsampType)) * sourceWidth),
height:round(Math.min(1, getScale(sourceWidth, sourceHeight, requestedWidth, requestedHeight, downsampType)) * sourceHeight) height:round(Math.min(1, getScale(sourceWidth, sourceHeight, requestedWidth, requestedHeight, downsampType)) * sourceHeight)
@ -173,17 +126,7 @@ export class CenterInside implements BaseDownsampling {
return SampleSizeRounding.QUALITY return SampleSizeRounding.QUALITY
} }
//否则,使用 FIL_CENTER 的 SampleSizeRounding 值 //否则,使用 FIL_CENTER 的 SampleSizeRounding 值
return this.getSampleSize(sourceWidth, sourceHeight, requestedWidth, requestedHeight, downsampType); return downsampType === DownsampleStrategy.CENTER_INSIDE_MEMORY?SampleSizeRounding.MEMORY:SampleSizeRounding.QUALITY
}
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;
}
} }
} }

View File

@ -28,7 +28,7 @@ export enum SampleSizeRounding {
//(质量优先) //(质量优先)
QUALITY QUALITY
} }
//找出给定整数 i 中最高位的1即最左边的1所代表的值
export function highestOneBit(i: number): number { export function highestOneBit(i: number): number {
i |= (i >> 1); i |= (i >> 1);
i |= (i >> 2); i |= (i >> 2);
@ -52,6 +52,7 @@ export function getScale(sourceWidth: number, sourceHeight: number, requestedWid
} }
} }
//四舍五入
export function round(value: number): number { export function round(value: number): number {
return Math.floor(value + 0.5); return Math.floor(value + 0.5);
} }

View File

@ -18,11 +18,7 @@ import {
CenterOutside, CenterOutside,
DownsampleStrategy, DownsampleStrategy,
FitCenter, FitCenter,
None,
} from './DownsampleStartegy'; } from './DownsampleStartegy';
import { highestOneBit, round, SampleSizeRounding } from './DownsampleUtils';
export class Downsampler { export class Downsampler {
calculateScaling( calculateScaling(
typeValue: string, typeValue: string,
@ -39,22 +35,6 @@ export class Downsampler {
let downsampler = this.getDownsampler(downsampType); let downsampler = this.getDownsampler(downsampType);
let scaleFactor: number = let scaleFactor: number =
downsampler.getScaleFactor(sourceWidth, sourceHeight, requestWidth, requestHeight, downsampType);//缩放比 downsampler.getScaleFactor(sourceWidth, sourceHeight, requestWidth, requestHeight, downsampType);//缩放比
// let rounding: SampleSizeRounding =
// downsampler.getSampleSizeType(sourceWidth, sourceHeight, requestWidth, requestHeight, downsampType); //采样类型
//根据缩放比重新计算宽高
// let outSize: Size = {
// width: round(exactScaleFactor * sourceWidth),
// height:round(exactScaleFactor * sourceHeight)
// }
// let scaleFactor =
// rounding == SampleSizeRounding.QUALITY ? Math.max(sourceWidth / exactScaleFactor.width, sourceHeight / exactScaleFactor.height) :
// Math.min(sourceWidth / exactScaleFactor.width, sourceHeight / exactScaleFactor.height) //重新计算宽高比
// scaleFactor = Math.max(1, highestOneBit(scaleFactor))//将整型的缩放因子转换为2的次幂采样大小
//
// if (rounding == 0 && (scaleFactor < (1 / exactScaleFactor))) {
// scaleFactor = scaleFactor << 1;
// }
//基于上一步得出的采样大小,根据不同的图片类型,计算采样后的图片尺寸 //基于上一步得出的采样大小,根据不同的图片类型,计算采样后的图片尺寸
if (typeValue === "png") { if (typeValue === "png") {
return { return {
@ -74,14 +54,11 @@ export class Downsampler {
} }
} }
} }
getDownsampler(downsampType: DownsampleStrategy) { getDownsampler(downsampType: DownsampleStrategy) {
switch (downsampType) { switch (downsampType) {
case DownsampleStrategy.FIT_CENTER_MEMORY: case DownsampleStrategy.FIT_CENTER_MEMORY:
case DownsampleStrategy.FIT_CENTER_QUALITY: case DownsampleStrategy.FIT_CENTER_QUALITY:
return new FitCenter(); return new FitCenter();
case DownsampleStrategy.NONE:
return new None();
case DownsampleStrategy.AT_MOST: case DownsampleStrategy.AT_MOST:
return new AtMost(); return new AtMost();
case DownsampleStrategy.CENTER_INSIDE_MEMORY: case DownsampleStrategy.CENTER_INSIDE_MEMORY: