diff --git a/CHANGELOG.md b/CHANGELOG.md index 4e0b603..ddb1842 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ - 适配Sendable内存共享优化 - 修改全局请求头覆盖request请求头 - imageKnife支持heic测试demo独立页面展示 +- drawLifeCycle支持gif图 ## 2.1.2-rc.12 - 新增gif播放次数功能 diff --git a/entry/src/main/ets/pages/testImageKnifeOptionChangedPage5.ets b/entry/src/main/ets/pages/testImageKnifeOptionChangedPage5.ets index 47c1119..d331111 100644 --- a/entry/src/main/ets/pages/testImageKnifeOptionChangedPage5.ets +++ b/entry/src/main/ets/pages/testImageKnifeOptionChangedPage5.ets @@ -27,6 +27,9 @@ import { ImageKnifeDrawFactory } from '@ohos/libraryimageknife' import worker from '@ohos.worker'; + +let gifUrl: string = 'https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658'; + @Entry @Component struct TestImageKnifeOptionChangedPage5 { @@ -83,6 +86,64 @@ struct TestImageKnifeOptionChangedPage5 { }; }).margin({ left: 5 }).backgroundColor(Color.Blue) }.margin({ top: 15 }) + Flex({ direction: FlexDirection.Row }) { + Button("本地gif") + .onClick(() => { + this.imageKnifeOption1 = { + loadSrc: $r('app.media.gifSample'), + placeholderSrc: $r('app.media.icon_loading'), + errorholderSrc: $r('app.media.icon_failed'), + }; + }).margin({ left: 5 }).backgroundColor(Color.Blue) + Button("网络gif") + .onClick(() => { + this.imageKnifeOption1 = { + loadSrc: gifUrl, + placeholderSrc: $r('app.media.icon_loading'), + errorholderSrc: $r('app.media.icon_failed'), + }; + }).margin({ left: 5 }).backgroundColor(Color.Blue) + }.margin({ top: 15 }) + Flex({ direction: FlexDirection.Row }) { + Button("网络gif - 圆角小") + .onClick(() => { + this.imageKnifeOption1 = { + loadSrc: gifUrl, + placeholderSrc: $r('app.media.icon_loading'), + errorholderSrc: $r('app.media.icon_failed'), + drawLifeCycle: ImageKnifeDrawFactory.createRoundLifeCycle(3, "#ff0000", 30) + }; + }).margin({ left: 5 }).backgroundColor(Color.Blue) + Button("本地gif - 圆角大") + .onClick(() => { + this.imageKnifeOption1 = { + loadSrc: $r('app.media.gifSample'), + placeholderSrc: $r('app.media.icon_loading'), + errorholderSrc: $r('app.media.icon_failed'), + drawLifeCycle: ImageKnifeDrawFactory.createRoundLifeCycle(5, "#ffff00", 300) + }; + }).margin({ left: 5 }).backgroundColor(Color.Blue) + }.margin({ top: 15 }) + Flex({ direction: FlexDirection.Row }) { + Button("网络gif-椭圆长方形资源") + .onClick(() => { + this.imageKnifeOption1 = { + loadSrc: gifUrl, + placeholderSrc: $r('app.media.icon_loading'), + errorholderSrc: $r('app.media.icon_failed'), + drawLifeCycle: ImageKnifeDrawFactory.createOvalLifeCycle(8, "#88ee00") + }; + }).margin({ left: 5 }).backgroundColor(Color.Blue) + Button("本地gif-椭圆正方形资源") + .onClick(() => { + this.imageKnifeOption1 = { + loadSrc: $r('app.media.gifSample'), + placeholderSrc: $r('app.media.icon_loading'), + errorholderSrc: $r('app.media.icon_failed'), + drawLifeCycle: ImageKnifeDrawFactory.createOvalLifeCycle(5, "#ff00ff") + }; + }).margin({ left: 5 }).backgroundColor(Color.Blue) + }.margin({ top: 15 }) Text("下面为展示图片区域").margin({ top: 5 }) Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { diff --git a/library/src/main/ets/components/imageknife/ImageKnifeComponent.ets b/library/src/main/ets/components/imageknife/ImageKnifeComponent.ets index e8ea770..3fe841a 100644 --- a/library/src/main/ets/components/imageknife/ImageKnifeComponent.ets +++ b/library/src/main/ets/components/imageknife/ImageKnifeComponent.ets @@ -27,6 +27,7 @@ import { ObjectKey } from './ObjectKey' import componentUtils from '@ohos.arkui.componentUtils' import inspector from '@ohos.arkui.inspector' import util from '@ohos.util' +import { ImageKnifeDrawFactory } from './ImageKnifeDrawFactory' interface KeyCanvas { keyId:string @@ -415,6 +416,7 @@ export struct ImageKnifeComponent { } displayMainSource = (data: ImageKnifeData|number|undefined)=> { + ImageKnifeDrawFactory.type = undefined; if(data == undefined || typeof data == 'number'){ return } @@ -899,10 +901,58 @@ export struct ImageKnifeComponent { ScaleTypeHelper.drawImageWithScaleType(context, scaleType, pixelmap, px2vp(frameW), px2vp(frameH), compWidth, compHeight, px2vp(frame.dims.left), px2vp(frame.dims.top)) // tips:worker如果不是在展示页面中创建,使用子线程回来的数据创建的图片,会导致canvas绘制不出来 context.restore(); + if (ImageKnifeDrawFactory.type === undefined) { + return; + } + // 通过 destination-in 裁剪出圆角 + if (ImageKnifeDrawFactory?.type === DrawType.Round || ImageKnifeDrawFactory?.type === DrawType.Oval) { + context.save(); + context.globalCompositeOperation = 'destination-in'; + if (ImageKnifeDrawFactory.type === DrawType.Round) { + ImageKnifeDrawFactory.setRect(context, scaleType, pixelmap, px2vp(frameW), px2vp(frameH), compWidth, + compHeight, 0, 0, ImageKnifeDrawFactory.borderWidth, ImageKnifeDrawFactory.connerRadius); + } else { + context.beginPath(); + ImageKnifeDrawFactory.setOval(context, scaleType, pixelmap, px2vp(frameW), px2vp(frameH), compWidth, + compHeight, 0, 0, ImageKnifeDrawFactory.borderWidth); + context.closePath(); + } + context.fill(); + context.restore(); + if (ImageKnifeDrawFactory.borderWidth > 0) { + // 为圆角添加边框 + context.save(); + context.strokeStyle = ImageKnifeDrawFactory.colorString; + context.lineWidth = ImageKnifeDrawFactory.borderWidth; + context.globalCompositeOperation = 'source-over'; + if (ImageKnifeDrawFactory.type === DrawType.Round) { + ImageKnifeDrawFactory.setRect(context, scaleType, pixelmap, px2vp(frameW), px2vp(frameH), compWidth, + compHeight, 0, 0, ImageKnifeDrawFactory.borderWidth, ImageKnifeDrawFactory.connerRadius); + } else { + context.beginPath(); + ImageKnifeDrawFactory.setOval(context, scaleType, pixelmap, px2vp(frameW), px2vp(frameH), compWidth, + compHeight, 0, 0, ImageKnifeDrawFactory.borderWidth); + context.closePath(); + } + context.stroke(); + context.restore(); + } + context.restore(); + } LogUtil.log('ImageKnifeComponent canvasDrawPixelMap end!') } } +export enum DrawType{ + + Normal = 0, + + Oval = 1, + + Round = 2 + +} + export enum FrameDisposalType { // 0 - No disposal specified. The decoder is not required to take any action. // 不使用处置方法 diff --git a/library/src/main/ets/components/imageknife/ImageKnifeDrawFactory.ets b/library/src/main/ets/components/imageknife/ImageKnifeDrawFactory.ets index f67bfad..5080f1f 100644 --- a/library/src/main/ets/components/imageknife/ImageKnifeDrawFactory.ets +++ b/library/src/main/ets/components/imageknife/ImageKnifeDrawFactory.ets @@ -16,9 +16,13 @@ import { ImageKnifeOption } from '../imageknife/ImageKnifeOption' import { ImageKnifeData } from '../imageknife/ImageKnifeData' import { GIFFrame } from '../imageknife/utils/gif/GIFFrame' import { IDrawLifeCycle } from '../imageknife/interface/IDrawLifeCycle' -import { ScaleTypeHelper,ScaleType } from '../imageknife/ImageKnifeComponent' +import { ScaleTypeHelper,ScaleType, DrawType } from '../imageknife/ImageKnifeComponent' export class ImageKnifeDrawFactory{ + public static borderWidth: number; + public static type: DrawType | undefined = undefined; + public static colorString: string; + public static connerRadius: number; /** * 绘制PixelMap内容情况下,主图的椭圆裁剪,可添加边框 @@ -81,6 +85,11 @@ export class ImageKnifeDrawFactory{ }) return true; } + if (data.isGIFFrame()) { + ImageKnifeDrawFactory.type = DrawType.Oval; + ImageKnifeDrawFactory.borderWidth = borderWidth; + ImageKnifeDrawFactory.colorString = colorString; + } return false; }, // 展示重试图层 @@ -108,7 +117,7 @@ export class ImageKnifeDrawFactory{ * @param imageOffsetY * @param borderWidth */ - private static setOval(context: CanvasRenderingContext2D, scaleType: ScaleType, source: PixelMap | undefined, imageWidth: number, imageHeight: number, compWidth: number, compHeight: number, imageOffsetX:number,imageOffsetY:number + public static setOval(context: CanvasRenderingContext2D, scaleType: ScaleType, source: PixelMap | undefined, imageWidth: number, imageHeight: number, compWidth: number, compHeight: number, imageOffsetX:number,imageOffsetY:number ,borderWidth:number) { let scaleW = compWidth / imageWidth let scaleH = compHeight / imageHeight @@ -240,6 +249,12 @@ export class ImageKnifeDrawFactory{ }) return true; } + if (data.isGIFFrame()) { + ImageKnifeDrawFactory.type = DrawType.Round; + ImageKnifeDrawFactory.borderWidth = borderWidth; + ImageKnifeDrawFactory.colorString = colorString; + ImageKnifeDrawFactory.connerRadius = connerRadius; + } return false; }, // 展示重试图层 @@ -268,7 +283,7 @@ export class ImageKnifeDrawFactory{ * @param borderWidth * @param cornerRadius */ - private static setRect(context: CanvasRenderingContext2D, scaleType: ScaleType, source: PixelMap | undefined, imageWidth: number, imageHeight: number, compWidth: number, compHeight: number, imageOffsetX:number,imageOffsetY:number + public static setRect(context: CanvasRenderingContext2D, scaleType: ScaleType, source: PixelMap | undefined, imageWidth: number, imageHeight: number, compWidth: number, compHeight: number, imageOffsetX:number,imageOffsetY:number ,borderWidth:number,cornerRadius:number) { let scaleW = compWidth / imageWidth let scaleH = compHeight / imageHeight