您的位置:首页 > 移动开发 > Android开发

Android下的图形处理

2016-12-20 13:38 274 查看
•Android系统下的图片都是32位的位图

•Android下加载图片的大小是和图片的分辨率有关系的,因为每个像素点都要被存入到内存,所以,往往我们看图片只有1M多,但是放到手机上就会OOM异常 out of Memery

Android图片操作技巧

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;i<radius+1;i++){
for (int j = -radius; j < radius+1; j++) {
if (Math.sqrt(i*i+j*j)<=radius) {
if ((x+i)<alterBitmap.getWidth()&&(x+i)>0&&(y+j)<alterBitmap.getHeight()&&(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实现触摸图片时发出音效的效果. 感觉很赞呀!!

以上,请各位大侠们指点,点拨~~~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: