•Android系统下的图片都是32位的位图
•Android下加载图片的大小是和图片的分辨率有关系的,因为每个像素点都要被存入到内存,所以,往往我们看图片只有1M多,但是放到手机上就会OOM异常 out of Memery
1. 如何在Android中加载大图片防止OOM异常呢??
具体步骤如下:
1.获取图片的信息类
ExifInterface exif = new ExifInterface("图片地址");
2.获取图片的宽高信息
int width = exif.getAttributeInt(ExifInterface.TAG_IMAGE_WIDTH, 0);
int height = exif.getAttributeInt(ExifInterface.TAG_IMAGE_LENGTH, 0);
3.获取到当前设备屏幕宽高
WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
int screenWidth = wm.getDefaultDisplay().getWidth();
int screenHeight = wm.getDefaultDisplay().getHeight();
4.创建一个选项条件
Options opts = new Options();
5.根据图片宽高和屏幕宽高的比例,确定图片缩放的值,这里通常会优先选择值比较大的,也可以选两者之间的中间值,然后设置进去
opts.inSampleSize = ?; //设置采样率
6.把图片创建出来
Bitmap bitmap = BitmapFactory.decodeFile("图片路径", opts);
小结:
只要选择合适的采样率inSampleSize去加载图片就不会发生OOM异常了!
2. Android中图片变换的步骤
将图片加载到Android应用中之后,免不了会对图片进行一系列变换操作,比如:平移,缩放,旋转…
下面推荐一个常规的操作步骤:
1.加载图片到内存中,获取bitmap对象
Bitmap srcBitmap = BitmapFactory.decodeFile("图片路径");
2.创建一个空的bitmap对象,大小和原来bitmap一样
Bitmap copyedBitmap = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), srcBitmap.getConfig());
3.创建画板
Canvas canvas = new Canvas("空白的bitmap");
4.创建画笔
Paint paint = new Paint();
5.创建matrix 矩阵,我们可以利用这个矩阵来做到图片的缩放,平移等操作
Matrix matrix = new Matrix();
//1. 按比例扩大扩展缩放
matrix.setScale(x轴比例, y轴比例);
//2. 平移
matrix.setTranslate(x轴偏移量, y轴偏移量);
//3. 旋转
matrix.setRotate(旋转角度, 围绕x轴点旋转, 围绕y轴点旋转);
//4. 镜面效果
matrix.setScale(-1, 1); //左右效果
matrix.postTranslate(srcBitmap.getWidth(), 0);
//如果想添加多个属性,后面的要用post,如果调用set会把前面的覆盖
//5. 倒影效果
matrix.setScale(1, -1); //上下效果
matrix.postTranslate(0, srcBitmap.getHeight());
6.作画
canvas.drawBitmap(原图, matrix, paint);
步骤小结:
1. 获取图片资源
2. 创建一个空白的原图副本,大小和原图一样
3. 创建画板
4. 创建画笔
5. 创建Matrix矩阵,设置对图片需要做的操作
6. 将步骤5操作后的图片画到画板上
市面上有一款经典的小游戏,叫做”撕衣服”, 这款游戏的实现原理就是遵循以上步骤实现的!!
核心API是:
bitmap.setPixel(x坐标,y坐标,要设置的颜色);//根据xy轴设置bitmap对应像素点的颜色值为透明
实现原理:
1.利用相对布局放两张图片,上面一张图片正常穿着衣服,下面一张图片不穿衣服.
2.通过以上API对上面一张图片进行操作,接触到的点全部变为透明,最终显示效果你懂得!!
<案例实现:美女撕衣服>
1.layout下的布局文件activity_main.xml
<LinearLayout 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"
android:orientation="vertical"
tools:context=".MainActivity" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<ImageView
android:id="@+id/iv_after"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:src="@drawable/after9"
/>
<ImageView
android:id="@+id/iv_pre"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
/>
RelativeLayout>
LinearLayout>
2.res/drawable-hdpi目录下放置图片资源和音效文件
3.包com.yashiro.dragclose包里面的MainActivtiy.java文件
package com.yashiro.dragclose;
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.media.AudioManager;
import android.media.SoundPool;
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_pre;
private Bitmap alterBitmap;
private SoundPool soundPool;
private int soundId;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
iv_pre=(ImageView) findViewById(R.id.iv_pre);
//加载音效
soundPool=new SoundPool(1, AudioManager.STREAM_MUSIC, 0);
//找到音效文件
soundId=soundPool.load(this, R.drawable.higirl, 1);
//获取原图的路径
Bitmap bitmap=BitmapFactory.decodeResource(getResources(), R.drawable.pre9);
//创建原图配置的空白副本
// 修改位图的配置信息(带有透明度alpha,兼容Android2.3低版本)Bitmap.Config.ARGB_8888
alterBitmap=Bitmap.createBitmap(bitmap.getWidth(),bitmap.getHeight(),bitmap.getConfig().ARGB_8888);
//创建画板
final Canvas canvas=new Canvas(alterBitmap);
//创建画笔
Paint paint=new Paint();
//将原图临摹到画板上
canvas.drawBitmap(bitmap, new Matrix(), paint);
//将临摹后的图像放到界面上
iv_pre.setImageBitmap(alterBitmap);
//设置图片的触摸事件. 触摸之处都是透明的
iv_pre.setOnTouchListener(new OnTouchListener() {
//定义触摸到时的坐标
int x;
int y;
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
//播放音效
soundPool.play(soundId, 1.0f, 1.0f, 0, 0, 1.1f);
x=(int) event.getX();
y=(int) event.getY();
//触摸到的地方都是透明的. 用半径为10的原点操作
dragClose(x,y,10);
break;
case MotionEvent.ACTION_UP:
break;
}
return true; //空间自己处理,事件结束就销毁
}
/**
* 撕衣服的方法
*/
private void dragClose(int x,int y, int radius) {
for(int i=-radius;i1;i++){
for (int j = -radius; j < radius+1; j++) {
if (Math.sqrt(i*i+j*j)<=radius) {
if ((x+i)0&&(y+j)0) {
alterBitmap.setPixel(x+i, y+j, Color.TRANSPARENT);
}
}
}
}
iv_pre.setImageBitmap(alterBitmap);
}
});
}
}
1.严格按照Android图片变换的5步获取到图片资源并进行透明处理
2.利用iv_pre.setOnTouchListener(listener), 这个触摸监听事件,实现所触之处皆为透明.
3.最后将上层透明操作之后的图片设置到下层图片之上.
4.利用SoundPool实现触摸图片时发出音效的效果. 感觉很赞呀!!
以上,请各位大侠们指点,点拨~~~