Paint API - Penjelasan terperinci tentang Xfermode dan PorterDuff (4)


Pengenalan kepada bahagian ini:

Dalam bahagian sebelumnya kami menulis tentang contoh pertama menggunakan Xfermode dan PorterDuff: pelaksanaan imej bulat & bulat ImageView, Kami telah menyedari faedah yang dibawa oleh PorterDuff.Mode.DST_IN kepada kami Dalam bahagian ini, kami akan terus menulis contoh untuk diamalkan. Adakah anda masih ingat pelaksanaan menanggalkan pakaian gadis cantik yang 8.3.2 Contoh Praktikal Lukisan dibawakan kepada anda?

1.gif

Pelan pelaksanaan kami pada masa itu adalah untuk menetapkan 20*20 piksel berhampiran kawasan sentuhan jari untuk menjadi lutsinar seperti ini:

2.gif

Saya tidak tahu Adakah anda perasan masalah apabila kita mengelap pakaian wanita cantik, mereka semua persegi, tetapi apabila kita melukis papan lukisan Apabila melukis gambar, garisan sangat licin Adakah terdapat cara untuk menggabungkan kedua-duanya supaya apabila kita mengelap pakaian, ia juga licin? Jawapannya pasti ya, hanya gunakan Xfermode! Dalam bahagian ini kami menggunakan mod lain, mod DST_OUT! Lukis graf sasaran di tempat yang berpecah

3.png

Jika anda terlupa mod tertentu atau belum melihat 18 mod, maka sila beralih ke:Tutorial pengenalan asas Android - 8.3 .5 Paint API - Penjelasan terperinci tentang Xfermode dan PorterDuff (2) Selain itu, saya masih mahu menyiarkan rendering PorterDuff.Mode:

4.png

Nah, tanpa berlengah lagi, mari kita mulakan bahagian ini lebih kurang 🎜>


Hmm, saya tak tahu berapa kali awak dah tengok Gif tu? Saya tidak tahu sama ada gambar itu menepati citarasa semua orang, Xiaozhu Ia telah dikikis daripada APP orang lain. Jangan tanya saya untuk nombor telefon atau alamat e-mel saya. Saya tidak tahu apa-apa. Tanya pemandu veteran dalam kumpulan - Ji Shen, okey, mari analisa proses pelaksanaan~

  • Mari kita bincangkan tentang prinsip Ia sebenarnya dua Bitmap, satu di hadapan dan satu di belakang Yang di hadapan memakai pakaian, dan yang di belakang tidak berpakaian. Kemudian gunakan Path untuk merakam grafik yang dilukis oleh pengguna, dan kemudian tetapkan mod DST_OUT untuk berus kami, kemudian DST (imej sasaran) yang bertindih dengan Path, iaitu imej memakai pakaian, akan menjadi lutsinar! Okay, itu mudah! Mari perhalusi perlahan-lahan!
  • Mula-mula kami memerlukan dua Peta Bit untuk menyimpan gambar hadapan dan belakang Di sini kami menjadikan kedua-dua Peta Bit itu skrin penuh!
  • Kemudian tetapkan berus, sudut bulat, lebar pen, anti-aliasing, dll.!
  • Kemudian tentukan Laluan lukisan, iaitu kaedah untuk pengguna melukis kawasan tersebut. Hanya lukis kawasan itu selepas menetapkan Xfermode!
  • Kemudian tulis semula kaedah onTouchEvent Bahagian ini sama dengan papan lukisan tersuai sebelumnya.
  • Akhir sekali tulis semula kaedah onDraw(), mula-mula lukis imej latar belakang, panggil kaedah pengguna untuk melukis kawasan itu, dan kemudian lukis imej latar depan!

Ia mungkin kelihatan agak rumit, tetapi ia tidak begitu mudah~


2 Hanya satu Paparan Tersuai——

StripMeiZi.java

/**
 * Created by Jay on 2015/10/25 0025.
 */
public class StripMeiZi extends View{

    private Paint mPaint = new Paint();
    private Path mPath = new Path();
    private Canvas mCanvas;
    private Bitmap mBeforeBitmap;
    private Bitmap mBackBitmap;
    private int mLastX,mLastY;
    private int screenW, screenH; //屏幕宽高
    private Xfermode mXfermode = new PorterDuffXfermode(PorterDuff.Mode.DST_OUT);


    public StripMeiZi(Context context) {
        this(context, null);
    }

    public StripMeiZi(Context context, AttributeSet attrs) {
        super(context, attrs);
        screenW = ScreenUtil.getScreenW(context);
        screenH = ScreenUtil.getScreenH(context);
        init();
    }


    public StripMeiZi(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    private void init() {
        //背后图片,这里让它全屏
        mBackBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.meizi_back);
        mBackBitmap = Bitmap.createScaledBitmap(mBackBitmap, screenW, screenH, false);
        //前面的图片,并绘制到Canvas上
        mBeforeBitmap = Bitmap.createBitmap(screenW, screenH, Bitmap.Config.ARGB_8888);
        mCanvas = new Canvas(mBeforeBitmap);
        mCanvas.drawBitmap(BitmapFactory.decodeResource(getResources(),
                R.mipmap.meizi_before), null, new RectF(0, 0, screenW, screenH), null);
        //画笔相关的设置
        mPaint.setAntiAlias(true);
        mPaint.setDither(true);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeJoin(Paint.Join.ROUND); // 圆角
        mPaint.setStrokeCap(Paint.Cap.ROUND); // 圆角
        mPaint.setStrokeWidth(80);    // 设置画笔宽
    }

    private void drawPath() {
        mPaint.setXfermode(mXfermode);
        mCanvas.drawPath(mPath, mPaint);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawBitmap(mBackBitmap, 0, 0, null);
        drawPath();
        canvas.drawBitmap(mBeforeBitmap, 0, 0, null);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int action = event.getAction();
        int x = (int) event.getX();
        int y = (int) event.getY();
        switch (action)
        {
            case MotionEvent.ACTION_DOWN:
                mLastX = x;
                mLastY = y;
                mPath.moveTo(mLastX, mLastY);
                break;
            case MotionEvent.ACTION_MOVE:

                int dx = Math.abs(x - mLastX);
                int dy = Math.abs(y - mLastY);

                if (dx > 3 || dy > 3)
                    mPath.lineTo(x, y);

                mLastX = x;
                mLastY = y;
                break;
        }
        invalidate();
        return true;
    }
}
Kod reka letak

activity_main.xml

:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <com.jay.xfermodedemo2.StripMeiZi
        android:layout_width="match_parent"
        android:layout_height="match_parent"/></RelativeLayout>

3.

Contoh praktikal - Demo mengoyakkan pakaian wanita cantik, berbanding apa yang pernah kita lakukan sebelum ini Cara mengoyakkan pakaian wanita cantik (menjadikan 20*20 piksel berhampiran titik sentuh telus) adalah lebih elegan~ Kodnya juga lebih mudah, bukan? Realisasikan faedah yang dibawa oleh Xfermode yang merombak imej Android kepada kami, atau kepentingan kawalan tersuai! Nah, apa tunggu lagi? Buka IDE anda, mainkan kod, dan rasai keseronokan mengoyak pakaian wanita cantik~