2019-07-28 PorterDuffXferMode的一些使用問題

PorterDuffXferMode的一些使用問題

一 PorterDuff.Mode使用問題

1.1 PorterDuff.Mode.CLEAR

  • 正常效果

    android_26_PorterDuff_Mode_CLEAR
  • targetSdkVersion 28

    android_28_PorterDuff_Mode_CLEAR

1.2 PorterDuff.Mode

PorterDuff.Mode 官方效果
https://developer.android.com/reference/android/graphics/PorterDuff.Mode.html

1.2 PorterDuffXfermode 在Android 27 和 28 的實際效果

  • PorterDuffXfermode_27

    PorterDuffXfermode_27
  • PorterDuffXfermode_28

    PorterDuffXfermode_28

圖片來源

二 繪制時 canvas 畫布不同導致的問題

after change another canvas ,PorterDuffXfermode(PorterDuff.Mode.CLEAR) is not work

創(chuàng)建 另一個 畫布

//保存沒有背景的截圖
screenShotBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
mScreenShotCanvas = Canvas(screenShotBitmap)

dispatchDraw


    override fun dispatchDraw(canvas: Canvas?) {

            ...

        //7.繪制蒙版
        drawMask(canvas)
       ....

        //截圖
        mScreenShotCanvas?.let { canvas ->
           ...
            //7.繪制蒙版
            drawMask(canvas, true)
           ...
        }


...


    }

問題 傳入的canvas 不同

    /**
     * 繪制蒙版
     *
     */
    private fun drawMask(canvas: Canvas, shotScreen: Boolean = false) {
        try {//qtip rl_frame_content -> 相框外層容器

            rl_frame_content?.let {
                //先獲取相框外層容器的位置
                val rlLeft = it.left
                val rlTop = it.top
                mGpuIV?.let { gpuIv ->

                    mMaskBitmap?.let { mask ->

                        //獲取相片和相框外側之間的位置關系

                        val gpuIvLeft = rl_gpu_iv_content_trim.left
                        val gpuIvTop = rl_gpu_iv_content_trim.top

                        val gpuIvWidth = rl_gpu_iv_content_trim.width
                        val gpuIvHeight = rl_gpu_iv_content_trim.height

                        val newWidth = gpuIvWidth - 2 * mMaskMargin
                        val newHeight = gpuIvHeight - 2 * mMaskMargin

                        //縮放后的蒙版(根據(jù)圖片的大小調整蒙版大小)
                        if (mScaledMaskBitmap == null) {
                            mScaledMaskBitmap = BitmapUtils.scaleBitmapInMaxWidthOrHeight(mask, newWidth, newHeight)
                        }

                          mScaledMaskBitmap?.let { scaleMask ->
                                //繪制mask
                                val left = rlLeft.toFloat() + gpuIvLeft
                                val top = rlTop.toFloat() + gpuIvTop

                                //1.離屏畫布
                                val save = canvas.saveLayer(left, top, left + gpuIvWidth, top + gpuIvHeight, null, Canvas.ALL_SAVE_FLAG)
                                //2.繪制帶顏色蒙版 創(chuàng)建大小和 rl_frame_content 一樣的蒙版
                                val dstBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
                                //創(chuàng)建蒙版畫布
                                val dstCav = Canvas(dstBitmap)
                                //蒙版顏色
                                dstCav.drawColor(mMaskColor)
                                canvas.drawBitmap(dstBitmap, left, top, null)

                                //3.蒙版掏空出透明形狀區(qū)域
                                val paintMask = Paint()
                                paintMask.isAntiAlias = true
                                paintMask.xfermode = PorterDuffXfermode(PorterDuff.Mode.CLEAR)
                                //蒙版位置居中
                                canvas.drawBitmap(scaleMask, left + (gpuIvWidth - scaleMask.width) / 2, top + (gpuIvHeight - scaleMask.height) / 2, paintMask)

                                //4.畫布恢復
                                canvas.restoreToCount(save)
                            }                     }
                }
            }
        } catch (e: Exception) {
            QLogger.e(e)
        }


    }

需要的效果

蒙版
蒙版形狀.png

截圖時實際效果

蒙版形狀失敗.png

并不是 paintMask.xfermode = PorterDuffXfermode(PorterDuff.Mode.CLEAR)
無效 而是 clear的區(qū)域不是 圖片的非透明區(qū)而是 整個圖片

  • 解決問題

// QTIP: 2019-07-23 修改

 PorterDuff.Mode.CLEAR 

PorterDuff.Mode.DST_OUT 或者 PorterDuff.Mode.XOR

待解決疑問 : Android api 28 以下 傳入有bitmap的canvas 繪制時 PorterDuff.Mode.CLEAR 無效

參考

https://stackoverflow.com/questions/51538443/xfermode-in-android-p-beta?noredirect=1#comment90044905_51538443

https://stackoverflow.com/questions/10494442/android-paint-porterduff-mode-clear?rq=1

https://issuetracker.google.com/issues/111819103

https://stackoverflow.com/questions/56189189/android-in-android-pie-api-28-radialgradient-draws-a-rectangle-instead-of-a?rq=1

https://android.googlesource.com/platform/development/+/master/samples/ApiDemos/src/com/example/android/apis/graphics/Xfermodes.java

關聯(lián)下 ViewOutlineProvider

/**
 * Interface by which a View builds its {@link Outline}, used for shadow casting and clipping.
 */
public abstract class ViewOutlineProvider {
...

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子开泽,更是在濱河造成了極大的恐慌,老刑警劉巖帚稠,帶你破解...
    沈念sama閱讀 218,682評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異床佳,居然都是意外死亡滋早,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評論 3 395
  • 文/潘曉璐 我一進店門砌们,熙熙樓的掌柜王于貴愁眉苦臉地迎上來杆麸,“玉大人,你說我怎么就攤上這事浪感∥敉罚” “怎么了?”我有些...
    開封第一講書人閱讀 165,083評論 0 355
  • 文/不壞的土叔 我叫張陵篮撑,是天一觀的道長减细。 經常有香客問我,道長赢笨,這世上最難降的妖魔是什么未蝌? 我笑而不...
    開封第一講書人閱讀 58,763評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮茧妒,結果婚禮上萧吠,老公的妹妹穿的比我還像新娘。我一直安慰自己桐筏,他們只是感情好纸型,可當我...
    茶點故事閱讀 67,785評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著梅忌,像睡著了一般狰腌。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上牧氮,一...
    開封第一講書人閱讀 51,624評論 1 305
  • 那天琼腔,我揣著相機與錄音,去河邊找鬼踱葛。 笑死丹莲,一個胖子當著我的面吹牛,可吹牛的內容都是我干的尸诽。 我是一名探鬼主播甥材,決...
    沈念sama閱讀 40,358評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼性含!你這毒婦竟也來了洲赵?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,261評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎板鬓,沒想到半個月后悲敷,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 45,722評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡俭令,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年后德,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片抄腔。...
    茶點故事閱讀 40,030評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡瓢湃,死狀恐怖,靈堂內的尸體忽然破棺而出赫蛇,到底是詐尸還是另有隱情绵患,我是刑警寧澤,帶...
    沈念sama閱讀 35,737評論 5 346
  • 正文 年R本政府宣布悟耘,位于F島的核電站落蝙,受9級特大地震影響,放射性物質發(fā)生泄漏暂幼。R本人自食惡果不足惜筏勒,卻給世界環(huán)境...
    茶點故事閱讀 41,360評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望旺嬉。 院中可真熱鬧管行,春花似錦、人聲如沸邪媳。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,941評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽雨效。三九已至迅涮,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間徽龟,已是汗流浹背逗柴。 一陣腳步聲響...
    開封第一講書人閱讀 33,057評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留顿肺,地道東北人。 一個月前我還...
    沈念sama閱讀 48,237評論 3 371
  • 正文 我出身青樓渣蜗,卻偏偏與公主長得像屠尊,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子耕拷,可洞房花燭夜當晚...
    茶點故事閱讀 44,976評論 2 355