[Android] 使用Matrix矩陣類對映像進行縮放、旋轉、對比、亮度處理

來源:互聯網
上載者:User

標籤:android   影像處理   matrix   colormatrix   旋轉移動   

    前一篇文章講述了Android拍照、、儲存並顯示在ImageView控制項中,該篇文章繼續講述Android影像處理技術,主要操作包括:通過開啟相簿裡的圖片,使用Matrix對映像進行縮放、旋轉、移動、對比、亮度、飽和度操作,希望對大家有所協助.

一. 顯示開啟圖片

    首先,設定activity_main.xml布局如下所示:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:id="@+id/container"    android:layout_width="match_parent"    android:layout_height="wrap_content"    tools:context="com.example.cangeimagetest.MainActivity"    tools:ignore="MergeRootFrame" >        <LinearLayout         android:layout_width="match_parent"    android:layout_height="wrap_content"    android:orientation="vertical" >        <Button        android:id="@+id/button1"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="選擇圖片" />    <TextView        android:id="@+id/textView1"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:visibility="invisible"        android:text="原圖顯示" />    <ImageView        android:id="@+id/imageView1"        android:layout_width="wrap_content"        android:layout_gravity="center_horizontal"        android:layout_height="wrap_content" />    <TextView        android:id="@+id/textView2"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:visibility="invisible"        android:text="變化後的圖片" />    <ImageView        android:id="@+id/imageView2"        android:layout_gravity="center_horizontal"        android:layout_marginBottom="20dp"         android:layout_width="wrap_content"        android:layout_height="wrap_content" />    </LinearLayout>        <LinearLayout         android:layout_width="match_parent"    android:layout_height="wrap_content"    android:orientation="horizontal"    android:layout_alignParentBottom="true" >        <Button        android:id="@+id/button2"        android:layout_width="wrap_content"        android:layout_height="match_parent"        android:layout_weight="1"        android:text="縮小" />        <Button        android:id="@+id/button3"        android:layout_width="wrap_content"        android:layout_height="match_parent"        android:layout_weight="1"        android:text="放大" />        <Button        android:id="@+id/button4"        android:layout_width="wrap_content"        android:layout_height="match_parent"        android:layout_weight="1"        android:text="旋轉" />        <Button        android:id="@+id/button5"        android:layout_width="wrap_content"        android:layout_height="match_parent"        android:layout_weight="1"        android:text="飽和" />        <Button        android:id="@+id/button6"        android:layout_width="wrap_content"        android:layout_height="match_parent"        android:layout_weight="1"        android:text="對比" />    </LinearLayout></RelativeLayout>

    然後,在Mainctivity.java中public class MainActivity extends Activity函數添加代碼如下:

private Button selectBn;private ImageView imageShow;private ImageView imageCreate;private TextView textview1;private TextView textview2;private Bitmap bmp; //原始圖片@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    selectBn = (Button) findViewById(R.id.button1);    imageShow = (ImageView) findViewById(R.id.imageView1);    imageCreate = (ImageView) findViewById(R.id.imageView2);    textview1 = (TextView) findViewById(R.id.textView1);    textview2 = (TextView) findViewById(R.id.textView2);        //選擇圖片    selectBn.setOnClickListener(new OnClickListener() {    @Override    public void onClick(View v) {    Intent intent = new Intent(Intent.ACTION_PICK,     android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);    startActivityForResult(intent, 0 );    }    });    if (savedInstanceState == null) {        getFragmentManager().beginTransaction()                .add(R.id.container, new PlaceholderFragment())                .commit();    }}//顯示兩張圖片protected void onActivityResult(int requestCode, int resultCode, Intent data) {  super.onActivityResult(requestCode, resultCode, data);if(resultCode==RESULT_OK) {ShowPhotoByImageView(data);     //顯示照片CreatePhotoByImageView();          //建立圖片}}

    再調用自訂函數實現顯示圖片:

//自訂函數 顯示開啟的照片在ImageView1中public void ShowPhotoByImageView(Intent data) {Uri imageFileUri = data.getData();DisplayMetrics dm = new DisplayMetrics();getWindowManager().getDefaultDisplay().getMetrics(dm);int width = dm.widthPixels;    //手機螢幕水平解析度int height = dm.heightPixels;  //手機螢幕垂直解析度Log.v("height", ""+height );Log.v("width", ""+width);try {// Load up the image's dimensions not the image itselfBitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();bmpFactoryOptions.inJustDecodeBounds = true;bmp = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageFileUri), null, bmpFactoryOptions);int heightRatio = (int)Math.ceil(bmpFactoryOptions.outHeight/(float)height);int widthRatio = (int)Math.ceil(bmpFactoryOptions.outWidth/(float)width);Log.v("bmpheight", ""+bmpFactoryOptions.outHeight);Log.v("bmpheight", ""+bmpFactoryOptions.outWidth);if(heightRatio>1&&widthRatio>1) {if(heightRatio>widthRatio) {bmpFactoryOptions.inSampleSize = heightRatio*2;}else {bmpFactoryOptions.inSampleSize = widthRatio*2;}} //映像真正解碼       bmpFactoryOptions.inJustDecodeBounds = false;              bmp = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageFileUri), null, bmpFactoryOptions);      imageShow.setImageBitmap(bmp); //將剪裁後照片顯示出來      textview1.setVisibility(View.VISIBLE);} catch(FileNotFoundException e) {e.printStackTrace();}}//建立第二張圖片並顯示public void CreatePhotoByImageView() {try {    Bitmap createBmp = Bitmap.createBitmap(bmp.getWidth(), bmp.getHeight(), bmp.getConfig());    Canvas canvas = new Canvas(createBmp); //畫布 傳入位元影像用於繪製    Paint paint = new Paint(); //畫刷 改變顏色 對比等屬性    canvas.drawBitmap(bmp, 0, 0, paint);    //錯誤:沒有圖片 因為參數bmp寫成createBmp    imageCreate.setImageBitmap(createBmp);    textview2.setVisibility(View.VISIBLE);} catch(Exception e) {e.printStackTrace();}}

    顯示的效果如所示,該圖叫萊娜圖(Lenna),是影像處理中經常使用的範例圖.

二. Matrix操作

   然後通過Matrix對映像進行處理操作,在onCreate函數中添加點擊事件:

//縮小圖片Button button2=(Button)findViewById(R.id.button2);button2.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {SmallPicture();}});//放大圖片    Button button3=(Button)findViewById(R.id.button3);    button3.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {BigPicture();}});   //旋轉圖片Button button4=(Button)findViewById(R.id.button4);button4.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {TurnPicture();}});//圖片飽和度改變Button button5=(Button)findViewById(R.id.button5);button5.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {SaturationPicture();}});//圖片對比改變Button button6=(Button)findViewById(R.id.button6);button6.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {ContrastPicture();}});

    最後分別自訂函數各操作實現,代碼如下:

//縮小圖片private void SmallPicture() {Matrix matrix = new Matrix();//縮放區間 0.5-1.0if(smallbig>0.5f)smallbig=smallbig-0.1f;elsesmallbig=0.5f;//x y座標同時縮放matrix.setScale(smallbig,smallbig,bmp.getWidth()/2,bmp.getHeight()/2); Bitmap createBmp = Bitmap.createBitmap(bmp.getWidth(), bmp.getHeight(), bmp.getConfig());Canvas canvas = new Canvas(createBmp); //畫布 傳入位元影像用於繪製Paint paint = new Paint(); //畫刷 改變顏色 對比等屬性    canvas.drawBitmap(bmp, matrix, paint);    imageCreate.setBackgroundColor(Color.RED);    imageCreate.setImageBitmap(createBmp);    textview2.setVisibility(View.VISIBLE);    }  //放大圖片private void BigPicture() {Matrix matrix = new Matrix();//縮放區間 0.5-1.0if(smallbig<1.5f)smallbig=smallbig+0.1f;elsesmallbig=1.5f;//x y座標同時縮放matrix.setScale(smallbig,smallbig,bmp.getWidth()/2,bmp.getHeight()/2); Bitmap createBmp = Bitmap.createBitmap(bmp.getWidth(), bmp.getHeight(), bmp.getConfig());Canvas canvas = new Canvas(createBmp); Paint paint = new Paint(); canvas.drawBitmap(bmp, matrix, paint);imageCreate.setBackgroundColor(Color.RED);imageCreate.setImageBitmap(createBmp);textview2.setVisibility(View.VISIBLE);}//旋轉圖片private void TurnPicture() {Matrix matrix = new Matrix();turnRotate=turnRotate+15;//選擇角度 饒(0,0)點選擇 正數順時針 負數逆時針 中心旋轉matrix.setRotate(turnRotate,bmp.getWidth()/2,bmp.getHeight()/2); Bitmap createBmp = Bitmap.createBitmap(bmp.getWidth(), bmp.getHeight(), bmp.getConfig());Canvas canvas = new Canvas(createBmp); Paint paint = new Paint(); canvas.drawBitmap(bmp, matrix, paint);imageCreate.setBackgroundColor(Color.RED);imageCreate.setImageBitmap(createBmp);textview2.setVisibility(View.VISIBLE);}//改變映像飽和度private void SaturationPicture() {//設定飽和度 0表示灰階映像 大於1飽和度增加 0-1飽和度減小ColorMatrix cm = new ColorMatrix();cm.setSaturation(saturation);Paint paint = new Paint(); paint.setColorFilter(new ColorMatrixColorFilter(cm));//顯示圖片Matrix matrix = new Matrix();Bitmap createBmp = Bitmap.createBitmap(bmp.getWidth(), bmp.getHeight(), bmp.getConfig());Canvas canvas = new Canvas(createBmp); canvas.drawBitmap(bmp, matrix, paint);imageCreate.setImageBitmap(createBmp);textview2.setVisibility(View.VISIBLE);saturation=saturation+0.1f;if(saturation>=1.5f) {saturation=0f;}}//設定圖片對比private void ContrastPicture() {ColorMatrix cm = new ColorMatrix();float brightness = -25;  //亮度float contrast = 2;        //對比cm.set(new float[] {contrast, 0, 0, 0, brightness,0, contrast, 0, 0, brightness,0, 0, contrast, 0, brightness,0, 0, 0, contrast, 0});Paint paint = new Paint(); paint.setColorFilter(new ColorMatrixColorFilter(cm));//顯示圖片Matrix matrix = new Matrix();Bitmap createBmp = Bitmap.createBitmap(bmp.getWidth(), bmp.getHeight(), bmp.getConfig());Canvas canvas = new Canvas(createBmp); canvas.drawBitmap(bmp, matrix, paint);imageCreate.setImageBitmap(createBmp);textview2.setVisibility(View.VISIBLE);}

    同時自訂變數如下:

//圖片變換參數private float smallbig=1.0f;   //縮放比例private int turnRotate=0;       //旋轉度數private float saturation=0f;    //飽和度

    它的運行結果如所示:
   
   
   
    需要指出的是:該項目僅僅講述處理的過程,並沒有考慮很多因素,如:有的映像顯示可能超出螢幕,沒有載入圖片點擊處理按鈕報錯,橫豎屏切換導致不顯示圖片,最下面按鈕可能被遮擋,映像放大畫布沒有變,因為為認為顯示一張改變後的圖片效果更好,而該工程僅僅是對比.映像縮放移動觸屏變換更好,下一篇講述.
    XML布局推薦:http://www.apkbus.com/forum.php?mod=viewthread&tid=44949
    解決畫布跟著圖片放大:http://www.eoeandroid.com/thread-3162-1-1.html

三. Matrix處理的原理

    Android中可以通過Matrix和ColorMatrix對映像進行處理.
    1.Matrix
    映像空間變換,包括旋轉、剪裁、縮放或移動.Matrix類中每個數字都將應用於映像上每個點的3個座標x\y\z之一.
    如下代碼通過setValues設定值.(1,0,0)表示x座標轉換x=1x+0y+0z,同樣y=0x+1y+0z,z=0x+0y+1z.該矩陣不做任何變換.如果第一行改為(.5f,0,0),那麼映像在x軸上將映像壓縮50%.移動見setTranslate()函數.

Matrix matrix = new Matrix();matrix.setValues(new float[] {        1, 0, 0,        0, 1, 0,        0, 0, 1});

    2.ColorMatrix
    在Canvas(畫布)對象上繪製時既可使用Matrix方法,也可使用ColorMatrix來改變在Canvas對象上繪製的Paint(畫刷)對象.對映像的像素處理時,每個像素由RGBA值組成(Red Green Blue Alpha).具體方法推薦博文:http://www.cnblogs.com/leon19870907/articles/1978065.html
    最後希望該文章對大家有所協助,尤其是Android初學者.該文章是講述Android使用Matrix處理圖片的基礎文章,如果有不足或錯誤地方,請見諒~參考資料《Android多媒體開發進階編程 著:Shawn Van Every
    :
(By:Eastmount 2014-10-26 夜2點 http://blog.csdn.net/eastmount)
 

[Android] 使用Matrix矩陣類對映像進行縮放、旋轉、對比、亮度處理

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.