Paint API - Penjelasan terperinci tentang Xfermode dan PorterDuff (2)
Pengenalan kepada bahagian ini:
Tulis contoh untuk mengesahkan gambar di atas:Dalam bahagian sebelumnya, kami mengetahui tentang dua anak lelaki Xfermode (usang) yang telah meninggal dunia: AvoidXfermode, PixelXorXfermode , Walaupun ia agak berguna, ia akhirnya dihapuskan Dalam bahagian ini, kita akan belajar tentang anak ketiga Xfermode yang masih hidup: PorterDuffXfermode
Pertama, mari kita lihat dokumen API rasmi: PorterDuffXfermode ! Dokumen mengandungi kandungan yang sangat sedikit. Kita dapat melihat kaedah pembinaannya:
Hanya ada satu parameter: mod Mod PorterDuff dan Android menyediakan 16 mod pencampuran imej. , ia boleh menjadi lebih mudah Difahamkan bahawa dua lapisan boleh digabungkan menjadi hasil yang berbeza dan dipaparkan mengikut mod yang berbeza! Imej hasil daripada 16 mod pencampuran adalah seperti berikut:
Terdapat dua lapisan di sini: imej yang dilukis dahulu ialah imej sasaran (DST) dan imej yang dilukis kemudian ialah Imej sumber (SRC) !
Sudah tentu, dalam dokumen kami mendapati bahawa mod yang tersedia bukan 16, tetapi 18, dengan dua mod baharu: TAMBAH dan TINDIHAN! 🎜>Nah, tidak berguna untuk mengatakan terlalu banyak Kod adalah yang paling praktikal Dalam bahagian ini, kami menulis kod untuk mengesahkan 18 mod ini.
PS: Nama PorterDuff sebenarnya adalah gabungan dua nama: Tomas Proter dan Tom Duff, yang merupakan yang pertama Orang tahap dewa yang mula-mula mencadangkan konsep percampuran grafik pada SIGGRAPH Jika anda berminat, sila Baidu~
<🎜. >
Okey, mari tulis contoh untuk mengesahkan gambar di atas, dan bandingkan serta analisis hasilnya dengan mengubah suai mod yang berbeza!
Pelaksanaan kod:
Langkah 1
: Mari kita tulis kelas alat dahulu untuk mendapatkan lebar dan ketinggian skrin!ScreenUtil.java:
/** * Created by Jay on 2015/10/23 0023. */ public class ScreenUtil { /** * 获取屏幕宽高,sdk17后不建议采用 * * @param context */ public static int[] getScreenHW(Context context) { WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); Display display = manager.getDefaultDisplay(); int width = display.getWidth(); int height = display.getHeight(); int[] HW = new int[] { width, height }; return HW; } /** * 获取屏幕宽高,建议采用 * * @param context */ public static int[] getScreenHW2(Context context) { WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); DisplayMetrics dm = new DisplayMetrics(); manager.getDefaultDisplay().getMetrics(dm); int width = dm.widthPixels; int height = dm.heightPixels; int[] HW = new int[] { width, height }; return HW; } /** * 获取屏幕的宽度 * * @param context * @return */ public static int getScreenW(Context context) { return getScreenHW2(context)[0]; } /** * 获取屏幕的高度 * * @param context * @return */ public static int getScreenH(Context context) { return getScreenHW2(context)[1]; } }Langkah 2: Tulis kelas Lihat tersuai kami dan percubaan di sini! XfermodeView.java:
/** * Created by Jay on 2015/10/23 0023. */ public class XfermodeView extends View { private PorterDuffXfermode pdXfermode; //定义PorterDuffXfermode变量 //定义MODE常量,等下直接改这里即可进行测试 private static PorterDuff.Mode PD_MODE = PorterDuff.Mode.ADD; private int screenW, screenH; //屏幕宽高 private int width = 200; //绘制的图片宽高 private int height = 200; private Bitmap srcBitmap, dstBitmap; //上层SRC的Bitmap和下层Dst的Bitmap public XfermodeView(Context context) { this(context, null); } public XfermodeView(Context context, AttributeSet attrs) { super(context, attrs); screenW = ScreenUtil.getScreenW(context); screenH = ScreenUtil.getScreenH(context); //创建一个PorterDuffXfermode对象 pdXfermode = new PorterDuffXfermode(PD_MODE); //实例化两个Bitmap srcBitmap = makeSrc(width, height); dstBitmap = makeDst(width, height); } public XfermodeView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } //定义一个绘制圆形Bitmap的方法 private Bitmap makeDst(int w, int h) { Bitmap bm = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); Canvas c = new Canvas(bm); Paint p = new Paint(Paint.ANTI_ALIAS_FLAG); p.setColor(0xFF26AAD1); c.drawOval(new RectF(0, 0, w * 3 / 4, h * 3 / 4), p); return bm; } //定义一个绘制矩形的Bitmap的方法 private Bitmap makeSrc(int w, int h) { Bitmap bm = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); Canvas c = new Canvas(bm); Paint p = new Paint(Paint.ANTI_ALIAS_FLAG); p.setColor(0xFFFFCE43); c.drawRect(w / 3, h / 3, w * 19 / 20, h * 19 / 20, p); return bm; } @Override protected void onDraw(Canvas canvas) { Paint paint = new Paint(); paint.setFilterBitmap(false); paint.setStyle(Paint.Style.FILL); canvas.drawBitmap(srcBitmap, (screenW / 3 - width) / 2, (screenH / 2 - height) / 2, paint); canvas.drawBitmap(dstBitmap, (screenW / 3 - width) / 2 + screenW / 3, (screenH / 2 - height) / 2, paint); //创建一个图层,在图层上演示图形混合后的效果 int sc = canvas.saveLayer(0, 0, screenW, screenH, null, Canvas.MATRIX_SAVE_FLAG | Canvas.CLIP_SAVE_FLAG | Canvas.HAS_ALPHA_LAYER_SAVE_FLAG | Canvas.FULL_COLOR_LAYER_SAVE_FLAG | Canvas.CLIP_TO_LAYER_SAVE_FLAG); canvas.drawBitmap(dstBitmap, (screenW / 3 - width) / 2 + screenW / 3 * 2, (screenH / 2 - height) / 2, paint); //绘制i //设置Paint的Xfermode paint.setXfermode(pdXfermode); canvas.drawBitmap(srcBitmap, (screenW / 3 - width) / 2 + screenW / 3 * 2, (screenH / 2 - height) / 2, paint); paint.setXfermode(null); // 还原画布 canvas.restoreToCount(sc); } }Kod ini kelihatan rumit, tetapi ia tidak hanya mendapatkan lebar dan ketinggian skrin, kemudian melukis segi empat tepat dan bulatan. Kira kedudukan mereka, kemudian tetapkan lapisan bawah (kaedah penulisan tetap), kemudian tetapkan set berus bawah setXfermode, dan kemudian Ia hanya dilukis di atas kanvas Apa yang anda tidak faham mungkin adalah pengiraan kedudukan lukisan. Ia akan baik-baik saja! Jadi mari kita lihat hasil satu persatu Anda hanya perlu mengubah suai nilai PD_MODE untuk menetapkannya kepada mod yang berbeza!
Penyampaian operasi
:1) PorterDuff.Mode.ADD:
Tepuan Tindanan
2) PorterDuff.Mode.CLEAR:
yang dilukis tidak akan Menyerahkannya ke kanvas, dan hasilnya... Saya tidak tahu mengapa, biasanya tiada apa-apa..
3) PorterDuff.Mode.DARKEN:
Ambil dua lapisan Semua kawasan, bahagian persimpangan berwarna lebih gelap
4) PorterDuff.Mode.DST:
Hanya mengekalkan alfa dan warna imej sasaran, jadi hanya imej sasaran dilukis
5) PorterDuff.Mode.DST_ATOP:
Imej sasaran dilukis di mana imej sumber dan imej sasaran bersilang, dan imej sumber dilukis di tempat mereka tidak bersilang
6) PorterDuff.Mode.DST_IN:
Imej sasaran dilukis di mana kedua-duanya bersilang, dan kesan lukisan akan dipengaruhi oleh ketelusan imej asal
7) PorterDuff.Mode.DST_OUT:
Lukis graf sasaran di tempat yang berpisah
8) PorterDuff.Mode.DST_OVER:
The graf sasaran dilukis di atas
9) PorterDuff.Mode:
Ambil semua kawasan dua lapisan dan terangkan warna persimpangan
10) PorterDuff. .Mod.MULTIPLY:
Ambil dua lapisan Warna bahagian persilangan selepas tindanan ialah
11) PorterDuff.Mode.OVERLAY:
Tindanan
12) PorterDuff.Mode.SCREEN:
Ambil semua kawasan dua lapisan, dan bahagian persilangan menjadi lutsinar
13) PorterDuff.Mode .SRC:
Hanya kekalkan alfa dan warna imej sumber, jadi lukiskannya Hanya imej sumber
14) PorterDuff.Mode.SRC_ATOP:
Imej sumber dilukis di mana imej sumber dan imej sasaran bersilang, dan imej sasaran dilukis di tempat yang tidak bersilang
15) PorterDuff.Mode SRC_IN:
Lukis imej sumber di mana kedua-duanya bersilang
16) PorterDuff.Mode.SRC_OUT:
Lukis imej sumber di mana ia tidak bersilang
17) PorterDuff.Mode.SRC_OVER:
Lukis imej sumber di atas
18) PorterDuff.Mode.XOR :
Imej sumber dan sasaran dilukis kerana ia berada di tempat ia tidak bersilang
Muat turun kod sampel untuk bahagian ini:
Ringkasan bahagian ini:
Nah, dalam bahagian ini saya menulis View ringkas untuk mengesahkan kesan berbeza daripada 18 PorterDuff berbeza ini .Mod. Hei, ia agak memakan masa, tetapi ia kelihatan lebih jelas kepada pembaca, kan~ Sudah tentu, ini hanyalah beberapa cerapan awal!
PorterDuffXfermode's PorterDuff.Mode sangat penting untuk kawalan tersuai kami! Dalam bahagian ini kita mempunyai pemahaman awal Dalam bahagian seterusnya kita akan memilih beberapa contoh untuk diamalkan!
Jika anda ingin melihat pengenalan yang lebih terperinci tentang PorterDuff.Mode, sila lihat: Penjelasan setXfermode PorterDuffXfermode Android Paint, artikel yang bagus yang ditulis oleh orang lain! Baiklah, itu sahaja, saya akan mempunyai peperiksaan fizikal esok pagi, itu sahaja yang akan saya tulis hari ini~