支持ico格式图片、修复错误回调无法执行reload和新增降采样默认值

Signed-off-by: zgf <zenggaofeng2@h-partners.com>
This commit is contained in:
zgf 2024-11-22 15:29:05 +08:00
parent 1ae2ce8d92
commit dac7731794
10 changed files with 74 additions and 27 deletions

View File

@ -1,3 +1,8 @@
## 3.2.0-rc.4
- Support ICO format images
- Fix bugs: call reload problem in onLoadFailed
- Provide default downsampling strategy to prevent slow loading for large images
## 3.2.0-rc.3
- Fix bug: PixelMap size exceeds the maximum value of memory cache and is not cached
- Dealing with exception scenarios where imageSource.getImageInfo return undefined

View File

@ -379,15 +379,15 @@ async function custom(context: Context, src: string | PixelMap | Resource,header
| downsampleOf | DownsampleStrategy | 降采样(可选) |
### 降采样类型
| 类型 | 相关描述 |
|---------------------|-------------------|
| NONE | 不进行降采样 |
| AT_MOST | 请求尺寸大于实际尺寸不进行放大 |
| FIT_CENTER_MEMORY | 两边自适应内存优先 |
| FIT_CENTER_QUALITY | 两边自适应质量优先 |
| CENTER_OUTSIDE_MEMORY | 宽高缩放比最大的比例,进行缩放适配内存优先 |
| CENTER_OUTSIDE_QUALITY | 宽高缩放比最大的比例,进行缩放适配质量优先 |
| AT_LEAST | 根据宽高的最小的比例,进行适配 |
| 类型 | 相关描述 |
|------------------------|-------------------|
| NONE | 不进行降采样 |
| AT_MOST | 请求尺寸大于实际尺寸不进行放大 |
| FIT_CENTER_MEMORY | 两边自适应内存优先 |
| FIT_CENTER_QUALITY | 两边自适应质量优先 |
| CENTER_INSIDE_MEMORY | 宽高缩放比最大的比例,进行缩放适配内存优先 |
| CENTER_INSIDE_QUALITY | 宽高缩放比最大的比例,进行缩放适配质量优先 |
| AT_LEAST | 根据宽高的最小的比例,进行适配 |
### ImageKnife接口

View File

@ -38,8 +38,8 @@ struct DownSamplePage {
new SamplingType(2, 'FIT_CENTER_MEMORY'),
new SamplingType(4, 'FIT_CENTER_QUALITY'),
new SamplingType(5, 'CENTER_OUTSIDE_MEMORY'),
new SamplingType(6, 'CENTER_OUTSIDE_QUALITY'),
new SamplingType(5, 'CENTER_INSIDE_MEMORY'),
new SamplingType(6, 'CENTER_INSIDE_QUALITY'),
new SamplingType(0, 'NONE'),
]
@ -86,23 +86,23 @@ struct DownSamplePage {
}
this.originalPixMap($r('app.media.pngSample'))
this.afterSamplingFunc($r('app.media.pngSample'))
} else if (value === 'CENTER_OUTSIDE_MEMORY') {
} else if (value === 'CENTER_INSIDE_MEMORY') {
this.imageKnifeOption = {
loadSrc: $r('app.media.pngSample'),
placeholderSrc: $r('app.media.loading'),
errorholderSrc: $r('app.media.app_icon'),
objectFit: ImageFit.Contain,
downsampleOf: DownsampleStrategy.CENTER_OUTSIDE_MEMORY
downsampleOf: DownsampleStrategy.CENTER_INSIDE_MEMORY
}
this.originalPixMap($r('app.media.pngSample'))
this.afterSamplingFunc($r('app.media.pngSample'))
} else if (value === 'CENTER_OUTSIDE_QUALITY') {
} else if (value === 'CENTER_INSIDE_QUALITY') {
this.imageKnifeOption = {
loadSrc: $r('app.media.pngSample'),
placeholderSrc: $r('app.media.loading'),
errorholderSrc: $r('app.media.app_icon'),
objectFit: ImageFit.Contain,
downsampleOf: DownsampleStrategy.CENTER_OUTSIDE_QUALITY
downsampleOf: DownsampleStrategy.CENTER_INSIDE_QUALITY
}
this.originalPixMap($r('app.media.pngSample'))
this.afterSamplingFunc($r('app.media.pngSample'))

View File

@ -19,6 +19,7 @@ import { ImageKnifeRequest,ImageKnife,ImageKnifeComponent } from '@ohos/libraryi
@Entry
@Component
struct ImageKnifeReload {
@State index: number = 0
aboutToAppear(): void {
NetWatchState.init()
}
@ -48,6 +49,22 @@ struct ImageKnifeReload {
}
}
}).width(200).height(200).margin({top:10})
Text("重试5次" + this.index)
ImageKnifeComponent({
imageKnifeOption:{
loadSrc:'https://img-blog.csdn.net/20140514114029140',
placeholderSrc:$r('app.media.loading'),
errorholderSrc:$r('app.media.failed'),
onLoadListener:{
onLoadFailed:(err,request) => {
this.index++
if(request != undefined && this.index < 5) {
ImageKnife.getInstance().reload(request)
}
}
}
}
}).width(200).height(200).margin({top:10})
}.width('100%')
.height('100%')
}

View File

@ -61,14 +61,14 @@ export default function SamplingTest() {
it('CENTER_OUTSIDE_MEMORY', 3, () => {
let reqSize: Size =
new Downsampler().calculateScaling('jpg', 1024, 1024, 200,
200, DownsampleStrategy.CENTER_OUTSIDE_MEMORY)
200, DownsampleStrategy.CENTER_INSIDE_MEMORY)
let req = (reqSize.width < 1024 && reqSize.height < 1024)
expect(req).assertEqual(true);
})
it('CENTER_OUTSIDE_QUALITY', 4, () => {
let reqSize: Size =
new Downsampler().calculateScaling('jpg', 1024, 1024, 200,
200, DownsampleStrategy.CENTER_OUTSIDE_QUALITY)
200, DownsampleStrategy.CENTER_INSIDE_QUALITY)
let req = (reqSize.width < 1024 && reqSize.height < 1024)
expect(req).assertEqual(true);
})

View File

@ -14,7 +14,7 @@
"main": "index.ets",
"repository": "https://gitee.com/openharmony-tpc/ImageKnife",
"type": "module",
"version": "3.2.0-rc.3",
"version": "3.2.0-rc.4",
"dependencies": {
"@ohos/gpu_transform": "^1.0.2"
},

View File

@ -259,7 +259,7 @@ export class ImageKnifeDispatcher {
caPath: currentRequest.imageKnifeOption.caPath,
targetWidth: currentRequest.componentWidth,
targetHeight: currentRequest.componentHeight,
downsampType: currentRequest.imageKnifeOption.downsampleOf == undefined ? DownsampleStrategy.NONE : currentRequest.imageKnifeOption.downsampleOf
downsampType: currentRequest.imageKnifeOption.downsampleOf == undefined ? DownsampleStrategy.DEFAULT : currentRequest.imageKnifeOption.downsampleOf
}
if(request.customGetImage == undefined) {
@ -371,6 +371,8 @@ export class ImageKnifeDispatcher {
if (pixelmap === undefined) {
LogUtil.error('ImageKnife_DataTime_getAndShowImage_CallBack.pixelmap undefined:'+currentRequest.imageKnifeOption.loadSrc + " error: " + requestJobResult.loadFail)
requestList.forEach((requestWithSource: ImageKnifeRequestWithSource) => {
requestWithSource.request.requestState = ImageKnifeRequestState.ERROR
this.executingJobMap.remove(memoryKey);
// 回调请求失败
if (requestWithSource.source === ImageKnifeRequestSource.SRC &&
requestWithSource.request.imageKnifeOption.onLoadListener?.onLoadFailed !== undefined &&
@ -389,7 +391,6 @@ export class ImageKnifeDispatcher {
}
}
});
this.executingJobMap.remove(memoryKey);
this.dispatchNextJob();
return;
}

View File

@ -126,7 +126,23 @@ export class CenterInside implements BaseDownsampling {
return SampleSizeRounding.QUALITY
}
//否则,使用 FIL_CENTER 的 SampleSizeRounding 值
return downsampType === DownsampleStrategy.CENTER_OUTSIDE_MEMORY?SampleSizeRounding.MEMORY:SampleSizeRounding.QUALITY
return downsampType === DownsampleStrategy.CENTER_INSIDE_MEMORY?SampleSizeRounding.MEMORY:SampleSizeRounding.QUALITY
}
}
// 默认值图片分辨率超过上限7680 * 4320宽高等比降为7680 * 4320
export class DefaultDownSampling implements BaseDownsampling {
getName(): string {
return 'DefaultDownSampling'
}
getScaleFactor(sourceWidth: number, sourceHeight: number, requestWidth: number, requestHeight: number, downsampType?: DownsampleStrategy | undefined): number {
let resolution_max_8k = 7680 * 4320
let resolution_source = sourceWidth * sourceHeight
if ( resolution_source <= resolution_max_8k ) {
return 1
} else {
return resolution_source / resolution_max_8k
}
}
}
@ -138,11 +154,13 @@ export enum DownsampleStrategy {
//两边自适应质量优先
FIT_CENTER_QUALITY,
//按照宽高比的最大比进行适配内存优先
CENTER_OUTSIDE_MEMORY,
CENTER_INSIDE_MEMORY,
//按照宽高比的最大比进行适配质量优先
CENTER_OUTSIDE_QUALITY,
CENTER_INSIDE_QUALITY,
//宽高进行等比缩放宽高里面最小的比例先放进去,然后再根据原图的缩放比去适配
AT_LEAST,
//不进行降采样
NONE,
// 默认值图片分辨率超过上限7680 * 4320宽高等比降为7680 * 4320
DEFAULT
}

View File

@ -18,6 +18,7 @@ import {
AtLeast,
DownsampleStrategy,
FitCenter,
DefaultDownSampling,
} from './DownsampleStartegy';
export class Downsampler {
calculateScaling(
@ -61,11 +62,13 @@ export class Downsampler {
return new FitCenter();
case DownsampleStrategy.AT_MOST:
return new AtMost();
case DownsampleStrategy.CENTER_OUTSIDE_MEMORY:
case DownsampleStrategy.CENTER_OUTSIDE_QUALITY:
case DownsampleStrategy.CENTER_INSIDE_MEMORY:
case DownsampleStrategy.CENTER_INSIDE_QUALITY:
return new CenterInside();
case DownsampleStrategy.AT_LEAST:
return new AtLeast();
case DownsampleStrategy.DEFAULT:
return new DefaultDownSampling();
default:
throw new Error('Unsupported downsampling strategy');
}

View File

@ -23,6 +23,7 @@ export class FileTypeUtil {
'bmp': [new Uint8Array([0x42, 0x4D])],
'svg': [new Uint8Array([0x3C, 0x3F, 0x78, 0x6D, 0x6C]),new Uint8Array([0x3C, 0x73, 0x76, 0x67, 0x20])],
'webp': [new Uint8Array([0x52, 0x49, 0x46, 0x46])],
'ico': [new Uint8Array([0x00,0x00,0x01,0x00])],
'tiff': [new Uint8Array([0x49, 0x20, 0x49]), new Uint8Array([0x49, 0x49, 0x2A, 0x00]), new Uint8Array([0x4D, 0x4D, 0x00, 0x2A]), new Uint8Array([0x4D, 0x4D, 0x00, 0x2B])],
// 添加更多的文件类型和特征
'heic': [new Uint8Array([0x00, 0x00, 0x00, 0x18, 0x66, 0x74, 0x79, 0x70, 0x68, 0x65, 0x69, 0x63, 0x00, 0x00, 0x00, 0x00]),new Uint8Array([0x00, 0x00, 0x00, 0x1C, 0x66, 0x74, 0x79, 0x70, 0x68, 0x65, 0x69, 0x63, 0x00, 0x00, 0x00, 0x00])],
@ -42,7 +43,8 @@ export class FileTypeUtil {
value == SupportFormat.bmp ||
value == SupportFormat.gif ||
value == SupportFormat.svg ||
value == SupportFormat.heic
value == SupportFormat.heic ||
value == SupportFormat.ico
) {
return true;
}
@ -108,5 +110,6 @@ export enum SupportFormat {
gif = 'gif',
svg = 'svg',
tiff = 'tiff',
heic = 'heic'
heic = 'heic',
ico = 'ico'
}