frame.imageStream?=?mPngStream; ????????return?frame; ????} ``` 2) Apng的消除操作Apng的消除操作是在ApngFrameRender的render方法做的,方法如下:
```
????/**
?????*?渲染当前帧画面
?????*
?????*?@param?frame?apng中当前帧
?????*?@return?渲染合成后的当前帧图像
?????*/
????public?Bitmap?render(ApngFrame?frame,?Bitmap?frameBmp)?{
????????//?执行消除操作
????????dispose(frame);
????????//?合成当前帧
????????blend(frame,?frameBmp);
????????return?mRenderFrame;
????}
dispose(ApngFrame frame)方法如下:
<pre style="box-sizing: border-box; outline: none; margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; font-size: 1em; line-height: inherit; font-family: couriernew, courier, monospace; vertical-align: baseline;">
/** ?????*?帧图像析构消除?-?提交结果 ?????*/ ????private?void?dispose(ApngFrame?frame)?{ ????????//?last?frame?dispose?op ????????switch?(mLastDisposeOp)?{ ????????????case?APNG_DISPOSE_OP_NONE: ????????????????//?no?op ????????????????break;
case?APNG_DISPOSE_OP_BACKGROUND: ????????????????//?clear?rect ????????????????mRenderCanvas.clipRect(mDisposeRect); ????????????????mRenderCanvas.drawColor(Color.TRANSPARENT,?PorterDuff.Mode.CLEAR); ????????????????mRenderCanvas.clipRect(mFullRect,?Region.Op.REPLACE); ????????????????break;
case?APNG_DISPOSE_OP_PREVIOUS: ????????????????//?swap?work?and?cache?bitmap ????????????????Bitmap?bmp?=?mRenderFrame; ????????????????mRenderFrame?=?mDisposedFrame; ????????????????mDisposedFrame?=?bmp; ????????????????mRenderCanvas.setBitmap(mRenderFrame); ????????????????mDisposeCanvas.setBitmap(mDisposedFrame); ????????????????break; ????????}
//?current?frame?dispose?op ????????mLastDisposeOp?=?frame.getDisposeOp(); ????????switch?(mLastDisposeOp)?{ ????????????case?APNG_DISPOSE_OP_NONE: ????????????????//?no?op ????????????????break;
case?APNG_DISPOSE_OP_BACKGROUND: ????????????????//?cache?rect?for?next?clear?dispose ????????????????int?x?=?frame.getxOff(); ????????????????int?y?=?frame.getyOff(); ????????????????mDisposeRect.set(x,?y,?x?+?frame.getWidth(),?y?+?frame.getHeight()); ????????????????break;
case?APNG_DISPOSE_OP_PREVIOUS: ????????????????//?cache?bmp?for?next?restore?dispose ????????????????mDisposeCanvas.clipRect(mFullRect,?Region.Op.REPLACE); ????????????????mDisposeCanvas.drawColor(Color.TRANSPARENT,?PorterDuff.Mode.CLEAR); ????????????????mDisposeCanvas.drawBitmap(mRenderFrame,?0,?0,?null); ????????????????break; ????????} ????}
</pre>
3) Apng的合成操作Apng的合成操作是在每一帧经过dispose之后做的,具体方法是blend(ApngFrame frame, Bitmap frameBmp),代码如下:
<pre style="box-sizing: border-box; outline: none; margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; font-size: 1em; line-height: inherit; font-family: couriernew, courier, monospace; vertical-align: baseline;">
/** ?????*?帧图像合成 ?????*/ ????private?void?blend(ApngFrame?frame,?Bitmap?frameBmp)?{ ????????int?xOff?=?frame.getxOff(); ????????int?yOff?=?frame.getyOff();
mRenderCanvas.clipRect(xOff,?yOff,?xOff?+?frame.getWidth(),?yOff?+?frame.getHeight()); ????????if?(frame.getBlendOp()?==?APNG_BLEND_OP_SOURCE)?{ ????????????mRenderCanvas.drawColor(Color.TRANSPARENT,?PorterDuff.Mode.CLEAR); ????????} ????????mRenderCanvas.drawBitmap(frameBmp,?xOff,?yOff,?null); ????????mRenderCanvas.clipRect(mFullRect,?Region.Op.REPLACE); ????} ``` 4) Apng的绘制Apng的每一帧经过消除、合成操作之后,就可以在View上面draw,具体代码如下:
```
?/**
?????????*?draw?the?appointed?frame
?????????*/
????????private?void?drawFrame(AnimParams?animItem,?ApngFrame?frame,?Bitmap?frameBmp)?{
????????????if?(surfaceEnabled?&&?!isInterrupted())?{
????????????????//start?to?draw?the?frame
????????????????try?{
????????????????????Matrix?matrix?=?new?Matrix();
????????????????????matrix.setScale(mScale,?mScale);
????????????????????Bitmap?bmp?=?mFrameRender.render(frame,?frameBmp);
????????????????????//saveBitmap(bmp,?index);
????????????????????index?++;
????????????????????Canvas?canvas?=?getHolder().lockCanvas();
????????????????????//anti-aliasing
????????????????????canvas.drawColor(Color.TRANSPARENT,?PorterDuff.Mode.CLEAR);
????????????????????float[]?tranLeftAndTop?=?ApngUtils.getTranLeftAndTop(canvas,?bmp,?animItem.align,?mScale,?animItem.percent);
????????????????????canvas.setDrawFilter(new?PaintFlagsDrawFilter(0,?Paint.ANTI_ALIAS_FLAG?|?Paint.FILTER_BITMAP_FLAG));
????????????????????matrix.postTranslate(tranLeftAndTop[0],?tranLeftAndTop[1]);
????????????????????canvas.drawBitmap(bmp,?matrix,?null);
????????????????????getHolder().unlockCanvasAndPost(canvas);?//??unlock?the?canvas
????????????????}?catch?(Exception?e)?{
????????????????????Log.e(TAG,?"draw?error?msg:"?+?Log.getStackTraceString(e));
????????????????}
????????????}
????????}
4. 实例我们是在SurfaceView上面来绘制Apng的每一帧,例子如下:
Activity代码:
<pre style="box-sizing: border-box; outline: none; margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; font-size: 1em; line-height: inherit; font-family: couriernew, courier, monospace; vertical-align: baseline;">
public?class?MainActivity?extends?Activity{ ????private?ApngSurfaceView?mApngSurfaceView; ????private?static?final??String?COLOR_BALL_IMAGE_PATH?=?“assets://color_ball.png”; ????//private?static?final??String?CAR_IMAGE_PATH?=?“assets://car.png”;
@Override ????protected?void?onCreate(Bundle?savedInstanceState)?{ ????????super.onCreate(savedInstanceState); ????????setContentView(R.layout.activity_main); ????????mApngSurfaceView?=?(ApngSurfaceView)findViewById(R.id.apng_surface_view); ????????Button?startPlay?=?(Button)?findViewById(R.id.start_play); ????????startPlay.setOnClickListener(new?View.OnClickListener()?{ ????????????@Override ????????????public?void?onClick(View?v)?{ ????????????????playAnim(); ????????????} ????????}); ????}
private?void?playAnim(){ ????????File?file?=?FileUtils.processApngFile(COLOR_BALL_IMAGE_PATH,?this); ????????if(file?==?null)?return; ????????AnimParams?animItem?=?new?AnimParams(); ????????animItem.align?=?2; ????????animItem.imagePath?=?file.getAbsolutePath(); ????????animItem.isHasBackground?=?true; ????????animItem.percent?=?0.5f; ????????mApngSurfaceView.addApngForPlay(animItem); ????} } ``` Layout代码:
```
<?xml?version="1.0"?encoding="utf-8"?>
????
|