降采样适配3.x

Signed-off-by: tsm <2418639820@qq.com>
This commit is contained in:
tsm 2024-05-22 11:35:37 +08:00
parent 8c15816eee
commit a7c8d54324
10 changed files with 86 additions and 41 deletions

View File

@ -17,8 +17,6 @@ import router from '@system.router';
@Entry @Entry
@Component @Component
struct Index { struct Index {
aboutToAppear(): void { aboutToAppear(): void {
} }
@ -26,73 +24,78 @@ struct Index {
build() { build() {
Column() { Column() {
Button("单个图片使用").onClick(()=>{ Button("单个图片使用").onClick(() => {
router.push({ router.push({
uri: 'pages/SingleImage', uri: 'pages/SingleImage',
}); });
}) })
Button("多图 + LazyForEach").margin({top:10}).onClick(()=>{ Button("下采样").margin({ top: 10 }).onClick(() => {
router.push({
uri: "pages/DownSamplePage",
});
})
Button("多图 + LazyForEach").margin({ top: 10 }).onClick(() => {
router.push({ router.push({
uri: 'pages/ManyPhotoShowPage', uri: 'pages/ManyPhotoShowPage',
}); });
}) })
Button("多图 + reuse + LazyForeach").margin({top:10}).onClick(()=>{ Button("多图 + reuse + LazyForeach").margin({ top: 10 }).onClick(() => {
router.push({ router.push({
uri: 'pages/UserPage', uri: 'pages/UserPage',
}); });
}) })
Button("长图显示").margin({top:10}).onClick(()=>{ Button("长图显示").margin({ top: 10 }).onClick(() => {
router.push({ router.push({
uri: 'pages/LongImagePage', uri: 'pages/LongImagePage',
}); });
}) })
Button("缩放图片").margin({top:10}).onClick(()=>{ Button("缩放图片").margin({ top: 10 }).onClick(() => {
router.push({ router.push({
uri: 'pages/TransformPage', uri: 'pages/TransformPage',
}); });
}) })
Button("消息+List").margin({top:10}).onClick(()=>{ Button("消息+List").margin({ top: 10 }).onClick(() => {
router.push({ router.push({
uri: 'pages/TestImageFlash', uri: 'pages/TestImageFlash',
}); });
}) })
Button("自定义缓存key").margin({top:10}).onClick(()=>{ Button("自定义缓存key").margin({ top: 10 }).onClick(() => {
router.push({ router.push({
uri: 'pages/SignatureTestPage', uri: 'pages/SignatureTestPage',
}); });
}) })
Button("预加载图片到文件缓存").margin({top:10}).onClick(()=>{ Button("预加载图片到文件缓存").margin({ top: 10 }).onClick(() => {
router.push({ router.push({
uri: 'pages/TestPrefetchToFileCache', uri: 'pages/TestPrefetchToFileCache',
}); });
}) })
Button("从缓存获取图片显示").margin({top:10}).onClick(()=>{ Button("从缓存获取图片显示").margin({ top: 10 }).onClick(() => {
router.push({ router.push({
uri: 'pages/TestIsUrlExist', uri: 'pages/TestIsUrlExist',
}); });
}) })
Button("测试单个请求头").margin({top:10}).onClick(()=>{ Button("测试单个请求头").margin({ top: 10 }).onClick(() => {
router.push({ router.push({
uri: 'pages/TestHeader', uri: 'pages/TestHeader',
}); });
}) })
Button("测试写入缓存策略").margin({top:10}).onClick(()=>{ Button("测试写入缓存策略").margin({ top: 10 }).onClick(() => {
router.push({ router.push({
uri: 'pages/TestWriteCacheStage', uri: 'pages/TestWriteCacheStage',
}); });
}) })
Button("图片变换").margin({top:10}).onClick(()=>{ Button("图片变换").margin({ top: 10 }).onClick(() => {
router.push({ router.push({
uri: 'pages/ImageTransformation', uri: 'pages/ImageTransformation',
@ -100,7 +103,7 @@ struct Index {
}) })
Button("不同的ObjectFit").margin({top:10}).onClick(()=>{ Button("不同的ObjectFit").margin({ top: 10 }).onClick(() => {
router.push({ router.push({
uri: 'pages/ObjectFitPage', uri: 'pages/ObjectFitPage',

View File

@ -14,8 +14,9 @@
"pages/TestHeader", "pages/TestHeader",
"pages/ImageTransformation", "pages/ImageTransformation",
"pages/ObjectFitPage", "pages/ObjectFitPage",
"pages/TestWriteCacheStage",
"pages/LoadStatePage", "pages/LoadStatePage",
"pages/TestRemoveCache" "pages/TestRemoveCache",
"pages/TestWriteCacheStage",
"pages/DownSamplePage"
] ]
} }

View File

@ -1,6 +1,7 @@
{ {
"modelVersion": "5.0.0", "modelVersion": "5.0.0",
"dependencies": { "dependencies": {
"@ohos/hvigor-ohos-plugin": "4.1.2"
}, },
"execution": { "execution": {
// "analyze": "default", /* Define the build analyze mode. Value: [ "default" | "verbose" | false ]. Default: "default" */ // "analyze": "default", /* Define the build analyze mode. Value: [ "default" | "verbose" | false ]. Default: "default" */

View File

@ -1,5 +1,6 @@
export default class BuildProfile { export default class BuildProfile {
static readonly HAR_VERSION = '3.0.0-rc.0'; static readonly HAR_VERSION = '3.0.0-rc.4';
static readonly BUILD_MODE_NAME = 'debug'; static readonly BUILD_MODE_NAME = 'debug';
static readonly DEBUG = true; static readonly DEBUG = true;
static readonly TARGET_NAME = 'default';
} }

View File

@ -22,4 +22,6 @@ export { BrightnessTransformation } from './src/main/ets/transform/BrightnessTra
export { BlurTransformation } from './src/main/ets/transform/BlurTransformation' export { BlurTransformation } from './src/main/ets/transform/BlurTransformation'
export { DownsampleStrategy } from './src/main/ets/downsampling/DownsampleStartegy'

View File

@ -39,6 +39,9 @@ import {
RequestJobRequest RequestJobRequest
} from './model/ImageKnifeData' } from './model/ImageKnifeData'
import { combineArrayBuffers } from './model/utils'; import { combineArrayBuffers } from './model/utils';
import { BusinessError } from '@kit.BasicServicesKit';
import { Downsampler } from './downsampling/Downsampler'
import { DownsampleStrategy } from './downsampling/DownsampleStartegy';
export class ImageKnifeDispatcher { export class ImageKnifeDispatcher {
// 最大并发 // 最大并发
@ -144,7 +147,12 @@ export class ImageKnifeDispatcher {
.isFileCacheInit() ? currentRequest.imageKnifeOption.writeCacheStrategy : CacheStrategy.Memory, // 未初始化文件缓存时,不写文件缓存 .isFileCacheInit() ? currentRequest.imageKnifeOption.writeCacheStrategy : CacheStrategy.Memory, // 未初始化文件缓存时,不写文件缓存
engineKey: this.engineKey, engineKey: this.engineKey,
signature: currentRequest.imageKnifeOption.signature, signature: currentRequest.imageKnifeOption.signature,
requestSource requestSource,
targetWidth: currentRequest.componentWidth,
targetHeight: currentRequest.componentHeight,
downsampType: currentRequest.imageKnifeOption.downsampling,
autoResize:currentRequest.imageKnifeOption.autoResize
} }
// 启动线程下载和解码主图 // 启动线程下载和解码主图
let task = new taskpool.Task(requestJob, request) let task = new taskpool.Task(requestJob, request)
@ -404,7 +412,6 @@ async function requestJob(request: RequestJobRequest): Promise<RequestJobResult
} }
} }
if (resBuf == undefined) { if (resBuf == undefined) {
return { return {
pixelMap: undefined, pixelMap: undefined,
@ -418,7 +425,6 @@ async function requestJob(request: RequestJobRequest): Promise<RequestJobResult
let typeValue = fileTypeUtil.getFileType(resBuf); let typeValue = fileTypeUtil.getFileType(resBuf);
if (typeValue === 'gif' || typeValue === 'webp') { if (typeValue === 'gif' || typeValue === 'webp') {
let base64Help = new util.Base64Helper() let base64Help = new util.Base64Helper()
let base64str = "data:image/" + typeValue + ";base64," + base64Help.encodeToStringSync(new Uint8Array(resBuf)) let base64str = "data:image/" + typeValue + ";base64," + base64Help.encodeToStringSync(new Uint8Array(resBuf))
return { return {
pixelMap: base64str, pixelMap: base64str,
@ -426,10 +432,19 @@ async function requestJob(request: RequestJobRequest): Promise<RequestJobResult
fileKey: fileKey fileKey: fileKey
}; };
} }
let autoResizes = request.autoResize
let imageSource: image.ImageSource = image.createImageSource(resBuf); let imageSource: image.ImageSource = image.createImageSource(resBuf);
let decodingOptions: image.DecodingOptions = { let imageInfo = await imageSource.getImageInfo()
let a = new Downsampler().calculateScaling(typeValue, imageInfo.size.width, imageInfo.size.height, request.targetWidth,
request.targetHeight, request.downsampType,autoResizes)
let decodingOptions: image.DecodingOptions = request.downsampType === DownsampleStrategy.NONE ? {
editable: true, editable: true,
} : {
editable: true,
desiredSize: {
width: a.targetWidth,
height: a.targetHeight
}
} }
let resPixelmap: PixelMap | undefined = undefined let resPixelmap: PixelMap | undefined = undefined

View File

@ -13,14 +13,16 @@
* limitations under the License. * limitations under the License.
*/ */
import taskpool from '@ohos.taskpool'; import taskpool from '@ohos.taskpool';
import common from '@ohos.app.ability.common' import common from '@ohos.app.ability.common';
import { CacheStrategy } from './model/ImageKnifeData'; import { CacheStrategy } from './model/ImageKnifeData';
import { PixelMapTransformation } from './transform/PixelMapTransformation'; import { PixelMapTransformation } from './transform/PixelMapTransformation';
import { DownsampleStrategy } from './downsampling/DownsampleStartegy';
export interface HeaderOptions { export interface HeaderOptions {
key: string; key: string;
value: Object; value: Object;
} }
@Observed @Observed
export class ImageKnifeOption { export class ImageKnifeOption {
// 主图资源 // 主图资源
@ -29,31 +31,22 @@ export class ImageKnifeOption {
placeholderSrc?: string | PixelMap | Resource; placeholderSrc?: string | PixelMap | Resource;
// 失败占位图 // 失败占位图
errorholderSrc?: string | PixelMap | Resource; errorholderSrc?: string | PixelMap | Resource;
headerOption?: Array<HeaderOptions>; headerOption?: Array<HeaderOptions>;
// 自定义缓存关键字 // 自定义缓存关键字
signature?: string; signature?: string;
// 主图填充效果 // 主图填充效果
objectFit?: ImageFit objectFit?: ImageFit
// 占位图填充效果 // 占位图填充效果
placeholderObjectFit?: ImageFit placeholderObjectFit?: ImageFit
// 错误图填充效果 // 错误图填充效果
errorholderObjectFit?: ImageFit errorholderObjectFit?: ImageFit
customGetImage?: (context: Context, src: string | PixelMap | Resource) => Promise<ArrayBuffer | undefined> customGetImage?: (context: Context, src: string | PixelMap | Resource) => Promise<ArrayBuffer | undefined>
border?: BorderOptions border?: BorderOptions
// 缓存策略 // 缓存策略
writeCacheStrategy?: CacheStrategy writeCacheStrategy?: CacheStrategy
// 仅使用缓存加载数据 // 仅使用缓存加载数据
onlyRetrieveFromCache?: boolean = false; onlyRetrieveFromCache?: boolean = false;
priority?: taskpool.Priority = taskpool.Priority.LOW
priority? : taskpool.Priority = taskpool.Priority.LOW
context?: common.UIAbilityContext; context?: common.UIAbilityContext;
progressListener?: (progress: number)=>void; progressListener?: (progress: number)=>void;
@ -61,6 +54,11 @@ export class ImageKnifeOption {
transformation?: PixelMapTransformation transformation?: PixelMapTransformation
onLoadListener?: OnLoadCallBack | undefined; onLoadListener?: OnLoadCallBack | undefined;
progressListener?: (progress: number) => void;
transformation?: PixelMapTransformation;
// 下采样
downsampling?: DownsampleStrategy = DownsampleStrategy.NONE
autoResize?:boolean
constructor() { constructor() {
} }

View File

@ -15,7 +15,7 @@
import { ImageKnifeOption } from './ImageKnifeOption'; import { ImageKnifeOption } from './ImageKnifeOption';
import common from '@ohos.app.ability.common'; import common from '@ohos.app.ability.common';
import { ImageKnifeRequestSource } from './model/ImageKnifeData'; import { ImageKnifeRequestSource } from './model/ImageKnifeData';
import { DownsampleStrategy } from './downsampling/DownsampleStartegy';
export class ImageKnifeRequest { export class ImageKnifeRequest {
requestState: ImageKnifeRequestState = ImageKnifeRequestState.PROGRESS requestState: ImageKnifeRequestState = ImageKnifeRequestState.PROGRESS
@ -25,20 +25,29 @@ export class ImageKnifeRequest {
context: common.UIAbilityContext context: common.UIAbilityContext
ImageKnifeRequestCallback: ImageKnifeRequestCallback ImageKnifeRequestCallback: ImageKnifeRequestCallback
componentVersion: number = 0 componentVersion: number = 0
headers: Map<string,Object> = new Map<string,Object>() headers: Map<string, Object> = new Map<string, Object>()
downsampType?: DownsampleStrategy
autoResizes?:boolean
constructor(option: ImageKnifeOption, constructor(option: ImageKnifeOption,
uIAbilityContext: common.UIAbilityContext, uIAbilityContext: common.UIAbilityContext,
width: number, width: number,
height: number, height: number,
version: number, version: number,
ImageKnifeRequestCallback: ImageKnifeRequestCallback) { ImageKnifeRequestCallback: ImageKnifeRequestCallback,
downsampType?: DownsampleStrategy,
autoResizes?:boolean
) {
this.imageKnifeOption = option this.imageKnifeOption = option
this.context = uIAbilityContext this.context = uIAbilityContext
this.componentWidth = width this.componentWidth = width
this.componentHeight = height this.componentHeight = height
this.componentVersion = version this.componentVersion = version
this.ImageKnifeRequestCallback = ImageKnifeRequestCallback this.ImageKnifeRequestCallback = ImageKnifeRequestCallback
this.downsampType = downsampType
this.autoResizes = autoResizes
} }
// RequestOption调用header对于的方法 // RequestOption调用header对于的方法
addHeader(key: string, value: Object) { addHeader(key: string, value: Object) {
this.headers.set(key, value); this.headers.set(key, value);
@ -63,5 +72,5 @@ export enum ImageKnifeRequestState {
export interface ImageKnifeRequestCallback { export interface ImageKnifeRequestCallback {
showPixelMap: (version: number, pixelMap: PixelMap | string , requestSource: ImageKnifeRequestSource) => void; showPixelMap: (version: number, pixelMap: PixelMap | string, requestSource: ImageKnifeRequestSource) => void;
} }

View File

@ -18,6 +18,7 @@ import common from '@ohos.app.ability.common';
import { ImageKnife } from '../ImageKnife'; import { ImageKnife } from '../ImageKnife';
import { LogUtil } from '../utils/LogUtil'; import { LogUtil } from '../utils/LogUtil';
import { ImageKnifeRequestSource } from '../model/ImageKnifeData'; import { ImageKnifeRequestSource } from '../model/ImageKnifeData';
import { Downsampler } from '../downsampling/Downsampler';
@Component @Component
export struct ImageKnifeComponent { export struct ImageKnifeComponent {
@ -33,6 +34,8 @@ export struct ImageKnifeComponent {
private currentHeight: number = 0 private currentHeight: number = 0
private componentVersion: number = 0 private componentVersion: number = 0
private currentContext: common.UIAbilityContext | undefined = undefined private currentContext: common.UIAbilityContext | undefined = undefined
private targetHeight: number =0
private targetWidth: number =0
aboutToAppear(): void { aboutToAppear(): void {
//闪动问题失效,注释相应代码后续修复 //闪动问题失效,注释相应代码后续修复
@ -82,7 +85,10 @@ export struct ImageKnifeComponent {
ImageKnife.getInstance().execute(this.getRequest(this.currentWidth, this.currentHeight)) ImageKnife.getInstance().execute(this.getRequest(this.currentWidth, this.currentHeight))
} }
} }
}) }).sourceSize({
width:250,
height:250
})
} }
watchImageKnifeOption() { watchImageKnifeOption() {
@ -116,8 +122,9 @@ export struct ImageKnifeComponent {
} }
this.pixelMap = pixelMap this.pixelMap = pixelMap
if (typeof this.pixelMap !== 'string') { if (typeof this.pixelMap !== 'string') {
let info =await this.pixelMap.getImageInfo()
//图片自适应处理
if (this.imageKnifeOption.objectFit === ImageFit.Auto) { if (this.imageKnifeOption.objectFit === ImageFit.Auto) {
let info = await this.pixelMap.getImageInfo()
this.adaptiveWidth = this.currentWidth this.adaptiveWidth = this.currentWidth
this.adaptiveHeight = info.size.height * this.currentWidth / info.size.width this.adaptiveHeight = info.size.height * this.currentWidth / info.size.width

View File

@ -17,6 +17,7 @@ import { ImageKnifeRequest } from '../ImageKnifeRequest'
import { IEngineKey } from '../key/IEngineKey' import { IEngineKey } from '../key/IEngineKey'
import { PixelMapTransformation } from '../transform/PixelMapTransformation' import { PixelMapTransformation } from '../transform/PixelMapTransformation'
import common from '@ohos.app.ability.common'; import common from '@ohos.app.ability.common';
import { DownsampleStrategy} from '../downsampling/DownsampleStartegy'
export interface ImageKnifeData { export interface ImageKnifeData {
source: PixelMap | string, source: PixelMap | string,
@ -60,7 +61,10 @@ export interface RequestJobResult {
fileKey: string fileKey: string
loadFail?: string, loadFail?: string,
} }
export interface targetCcaleType {
width: number,
height: number
}
/** /**
* request子线程处理时的请求参数 * request子线程处理时的请求参数
*/ */
@ -76,5 +80,9 @@ export interface RequestJobRequest {
writeCacheStrategy?: CacheStrategy writeCacheStrategy?: CacheStrategy
signature?: string signature?: string
engineKey: IEngineKey engineKey: IEngineKey
targetWidth:number
targetHeight: number
downsampType?:DownsampleStrategy
autoResize?:boolean
} }