更新说明:

- 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
- 新增自定义key参数配置

View File

@ -14,7 +14,7 @@
"main": "index.ets",
"repository": "https://gitee.com/openharmony-tpc/ImageKnife",
"type": "module",
"version": "2.1.1-rc.1",
"version": "2.1.1-rc.2",
"dependencies": {
"@ohos/disklrucache": "^2.0.2-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)
} 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 { 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 { ImageKnifeGlobal } from '../../ImageKnifeGlobal'
import { BusinessError } from '@ohos.base'
import worker, { ErrorEvent, MessageEvents } from '@ohos.worker';
@ -35,143 +31,49 @@ export interface gifBackData{
transparentIndex:number[]
}
export class GIFParseImpl implements IParseGif {
//
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))
if (!resolveWorker && ImageKnifeGlobal.getInstance().getImageKnife() != undefined) {
resolveWorker = ImageKnifeGlobal.getInstance().getImageKnife()?.getGifWorker();
// 硬解码流程
let imageSource = image.createImageSource(imageinfo);
let decodeOpts: image.DecodingOptions = {
sampleSize: 1,
editable: true,
rotate: 0
}
LogUtil.log('parseGifs resolveWorker2 is null =' + (resolveWorker == null))
if (!!resolveWorker && !runMainThread) {
LogUtil.log('parseGifs in worker thread!')
let copyBuffer = imageinfo.slice(0);
this.useWorkerParse(resolveWorker, copyBuffer, (data, err) => {
if (err) {
callback(undefined, err)
} else {
if (data != undefined) {
this.createPixelMapAll(data).then((pixelmaps) => {
if (pixelmaps.length == data.length) {
for (let i = 0;i < data.length; i++) {
let frame = data[i];
frame['drawPixelMap'] = pixelmaps[i];
frame['patch'] = undefined;
}
callback(data, undefined)
}
}).catch((err: BusinessError) => {
callback(undefined, err)
})
}else{
callback(undefined, 'GIF Parse Error callback data is undefined')
}
}
})
} else {
LogUtil.log('parseGifs in main thread!')
let frames = parseBufferToFrame(imageinfo)
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 data:GIFFrame[] = [];
imageSource.createPixelMapList(decodeOpts).then((pixelList: Array<PixelMap>) => {
//sdk的api接口发生变更从.getDelayTime() 变为.getDelayTimeList()
imageSource.getDelayTimeList().then(delayTimes => {
if (pixelList.length > 0) {
let pixelmap1 = pixelList[0];
pixelmap1.getImageInfo().then(imageInfo => {
for (let i = 0; i < pixelList.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)
frame.drawPixelMap = pixelList[i];
frame.dims = { width: imageInfo.size.width, height: imageInfo.size.height, top: 0, left: 0 }
if (i < delayTimes.length) {
frame.delay = delayTimes[i];
} else {
frame.delay = delayTimes[delayTimes.length - 1]
}
return images;
data.push(frame)
}
callback(data,undefined)
imageSource.release();
}).catch((err: string) => {
imageSource.release();
callback(undefined,err)
})
}
}).catch((err: string) => {
imageSource.release();
callback(undefined,err)
})
}).catch((err: string) => {
imageSource.release();
callback(undefined,err)
})
}
}