zoukankan      html  css  js  c++  java
  • 19_Android中图片处理原理篇,关于人脸识别站点,图片载入到内存,图片缩放,图片翻转倒置,网上撕衣服游戏案例编写

    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>

     

    
  • 相关阅读:
    Selenium
    Selenium和ChromeDriver下载地址
    CQRS Event Sourcing介绍
    JAVA程序员面试30问(附带答案)
    拼多多、饿了么、蚂蚁金服Java面试题大集合
    40K刚面完Java岗,这些技术必须掌握
    接口测试之深入理解HTTPS
    选择了软件测试,你后悔吗?
    如何优雅的使用 Python 实现文件递归遍历
    刚从阿里回来,有些想法想跟测试员说说
  • 原文地址:https://www.cnblogs.com/zsychanpin/p/7256287.html
Copyright © 2011-2022 走看看