首页 > 其他分享 >混合模式(二)

混合模式(二)

时间:2023-01-06 10:33:51浏览次数:40  
标签:SRC DST 模式 混合 Mode 图像 import android


PorterDuffXfermode

  • 该模式针对的时在处理结果时以源图像显示为主的模式,主要有:Mode.SRC, Mode.SRC_IN, Mode.SRC_OUT, Mode.SRC_OVER和Mode.SRC_ATOP
Mode.SRC:
//全部以源图像进行显示
[Sa, Sc]

混合模式(二)_Android 自定义动画

Mode.SRC_IN:
//透明度和颜色值都是通过乘以目标图像的像素得到的
//利用这个特性可以实现,圆角效果,和图片倒影等
[Sa * Da, Sc * Da]

混合模式(二)_Android 自定义动画_02

  • 上述两者的唯一不同之处在于当目标图像为空白像素时,SRC_IN模式所对应的区域也会变成空白像素
  • 圆角效果:
  • 首先需要准备一个圆角的图片,通过图片和这个圆角的图片进行融合,透明的部分融合后显示透明即可
  • 图片倒影:
package com.example.adminstator.myviewdesign.hunhemoshi.yuantuxiangmoshi.daoying;


import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;


import com.example.adminstator.myviewdesign.R;


/**
* Created with Android Studio.
* Description:
*
* @author: 王拣贤
* @date: 2019/06/21
* Time: 16:58
*/
public class InvertedImageView extends View {
private Paint paint;
private Bitmap BmpDST, BmpSRC, BmpRevert;
public InvertedImageView(Context context, AttributeSet attrs) {
super(context, attrs);
setLayerType(LAYER_TYPE_SOFTWARE, null);
paint = new Paint();
BmpDST = BitmapFactory.decodeResource(getResources(), R.drawable.dog_invert_shade, null);
BmpSRC = BitmapFactory.decodeResource(getResources(), R.drawable.dog,null);
Matrix matrix = new Matrix();
matrix.setScale(1F, -1F);
//翻转小狗图像
BmpRevert = Bitmap.createBitmap(BmpSRC, 0, 0, BmpSRC.getWidth(),
BmpSRC.getHeight(), matrix, true);
}


@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int width = getWidth() / 2;
int height = width * BmpDST.getHeight()/BmpDST.getWidth();
//画出小狗图像
canvas.drawBitmap(BmpSRC, null, new RectF(0, 0, width, height), paint);


//将画布下移,画出倒影
int layerId = canvas.saveLayer(0, 0, getWidth(), getHeight(), null, Canvas.ALL_SAVE_FLAG);
canvas.translate(0, height);
//将小狗图的翻转和背景图结合
canvas.drawBitmap(BmpDST, null, new RectF(0, 0, width, height), paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(BmpRevert, null, new RectF(0, 0, width, height), paint);
paint.setXfermode(null);
canvas.restoreToCount(layerId);
}
}
Mode.SRC_OUT:
//当目标图像完全不透明的时候,计算结果是透明的,当目标图像是空白像素的时候,完全显示源图像。
//以目标图像的补值来调节图像的透明度和饱和度
//可以实现橡皮擦效果
//可以实现刮刮卡效果
[Sa * (1-Da), Sc * (1-Da)]

混合模式(二)_图像显示_03

  • eg:橡皮擦: 就是首先创建一个空白像素的Bitmap作为背景,这样在这个Bitmap上再创建一个画布,这样我们通过在这个画布上进行绘制手指的路径,将手指扫过的路径变的透明,这样原本不透明部分因为设置了Mode.SRC_OUT模式,而变得透明
package com.example.adminstator.myviewdesign.hunhemoshi.yuantuxiangmoshi.ModeSrcOut;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

import com.example.adminstator.myviewdesign.R;

/**
* Created with Android Studio.
* Description:
*
* @author: 王拣贤
* @date: 2019/06/21
* Time: 17:18
*/
public class EraserView extends View {
private Paint paint;
private Bitmap BmpDST, BmpSRC;
private Path path;
private float mPreX, mPreY;
public EraserView(Context context,AttributeSet attrs) {
super(context, attrs);
setLayerType(LAYER_TYPE_SOFTWARE, null);
paint = new Paint();
paint.setColor(Color.RED);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(45);
BitmapFactory.Options options = new BitmapFactory.Options();
//设置采样率为2,将图片设置为原来的1/2
options.inSampleSize = 2;
BmpSRC = BitmapFactory.decodeResource(getResources(), R.drawable.dog,options);
BmpDST = Bitmap.createBitmap(BmpSRC.getWidth(), BmpSRC.getHeight(), Bitmap.Config.ARGB_8888);
path = new Path();
}

@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
path.moveTo(event.getX(), event.getY());
mPreX = event.getX();
mPreY = event.getY();
return true;
case MotionEvent.ACTION_MOVE:
float endX = (mPreX+event.getX())/2;
float endY = (mPreY+event.getY())/2;
path.quadTo(mPreX, mPreY, endX, endY);
mPreX = event.getX();
mPreY = event.getY();
break;
case MotionEvent.ACTION_UP:
break;
}
postInvalidate();
return super.onTouchEvent(event);
}

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int layerId = canvas.saveLayer(0, 0, getWidth(), getHeight(), null, Canvas.ALL_SAVE_FLAG);
//先把手势轨迹画到目标图像上
Canvas c = new Canvas(BmpDST);
c.drawPath(path, paint);
//然后把目标图像画到画布上
canvas.drawBitmap(BmpDST,0, 0, paint);
//计算源图像区域
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OUT));
canvas.drawBitmap(BmpSRC, 0, 0, paint);
paint.setXfermode(null);
canvas.restoreToCount(layerId);
}
}
Mode.SRC_OVER:
//在目标图像的顶部绘制源图像,即在源图像的透明度的基础上增加一部分目标图像的透明度,增加的透明度是源图像透明度的补量,当源图像的透明度为100%时,原样显示源图像。
[Sa + (1 - Sa) * Da, Rc = Sc + (1-Sa)*Dc]

混合模式(二)_Android 自定义动画_04

Mode.SRC_ATOP:
//效果和SRC_IN相同,它直接使用目标图像的透明度作为源图像的透明度
//当透明度时是100%或者0时,SRC_ATOP和SRC_IN是通用的,当透明度不是SRC_ATOP和SRC_IN时,SRC_ATOP相比SRC_IN源图像饱和度会增加
[Da, Sc * Da + (1 - Sa) * Dc]

混合模式(二)_Android 自定义动画_05

目标图像模式和其他模式:

  • 目标图像模式:在SRC的相关模式中,处理相交区域,优先以源图像显示为主,而在与DST相关模式中,在处理相交区域时,优先以目标图像显示为主。目标图像显示的模式有:Mode.DST, Mode.DST_IN, Mode.DST_OUT, Mode.DST_OVER, Mode.DST_ATOP,所以只需要将上述的代码中的目标图像与源图像的位置进行互调就可以了。
Mode.DST:
//全部以目标图像进行展示
[Da, Dc]
Mode.DST_IN:
//利用源图像的透明度来改变目标图像的透明度和饱和度,当源图像的透明度为0, 目标图像完全不显示
[Sa * Da, Sa * Dc]
Mode.DST_OUT:
//利用源图像的透明度的补值来改变目标图像的透明度和饱和度的
//当源图像的不透明度是100%,那么目标图像就是空白,如果源图像不透明度是0%,那么目标图像就是完全显示
[Da * (1-Sa), Dc * (1-Sa)]
Mode.DST_OVER:
//在源图像顶部绘制目标图像
[Sa + (1 - Sa) * Da, Rc = Dc + (1 - Da) * Sc]
Mode.DST_ATOP:
//DST_ATOP和DST_IN模式可以通用,但是DST_ATOP所产生的效果图在源图像 的头民发都不是0或者100%时,会比DST_IN模式产生的效果图更明亮
[Sa, Sa * Dc + Sc * (1 - Da)]
SRC与DST总结:
  • DST的相关模式完全可以使用SRC对应的模式来实现,只需将目标图像和源图像对调一下即可
  • 在SRC模式中,以显示源图像为主,通过目标图像的透明度来调节计算结果的透明渡河饱和度,而在DST模式中,通过源图像 的透明度来调节目标图像计算结果的透明度和饱和度
Mode.CLEAR:
//空白像素,也就是说源图像所在区域会变成空白像素,起到清空源图像所在区域的作用
[0, 0]
总结:

(1)目标图像和源图像混合,需不需要生成颜色的叠加块,如果需要,则从颜色的叠加相关模式中进行选择:Mode.ADD(饱和度相加),Mode.DARKEN(变暗), Mode.LIGHTEN(变亮)、Mode.MULTIPLY(正片叠底)、Mode.OVERLAY(叠加)、Mode.SCREEN(绿色)
(2)当不需要特效的时候,而是需要根据魔杖图片的透明像素来裁剪时,就需要使用SRC相关模式或者DST相关模式了,而SRC相关模式和DST相关模式时相通的,唯一不同的时决定当前那个图像是目标图像和源图像。
(3)当需要清空源图像的时候,使用Mode.CLEAR模式


标签:SRC,DST,模式,混合,Mode,图像,import,android
From: https://blog.51cto.com/u_13987312/5992412

相关文章

  • 设计模式(5)--适配器模式
    首先声明鸭子和火鸡的接口packageshipeiqi;publicinterfaceDuck{publicvoidgaga();publicvoidfly();}publicinterfaceTurkey{publicvoidgogo();......
  • ESP32 I2C 总线主模式通信程序
    一、概述这里主要是记录ESP32中进行I2C通行的基本程序,也可以说是I2C总线驱动程序,当然这里只是作为主模式,从模式我还没需要这个需求,以后有机会贴上。此笔记的主要目......
  • 创建型模式——前言
    注:所有知识来源于《设计模式:可复用软件面向对象的基础》创建型设计模式抽象了实例化过程,它们帮助一个系统独立于如何创建、组合和表示它的那些对象。一个类创建型模式使用......
  • memcached并发CAS模式
    ​​http://hudeyong926.iteye.com/blog/1463992​​应用场景分析:​​http://hudeyong926.iteye.com/blog/1172189​​如原来MEMCACHED中的KES的内容为A,客户端C1和客户端C2......
  • 24*8点 段码LCD液晶显示驱动控制电路(IC/芯片)-VK0192M 具省电模式,可兼容替代市面1622
    产品品牌:永嘉微电/VINKA产品型号:VK0192M封装形式:LQFP44概述:VK0192MLQFP44是一个点阵式存储映射的LCD驱动器,可支持最大192点(24SEGx8COM)的LCD屏。单片机可通过3/4线串行......
  • RabbitMQ的工作模式及原理(1)
    RabbitMQ的5大核心概念RabbitMQ的5大核心概念:Connection(连接)、Channel(信道)、Exchange(交换机)、Queue(队列)、Virtualhost(虚拟主机)。其中,中间的Broker表示RabbitMQ服务,每个......
  • 设计模式
    一、装饰器模式1.基本概念和功能装饰器模式能够实现从一个对象的外部来给对象添加功能,有非常灵活的扩展性,可以在对原来的代码毫无修改的前提下,为对象添加新功能。除此之外,装......
  • 设计模式-单例模式
     时间:2023/01/04 一.单例模式介绍作用:所谓类的单例设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得其对......
  • 极光笔记 | 当前最佳实践:Header Bidding 与瀑布流混合请求技术
    通过这篇文章您讲将了解:HeaderBidding的发展史Waterfall、HeaderBidding的逻辑及优劣势为什么说HeaderBidding与瀑布流混合请求技术是当前最佳实践PART01、H......
  • 三种异步模式(扫盲)&BackgroundWorker
    1.APM&EAP&TAP.NET支持三种异步编程模式分别为APM、EAP和TAP:1.基于事件的异步编程设计模式 (EAP,Event-basedAsynchronousPattern)EAP的编程模式的代码命名有以下特点: ......