Android下的图形处理

•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对上面一张图片进行操作,接触到的点全部变为透明,最终显示效果你懂得!!

<案例实现:美女撕衣服>

  • 首先看看实现的效果(请保持平和的心态):

showResult
projectDir

  • 具体代码:

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实现触摸图片时发出音效的效果. 感觉很赞呀!!


以上,请各位大侠们指点,点拨~~~

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值