您现在的位置是:首页 > 文章详情

19_Android中图片处理原理篇,关于人脸识别网站,图片加载到内存,图片缩放,图片翻转倒置,网上撕衣服游戏案例编写

日期:2015-07-18点击:474

1 加载图片到内存

1.数码相机照片特别是大于3m以上的,内存吃不消,会报OutOfMemoryError,若是想只显示原图片的1/8,可以通过BitmapFactory.Options来实现,具体代码如下:

BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();

bmpFactoryOptions.inSampleSize = 8;

Bitmap bmp = BitmapFactory.decodeFile(imageFilePath, bmpFactoryOptions);

imv.setImageBitmap(bmp);

如果图片太大,会出现的以下的问题:

2 根据当前屏幕分辨率的大小,加载图片

Display currentDisplay = getWindowManager().getDefaultDisplay();

int dw = currentDisplay.getWidth();

int dh = currentDisplay.getHeight();

 

BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();

bmpFactoryOptions.inJustDecodeBounds = true;

Bitmap bmp = BitmapFactory.decodeFile(imageFilePath, bmpFactoryOptions);

//通过下面的代码计算缩放比,那个方向的缩放比大,就按照这把方向的缩放比来缩放。

int heightRatio = (int)Math.ceil(bmpFactoryOptions.outHeight/(float)dh);

int widthRatio = (int)Math.ceil(bmpFactoryOptions.outWidth/(float)dw);

Log.v("HEIGHTRATIO",""+heightRatio);

Log.v("WIDTHRATIO",""+widthRatio);

 

//判断是否要进行缩放

if (heightRatio > 1 && widthRatio > 1)

{

if (heightRatio > widthRatio)

{

//高度变化大,按高度缩放

bmpFactoryOptions.inSampleSize = heightRatio;

}

else

{

// 宽度变化大,按宽度缩放

bmpFactoryOptions.inSampleSize = widthRatio;

}

}

bmpFactoryOptions.inJustDecodeBounds = false;

bmp = BitmapFactory.decodeFile(imageFilePath, bmpFactoryOptions);

3 获取Exif图片信息

//从文件获取exif信息

ExifInterface ei = new ExifInterface(imageFilePath);

String imageDescription = ei.getAttribute("ImageDescription");

if (imageDescription != null)

{

Log.v("EXIF", imageDescription);

}

//exif信息写到文件:

ExifInterface ei = new ExifInterface(imageFilePath);

ei.setAttribute("ImageDescription","Something New");

4 gallery获取一个图片

Intent intent = new Intent(Intent.ACTION_PICK);

intent.setType(“image/*”);

intent.getData() 获取imageuri

Bitmap bmp = BitmapFactory.decodeStream(getContentResolver().

openInputStream(imageFileUri), null, bmpFactoryOptions);

5 创建bitmap拷贝

Bitmap bmp = BitmapFactory.decodeStream(getContentResolver().

openInputStream(imageFileUri), null, bmpFactoryOptions);

Bitmap alteredBitmap = Bitmap.createBitmap(bmp.getWidth(),bmp.getHeight(),

bmp.getConfig());

Canvas canvas = new Canvas(alteredBitmap);

Paint paint = new Paint();

canvas.drawBitmap(bmp, 0, 0, paint);

6 图形缩放

Matrix matrix = new Matrix();

matrix.setValues(new float[] {

         1, 0, 0,

         0, 1, 0,

         0, 0, 1

});

x = 1x + 0y + 0z

y = 0x + 1y + 0z

z = 0x + 0y + 1z

通过canvas.drawBitmap(bmp, matrix, paint);创建bitmap

1.水平缩放0.5

2.垂直拉扯2

matrix.setScale(1.5f,1);//水平点放大到1.5f,垂直1

7 图形旋转

Matrix matrix = new Matrix();

matrix.setRotate(15);

canvas.drawBitmap(bmp, matrix, paint);

消除锯齿

paint.setAntiAlias(true);  

指定圆心的旋转

matrix.setRotate(15,bmp.getWidth()/2,bmp.getHeight()/2);

Matrix matrix = new Matrix();

matrix.setRotate(15,bmp.getWidth()/2,bmp.getHeight()/2);

alteredBitmap = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(),

matrix, false);

alteredImageView.setImageBitmap(alteredBitmap);

8 图像平移:

setTranslate(1.5f,-10);

9 镜子效果:

matrix.setScale(-1, 1);

matrix.postTranslate(bmp.getWidth(),0);

10 倒影效果:

matrix.setScale(1, -1);

matrix.postTranslate(0, bmp.getHeight());

11 图像颜色处理:

颜色矩阵  ColorMatrix cm = new ColorMatrix();

paint.setColorFilter(new ColorMatrixColorFilter(cm));

1 0 0 0 0

0 1 0 0 0

0 0 1 0 0

0 0 0 1 0

New Red Value = 1*128 + 0*128 + 0*128 + 0*0 + 0

New Blue Value = 0*128 + 1*128 + 0*128 + 0*0 + 0

New Green Value = 0*128 + 0*128 + 1*128 + 0*0 + 0

New Alpha Value = 0*128 + 0*128 + 0*128 + 1*0 + 0

ColorMatrix cm = new ColorMatrix();

cm.set(new float[] {

2, 0, 0, 0, 0,

0, 1, 0, 0, 0,

0, 0, 1, 0, 0,

0, 0, 0, 1, 0

});

paint.setColorFilter(new ColorMatrixColorFilter(cm));

12 变换图像的亮度

ColorMatrix cm = new ColorMatrix();

float contrast = 2;

cm.set(new float[] {

contrast, 0, 0, 0, 0,

0, contrast, 0, 0, 0,

0, 0, contrast, 0, 0,

0, 0, 0, 1, 0 });

paint.setColorFilter(new ColorMatrixColorFilter(cm));

12 变换图像的亮度

ColorMatrix cm = new ColorMatrix();

float contrast = 2;

cm.set(new float[] {

contrast, 0, 0, 0, 0,

0, contrast, 0, 0, 0,

0, 0, contrast, 0, 0,

0, 0, 0, 1, 0 });

paint.setColorFilter(new ColorMatrixColorFilter(cm));

13 更改图片的饱和度:

ColorMatrix cm = new ColorMatrix();

cm.setSaturation(.5f);

paint.setColorFilter(new ColorMatrixColorFilter(cm));

14 图像合成:

Bitmap drawingBitmap = Bitmap.createBitmap(bmp1.getWidth(),bmp1.getHeight(), bmp1.getConfig());

canvas = new Canvas(drawingBitmap);

paint = new Paint();

canvas.drawBitmap(bmp1, 0, 0, paint);

paint.setXfermode(new PorterDuffXfermode(android.graphics.PorterDuff.Mode.MULTIPLY));

canvas.drawBitmap(bmp2, 0, 0, paint);

15 按指定path上绘制文字

Paint paint = new Paint();

paint.setColor(Color.GREEN);

paint.setTextSize(20);

paint.setTypeface(Typeface.DEFAULT);

Path p = new Path();

p.moveTo(20, 20);

p.lineTo(100, 150);

p.lineTo(200, 220);

canvas.drawTextOnPath("Hello this is text on a path", p, 0, 0, paint);

16 人脸识别

FaceDetector detector = new FaceDetector(faceBitmap.getWidth(),

faceBitmap.getHeight(), 3); // 创建识别器

mNumFaces = detector.findFaces(faceBitmap, mFaces);   

// 识别

if (mNumFaces > 0) {

     for (int i = 0; i < mNumFaces; i++) {

         handleFace(mFaces[i]);     

         //调用函数对人脸画面进行处理

     }

}

关于人脸识别部分(网站地址是):

http://www.faceplusplus.com/

 

============================================================================

1  场景:一张图片很大,放到手机上时需要对图片资源进行压缩以及缩放,编写如下界面的案例:

2 操作:当点击加载图片到内存时,图片从自己的手机sd卡中取到并显示。

3 ADT开发时,手机连接上电脑后,在Android开发工具中的”FileExplorer”中的文件位置如下:

4 下面开始编写代码,项目结构如下:

5 编写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" >

 

    <Button

        android:onClick="click"

        android:layout_width="fill_parent"

        android:layout_height="wrap_content"

        android:text="加载图片到内存" />

 

    <ImageView

        android:id="@+id/iv"

        android:layout_width="fill_parent"

        android:layout_height="fill_parent" />

 

</LinearLayout>

6 编写MainActivity,代码如下:

package com.itheima.loadimg;

 

import android.app.Activity;

import android.graphics.Bitmap;

import android.graphics.BitmapFactory;

import android.graphics.BitmapFactory.Options;

import android.os.Bundle;

import android.view.View;

import android.view.WindowManager;

import android.widget.ImageView;

 

public class MainActivity extends Activity {

    private ImageView iv;

 

    @Override

    protected void onCreate(Bundle savedInstanceState) {

       super.onCreate(savedInstanceState);

       setContentView(R.layout.activity_main);

       iv = (ImageView) findViewById(R.id.iv);

    }

 

    public void click(View view) {

       // 相当消耗内存资源 根据图片的分辨率而定

       // Bitmap bitmap = BitmapFactory.decodeFile("/mnt/sdcard/photo.jpg");

       // iv.setImageBitmap(bitmap);

 

       // 1.得到屏幕的宽高信息

       WindowManager wm = getWindowManager();

       int screenWidth = wm.getDefaultDisplay().getWidth();

       int screenHeight = wm.getDefaultDisplay().getHeight();

       System.out.println("屏幕宽高:" + screenWidth + "-" + screenHeight);

 

       // 2.得到图片的宽高。

       BitmapFactory.Options opts = new Options();// 解析位图的附加条件

       opts.inJustDecodeBounds = true;// 不去解析真实的位图,只是获取这个位图的头文件信息

       Bitmap bitmap = BitmapFactory.decodeFile("/mnt/sdcard2/photo.jpg", opts);

       int bitmapWidth = opts.outWidth;

       int bitmapHeight = opts.outHeight;

       System.out.println("图片宽高: " + bitmapWidth + "-" + bitmapHeight);

 

       // 3.计算缩放比例

       int dx = bitmapWidth / screenWidth;

       int dy = bitmapHeight / screenHeight;

       int scale = 1;

       if (dx > dy && dy > 1) {

           System.out.println("按照水平方法缩放,缩放比例:" + dx);

           scale = dx;

       }

 

       if (dy > dx && dx > 1) {

           System.out.println("按照垂直方法缩放,缩放比例:" + dy);

           scale = dy;

       }

       // 4.缩放加载图片到内存。

       opts.inSampleSize = scale;

       opts.inJustDecodeBounds = false;// 真正的去解析这个位图。

       bitmap = BitmapFactory.decodeFile("/mnt/sdcard2/photo.jpg", opts);

       iv.setImageBitmap(bitmap);

    }

}

7 编写AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

    package="com.itheima.loadimg"

    android:versionCode="1"

    android:versionName="1.0" >

 

    <uses-sdk

        android:minSdkVersion="8"

        android:targetSdkVersion="19" />

 

    <application

        android:allowBackup="true"

        android:icon="@drawable/ic_launcher"

        android:label="@string/app_name"

        android:theme="@style/AppTheme" >

        <activity

            android:name="com.itheima.loadimg.MainActivity"

            android:label="@string/app_name" >

            <intent-filter>

                <action android:name="android.intent.action.MAIN" />

 

                <category android:name="android.intent.category.LAUNCHER" />

            </intent-filter>

        </activity>

    </application>

 

</manifest>

=============================================================================

1 图像的拷贝,翻转倒置。

要做如下效果(开始的效果图):

点击拷贝一个位图之后的效果:

2 编写代码,代码结构如下:

3 编写布局文件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" >

   

    <Button

        android:layout_width="fill_parent"

        android:layout_height="wrap_content"

        android:onClick="click"

        android:text="拷贝一个位图" />

 

    <ImageView

        android:id="@+id/iv1"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content" />

 

    <ImageView

        android:id="@+id/iv2"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content" />

   

</LinearLayout>

4 编写MainActivity,内容如下:

package com.itheima.copybitmap;

 

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.View;

import android.widget.ImageView;

 

public class MainActivity extends Activity {

         private ImageView iv1,iv2;

         private Bitmap alterBitmap;

         private Bitmap srcBmp;

        

         @Override

         protected void onCreate(Bundle savedInstanceState) {

                   super.onCreate(savedInstanceState);

                   setContentView(R.layout.activity_main);

        

                   iv1 = (ImageView) findViewById(R.id.iv1);

                   iv2 = (ImageView) findViewById(R.id.iv2);

                   //给第一个imageview默认设置一个位图

                   srcBmp = BitmapFactory.decodeResource(getResources(), R.drawable.tomcat);

                   iv1.setImageBitmap(srcBmp);

                   //创建原图的一个副本。 可修改  创建的是一个空白的图形。

                   alterBitmap = Bitmap.createBitmap(srcBmp.getWidth(), srcBmp.getHeight(),srcBmp.getConfig());

         }

        

         /**

          * 创建原图  bm的一个拷贝。副本

          * @param view

          */

         public void click(View view) {

                   //1.准备一个画板   在上面放上准备好的  空白的位图

                   Canvas canvas = new Canvas(alterBitmap);

                   //2.准备一个画笔

                   Paint paint = new Paint();

                   paint.setColor(Color.BLACK);

                   //3.画画

                   Matrix m = new Matrix();

                   m.setScale(1.0f, -1.0f);

                   m.postTranslate(0, srcBmp.getHeight());

                   canvas.drawBitmap(srcBmp, m, paint);

                   iv2.setImageBitmap(alterBitmap); //把原图的副本设置到界面中

         }

}

 

  1. 拷贝放大图像的方式,只需要将上面的Click方法改成如下的方式:

/**

     * 创建原图bm的拷贝。副本

     * @param view

     */

    public void click(View view) {

       //1.准备一个画板   在上面放上准备好的   空白的位图

       Canvas canvas = new Canvas(alterBitmap);

       //2.准备一个画笔

       Paint paint = new Paint();

       paint.setColor(Color.BLACK);

       //3.画画

       Matrix m = new Matrix();

       m.setScale(2.0f, 2.0f);

       canvas.drawBitmap(srcBmp, m, paint);

       //把原图的副本设置到界面上。

       iv2.setImageBitmap(alterBitmap);

    }

运行效果图如下:

如果旋转,只需要将Scale处的代码换成:

m.setRotate(180, srcBmp.getWidth()/2,srcBmp.getHeight()/2);

如果想变换颜色,需要将上面的代码换成:

/**

          * 创建原图 bm的一个拷贝。副本

          * @param view

          */

         public void click(View view){

                   //1.准备一个画板  在上面放上准备好的 空白的位图

                   Canvas canvas = new Canvas(alterBitmap);

                   //2.准备一个画笔

                   Paint paint = new Paint();

                   paint.setColor(Color.BLACK);

                   //3.画画

                   Matrix m = new Matrix();

                  

                   ColorMatrix cm = new ColorMatrix();

                   cm.set(new float[] {

                   0.5f, 0, 0, 0, 0,

                   0, 0.8f, 0, 0, 0,

                   0, 0, 0.6f, 0, 0,

                   0, 0, 0, 1, 0

                   });

                   paint.setColorFilter(new ColorMatrixColorFilter(cm));

                   canvas.drawBitmap(srcBmp, m, paint);

                   iv2.setImageBitmap(alterBitmap);//把原图的副本设置到界面上。

         }

 

业务场景:

1)、手指在一张美女图片上移动时,移动部分的图片会变成成透明,然后显示底部的另外一张图片

2)、当手指离开的时候播放音乐

应用效果图:

1 编写应用,代码结构如下:

2、编写布局文件activity_main.xml

<RelativeLayout 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=".MainActivity" >

 

    <ImageView

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:layout_centerHorizontal="true"

        android:layout_centerVertical="true"

        android:src="@drawable/after" />

 

    <ImageView

        android:id="@+id/iv"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:layout_centerHorizontal="true"

        android:layout_centerVertical="true"/>

 

</RelativeLayout>

3、编写MainActivity

package com.itheima.play;

 

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.MediaPlayer;

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;

 

    @Override

    protected void onCreate(Bundle savedInstanceState) {

       super.onCreate(savedInstanceState);

       setContentView(R.layout.activity_main);

       iv = (ImageView) findViewById(R.id.iv);

       Bitmap bitmap = BitmapFactory.decodeResource(getResources(),

              R.drawable.pre);

       // 创建一个空白的原图的拷贝

       alertBitmap = Bitmap.createBitmap(bitmap.getWidth(),

              bitmap.getHeight(), bitmap.getConfig());

       canvas = new Canvas(alertBitmap);

       Paint paint = new Paint();

       paint.setColor(Color.BLACK);

       canvas.drawBitmap(bitmap, new Matrix(), paint);

       iv.setImageBitmap(alertBitmap);

       iv.setOnTouchListener(new OnTouchListener() {

           @Override

           public boolean onTouch(View v, MotionEvent event) {

              switch (event.getAction()) {

              case MotionEvent.ACTION_DOWN:// 手指按下屏幕

                  System.out.println("action down");

                  break;

              case MotionEvent.ACTION_MOVE:// 手指在屏幕上移动

                  int x = (int) event.getX();

                  int y = (int) event.getY();

                  System.out.println("设置("+x+","+y+")透明颜色");

                  for(int i=-4;i<5;i++){

                     for(int j=-4;j<5;j++){

                         try{

                         alertBitmap.setPixel(x+i, y+j, Color.TRANSPARENT);

                         } catch (Exception e) {

                            e.printStackTrace();

                         }

                     }

                  }

                  iv.setImageBitmap(alertBitmap);

                  break;

              case MotionEvent.ACTION_UP:// 手指离开屏幕

                  MediaPlayer.create(getApplicationContext(), R.raw.higirl).start();

                  break;

              }

              return true;//可以重复循环的处理事件

           }

       });

    }

}

4  Android的清单文件如下:

<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

    package="com.itheima.play"

    android:versionCode="1"

    android:versionName="1.0" >

 

    <uses-sdk

        android:minSdkVersion="8"

        android:targetSdkVersion="19" />

 

    <application

        android:allowBackup="true"

        android:icon="@drawable/ic_launcher"

        android:label="@string/app_name"

        android:theme="@style/AppTheme" >

        <activity

            android:name="com.itheima.play.MainActivity"

            android:label="@string/app_name" >

            <intent-filter>

                <action android:name="android.intent.action.MAIN" />

 

                <category android:name="android.intent.category.LAUNCHER" />

            </intent-filter>

        </activity>

    </application>

 

</manifest>

 


原文链接:https://yq.aliyun.com/articles/101171
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章