天天看點

19_Android中圖檔處理原理篇,關于人臉識别網站,圖檔加載到記憶體,圖檔縮放,圖檔翻轉倒置,網上撕衣服遊戲案例編寫

(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);

如果圖檔太大,會出現的以下的問題:

19_Android中圖檔處理原理篇,關于人臉識别網站,圖檔加載到記憶體,圖檔縮放,圖檔翻轉倒置,網上撕衣服遊戲案例編寫

2 根據目前螢幕分辨率的大小,加載圖檔

display currentdisplay = getwindowmanager().getdefaultdisplay();

int dw = currentdisplay.getwidth();

int dh = currentdisplay.getheight();

bmpfactoryoptions.injustdecodebounds = true;

//通過下面的代碼計算縮放比,那個方向的縮放比大,就按照這把方向的縮放比來縮放。

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資訊寫到檔案:

ei.setattribute("imagedescription","something new");

4 從gallery擷取一個圖檔

intent intent = new intent(intent.action_pick);

intent.settype(“image/*”);

intent.getdata() 擷取image的uri

bitmap bmp = bitmapfactory.decodestream(getcontentresolver().

openinputstream(imagefileuri), null, bmpfactoryoptions);

5 建立bitmap拷貝

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.setrotate(15);

canvas.drawbitmap(bmp, matrix, paint);

消除鋸齒

paint.setantialias(true);  

指定圓心的旋轉

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

12 變換圖像的亮度

float contrast = 2;

contrast, 0, 0, 0, 0,

0, contrast, 0, 0, 0,

0, 0, contrast, 0, 0,

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

13 更改圖檔的飽和度:

cm.setsaturation(.5f);

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.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  場景:一張圖檔很大,放到手機上時需要對圖檔資源進行壓縮以及縮放,編寫如下界面的案例:

19_Android中圖檔處理原理篇,關于人臉識别網站,圖檔加載到記憶體,圖檔縮放,圖檔翻轉倒置,網上撕衣服遊戲案例編寫

2 操作:當點選加載圖檔到記憶體時,圖檔從自己的手機sd卡中取到并顯示。

3 adt開發時,手機連接配接上電腦後,在android開發工具中的”fileexplorer”中的檔案位置如下:

19_Android中圖檔處理原理篇,關于人臉識别網站,圖檔加載到記憶體,圖檔縮放,圖檔翻轉倒置,網上撕衣服遊戲案例編寫

4 下面開始編寫代碼,項目結構如下:

19_Android中圖檔處理原理篇,關于人臉識别網站,圖檔加載到記憶體,圖檔縮放,圖檔翻轉倒置,網上撕衣服遊戲案例編寫

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_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 圖像的拷貝,翻轉倒置。

要做如下效果(開始的效果圖):

19_Android中圖檔處理原理篇,關于人臉識别網站,圖檔加載到記憶體,圖檔縮放,圖檔翻轉倒置,網上撕衣服遊戲案例編寫

點選”拷貝一個位圖”之後的效果:

19_Android中圖檔處理原理篇,關于人臉識别網站,圖檔加載到記憶體,圖檔縮放,圖檔翻轉倒置,網上撕衣服遊戲案例編寫

2 編寫代碼,代碼結構如下:

19_Android中圖檔處理原理篇,關于人臉識别網站,圖檔加載到記憶體,圖檔縮放,圖檔翻轉倒置,網上撕衣服遊戲案例編寫

3 編寫布局檔案activity_main.xml

        android:text="拷貝一個位圖" />

        android:id="@+id/iv1"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content" />

        android:id="@+id/iv2"

4 編寫mainactivity,内容如下:

package com.itheima.copybitmap;

import android.graphics.canvas;

import android.graphics.color;

import android.graphics.matrix;

import android.graphics.paint;

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); //把原圖的副本設定到界面中

拷貝放大圖像的方式,隻需要将上面的click方法改成如下的方式:

/**

     * 建立原圖bm的拷貝。副本

     * @param 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);

運作效果圖如下:

19_Android中圖檔處理原理篇,關于人臉識别網站,圖檔加載到記憶體,圖檔縮放,圖檔翻轉倒置,網上撕衣服遊戲案例編寫

如果旋轉,隻需要将scale處的代碼換成:

m.setrotate(180, srcbmp.getwidth()/2,srcbmp.getheight()/2);

如果想變換顔色,需要将上面的代碼換成:

          * 建立原圖 bm的一個拷貝。副本

         public void click(view view){

                   //1.準備一個畫闆  在上面放上準備好的 空白的位圖

                   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));

                   iv2.setimagebitmap(alterbitmap);//把原圖的副本設定到界面上。

業務場景:

(1)、手指在一張美女圖檔上移動時,移動部分的圖檔會變成成透明,然後顯示底部的另外一張圖檔

(2)、當手指離開的時候播放音樂…

應用效果圖:

19_Android中圖檔處理原理篇,關于人臉識别網站,圖檔加載到記憶體,圖檔縮放,圖檔翻轉倒置,網上撕衣服遊戲案例編寫

1 編寫應用,代碼結構如下:

19_Android中圖檔處理原理篇,關于人臉識别網站,圖檔加載到記憶體,圖檔縮放,圖檔翻轉倒置,網上撕衣服遊戲案例編寫

2、編寫布局檔案activity_main.xml

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

        android:layout_centerhorizontal="true"

        android:layout_centervertical="true"

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

        android:id="@+id/iv"

        android:layout_centervertical="true"/>

</relativelayout>

3、編寫mainactivity

package com.itheima.play;

import android.media.mediaplayer;

import android.view.motionevent;

import android.view.view.ontouchlistener;

    // 可以修改的位圖

    private bitmap alertbitmap;

    private canvas canvas;

       bitmap bitmap = bitmapfactory.decoderesource(getresources(),

              r.drawable.pre);

       // 建立一個空白的原圖的拷貝

       alertbitmap = bitmap.createbitmap(bitmap.getwidth(),

              bitmap.getheight(), bitmap.getconfig());

       canvas = new canvas(alertbitmap);

       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);

              case motionevent.action_up:// 手指離開螢幕

                  mediaplayer.create(getapplicationcontext(), r.raw.higirl).start();

              }

              return true;//可以重複循環的處理事件

           }

       });

4  android的清單檔案如下:

    package="com.itheima.play"

        android:theme="@style/apptheme" >

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

            android:label="@string/app_name" >



繼續閱讀