1.撕衣服的案例逻辑:

      是两者图片重叠在一起,上面我们看到的是美女穿衣服的图片,下面重叠(看不到的)是美女没有穿衣服的图片。当我们用手滑动画面,上面美女穿衣服的图片就会变成透明,这样的话下面美女没有穿衣服的图片就会显示出来。

2.根据工程实例,进行分析:

(1)首先我们分析布局文件,activity_main.xml,这里需要两张图片重叠覆盖,这里我们最好在根目录使用FrameLayout(帧布局),如下:

 <FrameLayout 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="com.himi.clothers.MainActivity" > <ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="@drawable/after19" /> <ImageView
android:id="@+id/iv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="@drawable/pre19" /> </FrameLayout>

注意这里两个ImageView的顺序不能颠倒,程序是顺序执行的,这样保证最后显示给用户的是美女穿衣服的图片(pre19.jpg)

布局效果如下:

(2)MainActivity.java,如下:

 package com.himi.clothers;

 import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.ImageView; public class MainActivity extends Activity {
private ImageView iv;
private Bitmap alertBitmap;//原图的拷贝,可以修改
private Canvas canvas;
private Paint paint;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
iv = (ImageView) findViewById(R.id.iv);
//创建原图的位图
Bitmap srcBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.pre19);
//创建原图的副本(拷贝)
alertBitmap = Bitmap.createBitmap(srcBitmap.getWidth(),srcBitmap.getHeight(),srcBitmap.getConfig());
//创建画布
canvas = new Canvas(alertBitmap);
//创建画笔
paint = new Paint();
//使用画笔绘画 参数1:原图 , 参数2:变化矩阵, 参数3:画笔
canvas.drawBitmap(srcBitmap, new Matrix(), paint);
//更新UI
iv.setImageBitmap(alertBitmap); iv.setOnTouchListener(new OnTouchListener() { public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_MOVE:
// 每次操作一个像素点,太慢了
// alertBitmap.setPixel((int)event.getX(),
// (int)event.getY(), Color.TRANSPARENT); // 我们希望每次触摸到屏幕点附近一个区域都可以实现这样的效果,使用双重for 循环即可 (区域是矩形)
for (int i = -3; i < 4; i++) {
for (int j = -3; j < 4; j++) {
// event.getX()、event.getY()坐标必须大于0,如果这里面event.getX()+i<0,就会报出IllegalArgumentException异常
try {
alertBitmap.setPixel((int) event.getX() + i,
(int) event.getY() + j,
Color.TRANSPARENT);
} catch (Exception e) {
// TODO: handle exception
} }
}
break;
}
// 更新UI,前面更改画面(画面参数发生变化),记得最后一定要重新刷新显示,这样才能看出更改后的画面
iv.setImageBitmap(alertBitmap);
return true;
} });
} }

手机程序中显示的图片、修改图片都是原图的拷贝,也就是说重启系统或者重启应用程序,图片还是原样。

得到原图拷贝和修改拷贝的逻辑思路:

(1)首先我们利用BitmapFactory.decodeResource这个API,把我们要把这些图片资源(png/jpg/bmp……)变成 Bitmap 位图对象:

         Bitmap srcBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.pre19);  

(2)上面得到srcBitmap是原图Bitmap的位图对象,这个是不能修改的(修改只能是拷贝),接下来就是临摹出原图srcBitmap的拷贝alertBitmap,如下:

         alertBitmap = Bitmap.createBitmap(srcBitmap.getWidth(),srcBitmap.getHeight(),srcBitmap.getConfig());

(3)利用上面获得的拷贝alertBitmap,获取对应的画布Canvas(画布),这里获得的画布对应着alertBitmap。

         canvas = new Canvas(alertBitmap);

(4)上面创建完画布,接下来创建画笔:

         paint = new Paint();

(5)接着画布对象canvas利用上面创建的画笔绘画,如下:

        canvas.drawBitmap(srcBitmap, new Matrix(), paint);

(6)绘画完毕,只是设置完了参数,要是显示给用户看,要更新UI,如下:

            iv.setImageBitmap(alertBitmap);  // 注意显示的是原图的拷贝alertBitmap(修改的是alertBitmap)

备注:setPixel:该函数将指定坐标处的像素设为指定的颜色

这里用户体验是,手指滑动,美女的身体是以矩形范围变透明的,如下:

这样的用户体验是不好,不自然的,我们希望是美女的身体是以圆形范围变透明的:

(3)如何实现美女的身体是以圆形范围变透明的

加一个逻辑判断皆可:

修改MainActivity,如下:

 package com.himi.clothers;

 import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.ImageView; public class MainActivity extends Activity {
private ImageView iv;
private Bitmap alertBitmap;//原图的拷贝,可以修改
private Canvas canvas;
private Paint paint;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
iv = (ImageView) findViewById(R.id.iv);
//创建原图的位图
Bitmap srcBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.pre19);
//创建原图的副本(拷贝)
alertBitmap = Bitmap.createBitmap(srcBitmap.getWidth(),srcBitmap.getHeight(),srcBitmap.getConfig());
//创建画布
canvas = new Canvas(alertBitmap);
//创建画笔
paint = new Paint();
//使用画笔绘画 参数1:原图 , 参数2:变化矩阵, 参数3:画笔
canvas.drawBitmap(srcBitmap, new Matrix(), paint);
//更新UI
iv.setImageBitmap(alertBitmap); iv.setOnTouchListener(new OnTouchListener() { public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_MOVE:
// 每次操作一个像素点,太慢了
// alertBitmap.setPixel((int)event.getX(),
// (int)event.getY(), Color.TRANSPARENT); // 我们希望每次触摸到屏幕点附近一个区域都可以实现这样的效果,使用双重for 循环即可 (区域是矩形)
for (int i = -3; i < 4; i++) {
for (int j = -3; j < 4; j++) {
if (Math.sqrt(i * i + j * j) <= 3) {
// event.getX()、event.getY()坐标必须大于0,如果这里面event.getX()+i<0,就会报出IllegalArgumentException异常
try {
alertBitmap.setPixel(
(int) event.getX() + i,
(int) event.getY() + j,
Color.TRANSPARENT);
} catch (Exception e) {
// TODO: handle exception
}
} }
}
break;
}
// 更新UI,前面更改画面(画面参数发生变化),记得最后一定要重新刷新显示,这样才能看出更改后的画面
iv.setImageBitmap(alertBitmap);
return true;
} });
} }

最新文章

  1. iOS 圆的放大动画效果
  2. [HTML] IE=edge,chrome=1的META标签详解
  3. Bootstrap Table表格一直加载(load)不了数据-解决办法
  4. [译]git reflog
  5. Android 下拉刷新
  6. Bootstap datetimepicker报错TypeError: intermediate value(转)
  7. SQL server 性能调优
  8. 线程暴长~Quartz中创建Redis频繁后导致线程暴长
  9. C++标准转换运算符const_cast
  10. 编写你的第一个 Django 程序 第2部分
  11. 李洪强漫谈iOS开发[C语言-014]-变量
  12. Java 原始数据类型
  13. 在Spring Boot中使用swagger-bootstrap-ui
  14. python学习日记(面向对象——继承)
  15. 【朝花夕拾】Android性能篇之(三)Java内存回收
  16. Java集合与泛型中的陷阱
  17. 多线程系列之十:Future模式
  18. python--第十四天总结(js)
  19. 命令行方式(SSH or powershell )远程windows server
  20. nginx 日志切割(也适用于docker)

热门文章

  1. Attribute操作的性能优化方式
  2. SQL语句处理一些修改、新增、删除、修改属性操作(MySql)
  3. jquery.validate 的ajax验证(转)
  4. Evolutionary Computing: 2. Genetic Algorithm(1)
  5. vim全选,全部复制,全部删除
  6. wpf4 文字 模糊 不清晰 解决方法
  7. 【转】数据库SQL优化大总结之 百万级数据库优化方案
  8. ASP.NET JSON的序列化和反序列化 之 Newtonsoft.Json
  9. MVC自学第一课
  10. .net程序员求职简历
  11. 利用Tkinter和matplotlib两种方式画饼状图
  12. Assets.car 解压工具 cartool 使用报错 segmentation fault cartool 解决方案
  13. scikit-learn 决策树 分类问题
  14. 乱码问题-页面跳转方式-Servlet配置文件
  15. grafna与饼状图
  16. Jmeter 常用断言使用
  17. (转)MySql 获取所有级联父级或所有级联子级
  18. 记一次Linux下数据统计
  19. 初涉定制linux系统之——rpm相关安装包的准备
  20. js处理url中的请求参数(编码/解码)