[Android] 使用Matrix矩阵类对图像进行缩放、旋转、对比度、亮度处理
??? 前一篇文章講述了Android拍照、截圖、保存并顯示在ImageView控件中,該篇文章繼續(xù)講述Android圖像處理技術(shù),主要操作包括:通過打開相冊里的圖片,使用Matrix對圖像進行縮放、旋轉(zhuǎn)、移動、對比度、亮度、飽和度操作,希望對大家有所幫助.
一. 顯示打開圖片
??? 首先,設(shè)置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" > <Buttonandroid:id="@+id/button1"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="選擇圖片" /><TextViewandroid:id="@+id/textView1"android:layout_width="match_parent"android:layout_height="wrap_content"android:visibility="invisible"android:text="原圖顯示" /><ImageViewandroid:id="@+id/imageView1"android:layout_width="wrap_content"android:layout_gravity="center_horizontal"android:layout_height="wrap_content" /><TextViewandroid:id="@+id/textView2"android:layout_width="match_parent"android:layout_height="wrap_content"android:visibility="invisible"android:text="變化后的圖片" /><ImageViewandroid: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" ><Buttonandroid:id="@+id/button2"android:layout_width="wrap_content"android:layout_height="match_parent"android:layout_weight="1"android:text="縮小" /><Buttonandroid:id="@+id/button3"android:layout_width="wrap_content"android:layout_height="match_parent"android:layout_weight="1"android:text="放大" /><Buttonandroid:id="@+id/button4"android:layout_width="wrap_content"android:layout_height="match_parent"android:layout_weight="1"android:text="旋轉(zhuǎn)" /><Buttonandroid:id="@+id/button5"android:layout_width="wrap_content"android:layout_height="match_parent"android:layout_weight="1"android:text="飽和" /><Buttonandroid: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函數(shù)添加代碼如下:
private Button selectBn; private ImageView imageShow; private ImageView imageCreate; private TextView textview1; private TextView textview2; private Bitmap bmp; //原始圖片@Override protected 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() {@Overridepublic 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(); //創(chuàng)建圖片} }??? 再調(diào)用自定義函數(shù)實現(xiàn)顯示圖片:
//自定義函數(shù) 顯示打開的照片在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();} } //創(chuàng)建第二張圖片并顯示 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); //錯誤:沒有圖片 因為參數(shù)bmp寫成createBmpimageCreate.setImageBitmap(createBmp);textview2.setVisibility(View.VISIBLE);} catch(Exception e) {e.printStackTrace();} }??? 顯示的效果如下圖所示,該圖叫萊娜圖(Lenna),是圖像處理中經(jīng)常使用的樣例圖.
?
二. Matrix操作
???然后通過Matrix對圖像進行處理操作,在onCreate函數(shù)中添加點擊事件:
//縮小圖片 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();}});//旋轉(zhuǎn)圖片 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();} });??? 最后分別自定義函數(shù)各操作實現(xiàn),代碼如下:
//縮小圖片 private void SmallPicture() {Matrix matrix = new Matrix();//縮放區(qū)間 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();//縮放區(qū)間 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); } //旋轉(zhuǎn)圖片 private void TurnPicture() {Matrix matrix = new Matrix();turnRotate=turnRotate+15;//選擇角度 饒(0,0)點選擇 正數(shù)順時針 負數(shù)逆時針 中心旋轉(zhuǎn)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() {//設(shè)置飽和度 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;} } //設(shè)置圖片對比度 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); }??? 同時自定義變量如下:
//圖片變換參數(shù) private float smallbig=1.0f; //縮放比例 private int turnRotate=0; //旋轉(zhuǎn)度數(shù) private float saturation=0f; //飽和度???  它的運行結(jié)果如下圖所示:
 ?
???
 ?
???
 ?
???
??? 需要指出的是:該項目僅僅講述處理的過程,并沒有考慮很多因素,如:有的圖像顯示可能超出屏幕,沒有載入圖片點擊處理按鈕報錯,橫豎屏切換導(dǎo)致不顯示圖片,最下面按鈕可能被遮擋,圖像放大畫布沒有變,因為為認為顯示一張改變后的圖片效果更好,而該工程僅僅是對比.圖像縮放移動觸屏變換更好,下一篇講述.
 ??? 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
 ????圖像空間變換,包括旋轉(zhuǎn)、剪裁、縮放或移動.Matrix類中每個數(shù)字都將應(yīng)用于圖像上每個點的3個坐標x\y\z之一.
 ??? 如下代碼通過setValues設(shè)置值.(1,0,0)表示x坐標轉(zhuǎn)換x=1x+0y+0z,同樣y=0x+1y+0z,z=0x+0y+1z.該矩陣不做任何變換.如果第一行改為(.5f,0,0),那么圖像在x軸上將圖像壓縮50%.移動見setTranslate()函數(shù).
????2.ColorMatrix
 ??? 在Canvas(畫布)對象上繪制時既可使用Matrix方法,也可使用ColorMatrix來改變在Canvas對象上繪制的Paint(畫刷)對象.對圖像的像素處理時,每個像素由RGBA值組成(Red Green Blue Alpha).具體方法推薦博文:http://www.cnblogs.com/leon19870907/articles/1978065.html
????最后希望該文章對大家有所幫助,尤其是Android初學(xué)者.該文章是講述Android使用Matrix處理圖片的基礎(chǔ)文章,如果有不足或錯誤地方,請見諒~參考資料《Android多媒體開發(fā)高級編程 著:Shawn Van Every》
??? 下載地址:http://download.csdn.net/detail/eastmount/8082043
 (By:Eastmount 2014-10-26 夜2點  http://blog.csdn.net/eastmount)?
總結(jié)
以上是生活随笔為你收集整理的[Android] 使用Matrix矩阵类对图像进行缩放、旋转、对比度、亮度处理的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: [Android] 拍照、截图、保存并显
 - 下一篇: [Android] 触屏setOnTou