1.撕衣服的案例逻辑:
是两者图片重叠在一起,上面我们看到的是美女穿衣服的图片,下面重叠(看不到的)是美女没有穿衣服的图片。当我们用手滑动画面,上面美女穿衣服的图片就会变成透明,这样的话下面美女没有穿衣服的图片就会显示出来。
2.根据工程实例,进行分析:
(1)首先我们分析布局文件,activity_main.xml,这里需要两张图片重叠覆盖,这里我们最好在根目录使用FrameLayout(帧布局),如下:
1 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 tools:context="com.himi.clothers.MainActivity" > 6 7 <ImageView 8 android:layout_width="wrap_content" 9 android:layout_height="wrap_content" 10 android:layout_gravity="center" 11 android:src="@drawable/after19" /> 12 13 <ImageView 14 android:id="@+id/iv" 15 android:layout_width="wrap_content" 16 android:layout_height="wrap_content" 17 android:layout_gravity="center" 18 android:src="@drawable/pre19" /> 19 20 </FrameLayout>
注意这里两个ImageView的顺序不能颠倒,程序是顺序执行的,这样保证最后显示给用户的是美女穿衣服的图片(pre19.jpg)
布局效果如下:
(2)MainActivity.java,如下:
1 package com.himi.clothers; 2 3 import android.app.Activity; 4 import android.graphics.Bitmap; 5 import android.graphics.BitmapFactory; 6 import android.graphics.Canvas; 7 import android.graphics.Color; 8 import android.graphics.Matrix; 9 import android.graphics.Paint; 10 import android.os.Bundle; 11 import android.view.MotionEvent; 12 import android.view.View; 13 import android.view.View.OnTouchListener; 14 import android.widget.ImageView; 15 16 public class MainActivity extends Activity { 17 private ImageView iv; 18 private Bitmap alertBitmap;//原图的拷贝,可以修改 19 private Canvas canvas; 20 private Paint paint; 21 @Override 22 protected void onCreate(Bundle savedInstanceState) { 23 super.onCreate(savedInstanceState); 24 setContentView(R.layout.activity_main); 25 iv = (ImageView) findViewById(R.id.iv); 26 //创建原图的位图 27 Bitmap srcBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.pre19); 28 //创建原图的副本(拷贝) 29 alertBitmap = Bitmap.createBitmap(srcBitmap.getWidth(),srcBitmap.getHeight(),srcBitmap.getConfig()); 30 //创建画布 31 canvas = new Canvas(alertBitmap); 32 //创建画笔 33 paint = new Paint(); 34 //使用画笔绘画 参数1:原图 , 参数2:变化矩阵, 参数3:画笔 35 canvas.drawBitmap(srcBitmap, new Matrix(), paint); 36 //更新UI 37 iv.setImageBitmap(alertBitmap); 38 39 iv.setOnTouchListener(new OnTouchListener() { 40 41 public boolean onTouch(View v, MotionEvent event) { 42 switch (event.getAction()) { 43 case MotionEvent.ACTION_MOVE: 44 // 每次操作一个像素点,太慢了 45 // alertBitmap.setPixel((int)event.getX(), 46 // (int)event.getY(), Color.TRANSPARENT); 47 48 // 我们希望每次触摸到屏幕点附近一个区域都可以实现这样的效果,使用双重for 循环即可 (区域是矩形) 49 for (int i = -3; i < 4; i++) { 50 for (int j = -3; j < 4; j++) { 51 // event.getX()、event.getY()坐标必须大于0,如果这里面event.getX()+i<0,就会报出IllegalArgumentException异常 52 try { 53 alertBitmap.setPixel((int) event.getX() + i, 54 (int) event.getY() + j, 55 Color.TRANSPARENT); 56 } catch (Exception e) { 57 // TODO: handle exception 58 } 59 60 } 61 } 62 break; 63 } 64 // 更新UI,前面更改画面(画面参数发生变化),记得最后一定要重新刷新显示,这样才能看出更改后的画面 65 iv.setImageBitmap(alertBitmap); 66 return true; 67 } 68 69 }); 70 } 71 72 73 }
手机程序中显示的图片、修改图片都是原图的拷贝,也就是说重启系统或者重启应用程序,图片还是原样。
得到原图拷贝和修改拷贝的逻辑思路:
(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,如下:
1 package com.himi.clothers; 2 3 import android.app.Activity; 4 import android.graphics.Bitmap; 5 import android.graphics.BitmapFactory; 6 import android.graphics.Canvas; 7 import android.graphics.Color; 8 import android.graphics.Matrix; 9 import android.graphics.Paint; 10 import android.os.Bundle; 11 import android.view.MotionEvent; 12 import android.view.View; 13 import android.view.View.OnTouchListener; 14 import android.widget.ImageView; 15 16 public class MainActivity extends Activity { 17 private ImageView iv; 18 private Bitmap alertBitmap;//原图的拷贝,可以修改 19 private Canvas canvas; 20 private Paint paint; 21 @Override 22 protected void onCreate(Bundle savedInstanceState) { 23 super.onCreate(savedInstanceState); 24 setContentView(R.layout.activity_main); 25 iv = (ImageView) findViewById(R.id.iv); 26 //创建原图的位图 27 Bitmap srcBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.pre19); 28 //创建原图的副本(拷贝) 29 alertBitmap = Bitmap.createBitmap(srcBitmap.getWidth(),srcBitmap.getHeight(),srcBitmap.getConfig()); 30 //创建画布 31 canvas = new Canvas(alertBitmap); 32 //创建画笔 33 paint = new Paint(); 34 //使用画笔绘画 参数1:原图 , 参数2:变化矩阵, 参数3:画笔 35 canvas.drawBitmap(srcBitmap, new Matrix(), paint); 36 //更新UI 37 iv.setImageBitmap(alertBitmap); 38 39 iv.setOnTouchListener(new OnTouchListener() { 40 41 public boolean onTouch(View v, MotionEvent event) { 42 switch (event.getAction()) { 43 case MotionEvent.ACTION_MOVE: 44 // 每次操作一个像素点,太慢了 45 // alertBitmap.setPixel((int)event.getX(), 46 // (int)event.getY(), Color.TRANSPARENT); 47 48 // 我们希望每次触摸到屏幕点附近一个区域都可以实现这样的效果,使用双重for 循环即可 (区域是矩形) 49 for (int i = -3; i < 4; i++) { 50 for (int j = -3; j < 4; j++) { 51 if (Math.sqrt(i * i + j * j) <= 3) { 52 // event.getX()、event.getY()坐标必须大于0,如果这里面event.getX()+i<0,就会报出IllegalArgumentException异常 53 try { 54 alertBitmap.setPixel( 55 (int) event.getX() + i, 56 (int) event.getY() + j, 57 Color.TRANSPARENT); 58 } catch (Exception e) { 59 // TODO: handle exception 60 } 61 } 62 63 } 64 } 65 break; 66 } 67 // 更新UI,前面更改画面(画面参数发生变化),记得最后一定要重新刷新显示,这样才能看出更改后的画面 68 iv.setImageBitmap(alertBitmap); 69 return true; 70 } 71 72 }); 73 } 74 75 76 }