Skip to content
This repository has been archived by the owner on Feb 6, 2023. It is now read-only.

Commit

Permalink
feat: draw matte sprite with PorterDuffXfermode(PorterDuff.Mode.DST_IN).
Browse files Browse the repository at this point in the history
  • Loading branch information
errnull committed May 31, 2019
1 parent f9e3827 commit bd55948
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 5 deletions.
Binary file removed app/src/main/assets/matte.svga
Binary file not shown.
Binary file added app/src/main/assets/matte1.svga
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public void onClick(View view) {

private void loadAnimation() {
SVGAParser parser = new SVGAParser(this);
parser.decodeFromAssets("matte.svga", new SVGAParser.ParseCompletion() {
parser.decodeFromAssets("matte1.svga", new SVGAParser.ParseCompletion() {
@Override
public void onComplete(@NotNull SVGAVideoEntity videoItem) {
animationView.setVideoItem(videoItem);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@ open internal class SGVADrawer(val videoItem: SVGAVideoEntity) {

val scaleInfo = SVGAScaleInfo()

inner class SVGADrawerSprite(val imageKey: String?, val frameEntity: SVGAVideoSpriteFrameEntity)
inner class SVGADrawerSprite(val matteKey: String?, val imageKey: String?, val frameEntity: SVGAVideoSpriteFrameEntity)

internal fun requestFrameSprites(frameIndex: Int): List<SVGADrawerSprite> {
return videoItem.sprites.mapNotNull {
if (frameIndex >= 0 && frameIndex < it.frames.size) {
if (it.frames[frameIndex].alpha <= 0.0) {
return@mapNotNull null
}
return@mapNotNull SVGADrawerSprite(it.imageKey, it.frames[frameIndex])
return@mapNotNull SVGADrawerSprite(it.matteKey, it.imageKey, it.frames[frameIndex])
}
return@mapNotNull null
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,57 @@ internal class SVGACanvasDrawer(videoItem: SVGAVideoEntity, val dynamicItem: SVG
super.drawFrame(canvas,frameIndex, scaleType)
this.pathCache.onSizeChanged(canvas)
val sprites = requestFrameSprites(frameIndex)
sprites.forEach {
drawSprite(it, canvas, frameIndex)
val matteSprites = mutableMapOf<String, SVGADrawerSprite>()

var isMatteing = false

sprites.forEachIndexed { index, svgaDrawerSprite ->

// save matte sprite
svgaDrawerSprite.imageKey?.let {
if (it.endsWith(".matte")) {
matteSprites.put(it, svgaDrawerSprite)
// continue
return@forEachIndexed
}
}

sprites.get(index - 1)?.let { lastSprite ->
if (isMatteing && (svgaDrawerSprite.matteKey == null || svgaDrawerSprite.matteKey != lastSprite.matteKey)) {
isMatteing = false

matteSprites.get(svgaDrawerSprite.matteKey)?.let {
val matteBitmap = Bitmap.createBitmap(canvas.width, canvas.height, Bitmap.Config.ARGB_8888)
val matteCanvas = Canvas(matteBitmap)
val paint = Paint()
paint.setXfermode(PorterDuffXfermode(PorterDuff.Mode.DST_IN))

drawSprite(it, matteCanvas, frameIndex)
canvas.drawBitmap(matteBitmap, 0f, 0f, paint)
canvas.restore()
}
}
if (svgaDrawerSprite.matteKey != null && (lastSprite.matteKey == null || lastSprite.matteKey != svgaDrawerSprite.matteKey)) {
isMatteing = true
canvas.save()
}
}

drawSprite(svgaDrawerSprite, canvas, frameIndex)

// if current sprite is the last one and isMatteing
if (isMatteing && index == sprites.count() - 1) {
matteSprites.get(svgaDrawerSprite.matteKey)?.let {
val matteBitmap = Bitmap.createBitmap(canvas.width, canvas.height, Bitmap.Config.ARGB_8888)
val matteCanvas = Canvas(matteBitmap)
val paint = Paint()
paint.setXfermode(PorterDuffXfermode(PorterDuff.Mode.DST_IN))

drawSprite(it, matteCanvas, frameIndex)
canvas.drawBitmap(matteBitmap, 0f, 0f, paint)
canvas.restore()
}
}
}
playAudio(frameIndex)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,14 @@ import org.json.JSONObject
*/
internal class SVGAVideoSpriteEntity {

val matteKey: String?

val imageKey: String?

val frames: List<SVGAVideoSpriteFrameEntity>

constructor(obj: JSONObject) {
this.matteKey = obj.optString("matteKey")
this.imageKey = obj.optString("imageKey")
val mutableFrames: MutableList<SVGAVideoSpriteFrameEntity> = mutableListOf()
obj.optJSONArray("frames")?.let {
Expand All @@ -34,6 +37,7 @@ internal class SVGAVideoSpriteEntity {
}

constructor(obj: SpriteEntity) {
this.matteKey = obj.imageKey
this.imageKey = obj.imageKey
var lastFrame: SVGAVideoSpriteFrameEntity? = null
frames = obj.frames?.map {
Expand Down

0 comments on commit bd55948

Please sign in to comment.