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;
} });
} }

Android(java)学习笔记182:多媒体之撕衣服的案例的更多相关文章

  1. Android(java)学习笔记239:多媒体之撕衣服的案例

    1.撕衣服的案例逻辑:       是两者图片重叠在一起,上面我们看到的是美女穿衣服的图片,下面重叠(看不到的)是美女没有穿衣服的图片.当我们用手滑动画面,上面美女穿衣服的图片就会变成透明,这样的话下 ...

  2. Java学习笔记17(面向对象十:综合案例)

    在面向对象这个专题的最后 结合前面多篇文章,用到了面向对象的很多方面知识,做了一个简单的案例: 饭店案例: package hotel; /* * 酒店的员工类 * 员工共同特点:姓名,工号,工作方法 ...

  3. 0028 Java学习笔记-面向对象-Lambda表达式

    匿名内部类与Lambda表达式示例 下面代码来源于:0027 Java学习笔记-面向对象-(非静态.静态.局部.匿名)内部类 package testpack; public class Test1{ ...

  4. 《Java学习笔记(第8版)》学习指导

    <Java学习笔记(第8版)>学习指导 目录 图书简况 学习指导 第一章 Java平台概论 第二章 从JDK到IDE 第三章 基础语法 第四章 认识对象 第五章 对象封装 第六章 继承与多 ...

  5. Android动画学习笔记-Android Animation

    Android动画学习笔记-Android Animation   3.0以前,android支持两种动画模式,tween animation,frame animation,在android3.0中 ...

  6. Java学习笔记:语言基础

    Java学习笔记:语言基础 2014-1-31   最近开始学习Java,目的倒不在于想深入的掌握Java开发,而是想了解Java的基本语法,可以阅读Java源代码,从而拓展一些知识面.同时为学习An ...

  7. Android 数字签名学习笔记

    Android 数字签名学习笔记 在Android系统中,所有安装到系统的应用程序都必有一个数字证书,此数字证书用于标识应用程序的作者和在应用程序之间建立信任关系,如果一个permission的pro ...

  8. 【Java学习笔记之二十六】深入理解Java匿名内部类

    在[Java学习笔记之二十五]初步认知Java内部类中对匿名内部类做了一个简单的介绍,但是内部类还存在很多其他细节问题,所以就衍生出这篇博客.在这篇博客中你可以了解到匿名内部类的使用.匿名内部类要注意 ...

  9. 20145316许心远《Java学习笔记(第8版)》课程总结

    20145316许心远<Java学习笔记(第8版)>课程总结 每周读书笔记链接汇总 ▪ 第一周读书笔记 ▪ 第二周读书笔记 ▪ 第三周读书笔记 ▪ 第四周读书笔记 ▪ 第五周读书笔记 ▪ ...

随机推荐

  1. 【NOIP2014】 联合权值

    [题目链接] 点击打开链接 [算法] 如果(u,v)的距离为2,那么有两种可能 : 1.u和v为祖孙关系 2.u和v为兄弟关系 树形DP即可,详见代码 [代码] #include<bits/st ...

  2. javascript之表格节点操作

    <html> <div class='add'>             名字: <input type="" name=""&g ...

  3. HDFS之二:HDFS文件系统JavaAPI接口

    HDFS是存取数据的分布式文件系统,HDFS文件操作常有两种方式,一种是命令行方式,即Hadoop提供了一套与Linux文件命令类似的命令行工具.HDFS操作之一:hdfs命令行操作 另一种是Java ...

  4. bash 脚本编程七 将命令输出保存到变量中(转载)

    转自:http://blog.csdn.net/csfreebird/article/details/7978699 `符号包含的命令执行完后,可以讲其输出结果保存到变量中 #!/bin/bash v ...

  5. eclipse快捷键设置

    文章斋词水电费 55 48 Eclipse中10个最有用的快捷键组合  一个Eclipse骨灰级开发者总结了他认为最有用但又不太为人所知的快捷键组合.通过这些组合可以更加容易的浏览源代码,使得整体的开 ...

  6. POJ1787 【完全背包+物品计数+路径输出】

    题意: 有1,5,10,25四种硬币,给每种硬币的数量和要组合成的价值,求刚好达到价值时用的硬币最多,然后还要输出具体的用的数量 前言: 一开始是偶然看见了kuangbin爷的题解说是完全背包+路径, ...

  7. noip 2012 Day2 T2 借教室

    一.暴力简述 甩链接.jpeg 首先我们不难看出,这道题————并不是一道多难的题,因为显然,第一眼看题目时便很容易地想到暴力如何打:枚举每一种订单,然后针对每一种订单,对区间内的每一天进行修改(做减 ...

  8. Udp实现省略编码

    class My_Socket(socket.socket): def __init__(self, encoding='utf-8'): self.encoding = encoding super ...

  9. Hdu 5442 Favorite Donut (2015 ACM/ICPC Asia Regional Changchun Online 最大最小表示法 + KMP)

    题目链接: Hdu 5442 Favorite Donut 题目描述: 给出一个文本串,找出顺时针或者逆时针循环旋转后,字典序最大的那个字符串,字典序最大的字符串如果有多个,就输出下标最小的那个,如果 ...

  10. 模拟 Codeforces Round #297 (Div. 2) A. Vitaliy and Pie

    题目传送门 /* 模拟:这就是一道模拟水题,看到标签是贪心,还以为错了呢 题目倒是很长:) */ #include <cstdio> #include <algorithm> ...