更新说明:

- gif解码改为imageSource解码,不在对worker强依赖
- 下载接口修改为http.requestInStream

Signed-off-by: 明月清风 <2928139825@qq.com>
This commit is contained in:
明月清风 2023-11-14 10:21:34 +08:00
parent f6f4e3c49a
commit 8f679a2293
4 changed files with 44 additions and 136 deletions

View File

@ -1,3 +1,8 @@
## 2.1.1-rc.2
- gif解码改为imageSource解码,不在对worker强依赖
- 下载接口修改为http.requestInStream
## 2.1.1-rc.1 ## 2.1.1-rc.1
- 新增自定义key参数配置 - 新增自定义key参数配置

View File

@ -14,7 +14,7 @@
"main": "index.ets", "main": "index.ets",
"repository": "https://gitee.com/openharmony-tpc/ImageKnife", "repository": "https://gitee.com/openharmony-tpc/ImageKnife",
"type": "module", "type": "module",
"version": "2.1.1-rc.1", "version": "2.1.1-rc.2",
"dependencies": { "dependencies": {
"@ohos/disklrucache": "^2.0.2-rc.0", "@ohos/disklrucache": "^2.0.2-rc.0",
"@ohos/svg": "^2.1.1-rc.0", "@ohos/svg": "^2.1.1-rc.0",

View File

@ -44,7 +44,8 @@ export class DownloadClient implements IDataFetch {
this.dataShareFileClient.loadData(request, onCompleteFunction, onErrorFunction) this.dataShareFileClient.loadData(request, onCompleteFunction, onErrorFunction)
} else { } else {
// 网络下载 // 网络下载
this.networkDownloadClient.loadData(request, onCompleteFunction, onErrorFunction) // this.networkDownloadClient.loadData(request, onCompleteFunction, onErrorFunction)
this.httpDownloadClient.loadData(request, onCompleteFunction, onErrorFunction)
} }
} }
} }

View File

@ -14,11 +14,7 @@
*/ */
import { IParseGif } from './IParseGif' import { IParseGif } from './IParseGif'
import { Dims, GIFFrame } from './GIFFrame' import { Dims, GIFFrame } from './GIFFrame'
import { LoadType } from '../../../../../../../GifWorker'
import { parseBufferToFrame } from './parse/GIFParse'
import { LogUtil } from '../../utils/LogUtil'
import image from '@ohos.multimedia.image' import image from '@ohos.multimedia.image'
import { ImageKnifeGlobal } from '../../ImageKnifeGlobal'
import { BusinessError } from '@ohos.base' import { BusinessError } from '@ohos.base'
import worker, { ErrorEvent, MessageEvents } from '@ohos.worker'; import worker, { ErrorEvent, MessageEvents } from '@ohos.worker';
@ -35,143 +31,49 @@ export interface gifBackData{
transparentIndex:number[] transparentIndex:number[]
} }
export class GIFParseImpl implements IParseGif { export class GIFParseImpl implements IParseGif {
//
parseGifs(imageinfo: ArrayBuffer, callback: (data?:GIFFrame[], err?:BusinessError|string) => void, worker?:worker.ThreadWorker,runMainThread?:boolean) { parseGifs(imageinfo: ArrayBuffer, callback: (data?:GIFFrame[], err?:BusinessError|string) => void, worker?:worker.ThreadWorker,runMainThread?:boolean) {
let resolveWorker = worker; // 硬解码流程
LogUtil.log('parseGifs resolveWorker1 is null =' + (resolveWorker == null)) let imageSource = image.createImageSource(imageinfo);
if (!resolveWorker && ImageKnifeGlobal.getInstance().getImageKnife() != undefined) { let decodeOpts: image.DecodingOptions = {
resolveWorker = ImageKnifeGlobal.getInstance().getImageKnife()?.getGifWorker(); sampleSize: 1,
editable: true,
rotate: 0
} }
LogUtil.log('parseGifs resolveWorker2 is null =' + (resolveWorker == null)) let data:GIFFrame[] = [];
imageSource.createPixelMapList(decodeOpts).then((pixelList: Array<PixelMap>) => {
if (!!resolveWorker && !runMainThread) { //sdk的api接口发生变更从.getDelayTime() 变为.getDelayTimeList()
LogUtil.log('parseGifs in worker thread!') imageSource.getDelayTimeList().then(delayTimes => {
let copyBuffer = imageinfo.slice(0); if (pixelList.length > 0) {
this.useWorkerParse(resolveWorker, copyBuffer, (data, err) => { let pixelmap1 = pixelList[0];
if (err) { pixelmap1.getImageInfo().then(imageInfo => {
callback(undefined, err) for (let i = 0; i < pixelList.length; i++) {
} else { let frame = new GIFFrame();
if (data != undefined) { frame.drawPixelMap = pixelList[i];
this.createPixelMapAll(data).then((pixelmaps) => { frame.dims = { width: imageInfo.size.width, height: imageInfo.size.height, top: 0, left: 0 }
if (pixelmaps.length == data.length) { if (i < delayTimes.length) {
for (let i = 0;i < data.length; i++) { frame.delay = delayTimes[i];
let frame = data[i]; } else {
frame['drawPixelMap'] = pixelmaps[i]; frame.delay = delayTimes[delayTimes.length - 1]
frame['patch'] = undefined;
}
callback(data, undefined)
} }
}).catch((err: BusinessError) => { data.push(frame)
callback(undefined, err) }
}) callback(data,undefined)
}else{ imageSource.release();
callback(undefined, 'GIF Parse Error callback data is undefined') }).catch((err: string) => {
} imageSource.release();
callback(undefined,err)
})
} }
}).catch((err: string) => {
imageSource.release();
callback(undefined,err)
}) })
} else { }).catch((err: string) => {
LogUtil.log('parseGifs in main thread!') imageSource.release();
let frames = parseBufferToFrame(imageinfo) callback(undefined,err)
LogUtil.log('frames length =' + frames.length)
this.createPixelMapAll(frames).then((pixelmaps) => {
if (pixelmaps.length == frames.length) {
for (let i = 0;i < frames.length; i++) {
let frame = frames[i];
frame['drawPixelMap'] = pixelmaps[i];
frame['patch'] = undefined;
}
LogUtil.log('parseGifs in main thread! callback is done!')
callback(frames, undefined)
}
}).catch((err:BusinessError) => {
LogUtil.log('parseGifs in main thread! err =' + err)
callback(undefined, err)
})
}
}
private createPixelMapAll(frames:GIFFrame[]): Promise<PixelMap[]> {
let promises:Promise<PixelMap>[] = new Array();
let filterCriteria = (item:GIFFrame) => {
if (!item['drawPixelMap']) {
return true;
}
return false;
}
frames.filter(filterCriteria, frames).flatMap<void,undefined>((frame:GIFFrame) => {
if(frame.patch != undefined) {
promises.push(image.createPixelMap(frame.patch.buffer, {
'size': {
'height': frame.dims.height as number,
'width': frame.dims.width as number
}
}))
}
}) })
return Promise.all<PixelMap>(promises)
}
private useWorkerParse(worker:worker.ThreadWorker, buffer: ArrayBuffer, callback: (data?:GIFFrame[], err?:BusinessError|string) => void) {
worker.onerror = (err:ErrorEvent)=>{
callback(undefined, err.message)
}
worker.onmessageerror = (event: MessageEvents) => {
callback(undefined, event.type)
}
worker.onexit = ()=> {
LogUtil.log('gifWork worker.onexit!')
}
worker.onmessage = (e: MessageEvents) => {
let data:Record<string,Object> = e.data;
switch (data.type as string) {
case LoadType.loadBufferByWorker:
let pages:gifBackData = (data.data as gifBackData);
if (this.gifDecodeCorrect(pages)) {
let images = this.recDecodedData(pages);
callback(images, undefined)
} else {
callback(undefined, 'GIF Worker Decoder Data Is Error!')
}
break;
default:
break
}
}
let obj:senderData = { type: LoadType.loadBufferByWorker, data: buffer }
worker.postMessage(obj, [buffer])
} }
private gifDecodeCorrect(frames:gifBackData) {
if (
(frames.patch.length == frames.dims.length) &&
(frames.patch.length == frames.delay.length) &&
(frames.patch.length == frames.disposalType.length) &&
(frames.patch.length == frames.patch.length) &&
(frames.patch.length == frames.transparentIndex.length)
) {
return true;
}
return false;
}
// 子线程数据回传处理
private recDecodedData(pages:gifBackData): GIFFrame[] {
let images:GIFFrame[] = new Array()
for (let i = 0; i < pages.patch.length; i++) {
let frame = new GIFFrame();
frame['dims'] = pages.dims[i]
frame['delay'] = pages.delay[i]
frame['disposalType'] = pages.disposalType[i]
let uint8ClampedArray = new Uint8ClampedArray(pages.patch[i])
frame['patch'] = uint8ClampedArray
frame['transparentIndex'] = pages.transparentIndex[i]
images.push(frame)
}
return images;
}
} }