編輯:Android開發實例
閒話少說,全在注釋中:
- package demo.camera;
- import java.io.FileNotFoundException;
- import android.app.Activity;
- import android.content.Intent;
- import android.graphics.Bitmap;
- import android.graphics.BitmapFactory;
- import android.graphics.Canvas;
- import android.graphics.ColorMatrix;
- import android.graphics.ColorMatrixColorFilter;
- import android.graphics.Matrix;
- import android.graphics.Paint;
- import android.graphics.PorterDuff;
- import android.graphics.PorterDuffXfermode;
- import android.net.Uri;
- import android.os.Bundle;
- import android.provider.MediaStore;
- import android.util.Log;
- import android.view.Menu;
- import android.view.MenuItem;
- import android.view.View;
- import android.widget.Button;
- import android.widget.ImageView;
- /**
- * 在Android中我們可以對圖像進行編輯處理等操作
- * 包括放大縮小,旋轉,偏移,裁剪,以及更改亮度,飽和度等
- *
- * 1、首先,從SDCard中選擇圖片,采用Android自帶的Callery應用獲得
- * Gallery是Android自帶的圖片和視頻管理應用
- * 使用Intent來啟動Gallery應用,需要指定兩個參數,一個是Action,另一個是多媒體存放的URI
- * Action是一個通用的Action叫ACTION_PICK,來告訴Gallery,我們想檢索數據。
- * 第二個是Data,是一個URI,這裡當然是MediaStore.Images.Media.EXTERNAL_CONTENT_URI
- * 當在Gallery中選擇了一個圖片的時候,返回的Intent中的Data域就是所選圖片對應的URI
- *
- * @author Administrator
- *
- */
- public class PhotoProcess extends Activity{
- public static final int FIRST_PIC = 0;
- public static final int SECOND_PIC = 1;
- public static final int MAX_WIDTH = 240;
- public static final int MAX_HEIGHT = 180;
- private Button btnSelect,btnSelect2;
- private ImageView srcImageView, dstImageView;
- private Bitmap srcBitmap, dstBitmap;
- private Uri imageUri;
- public void onCreate(Bundle savedInstanceState){
- super.onCreate(savedInstanceState);
- this.setContentView(R.layout.process);
- this.btnSelect = (Button)this.findViewById(R.id.btn_select);
- btnSelect.setOnClickListener(clickListener);
- this.btnSelect2 = (Button)this.findViewById(R.id.btn_select2);
- btnSelect2.setOnClickListener(clickListener2);
- srcImageView = (ImageView)this.findViewById(R.id.img_src);
- dstImageView = (ImageView)this.findViewById(R.id.img_dst);
- }
- private View.OnClickListener clickListener = new View.OnClickListener() {
- @Override
- public void onClick(View arg0) {
- // 啟動Gallery應用
- Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
- startActivityForResult(intent, FIRST_PIC);
- }
- };
- private View.OnClickListener clickListener2 = new View.OnClickListener() {
- @Override
- public void onClick(View arg0) {
- // 啟動Gallery應用
- Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
- startActivityForResult(intent, SECOND_PIC);
- }
- };
- public boolean onCreateOptionsMenu(Menu menu){
- //super.onCreateOptionsMenu(menu);
- //MenuInflater menuInflater = new MenuInflater(this);
- //menuInflater.inflate(R.layout.image, menu)
- menu.add(Menu.NONE,1,Menu.NONE,"復制");
- menu.add(Menu.NONE,2,Menu.NONE,"變換");
- menu.add(Menu.NONE,3,Menu.NONE,"亮度");
- menu.add(Menu.NONE,4,Menu.NONE,"合成");
- return super.onCreateOptionsMenu(menu);
- }
- public boolean onOptionsItemSelected(MenuItem item){
- int id = item.getItemId();
- switch(id){
- case 1:
- //復制一個圖像
- if(srcBitmap != null){
- dstBitmap = getDstImage(null);//這裡沒有變換
- dstImageView.setImageBitmap(dstBitmap);
- }
- break;
- case 2:
- //對復制後的圖像進行變換
- if(srcBitmap != null){
- dstBitmap = transferImage();
- dstImageView.setImageBitmap(dstBitmap);
- }
- break;
- case 3:
- //改變圖像的色彩
- if(srcBitmap != null){
- dstBitmap = ajustImage();
- dstImageView.setImageBitmap(dstBitmap);
- }
- break;
- case 4:
- if(srcBitmap != null && dstBitmap != null){
- dstBitmap = compositeImages();
- dstImageView.setImageBitmap(dstBitmap);
- }
- break;
- }
- return true;
- }
- /**
- * 為了創建一個圖像的副本,我們可以在創建一個新的空的Bitmap,然後在這個Bitmap上繪制一個Bitmap
- * 這個空的Bitmap應該和已存在的Bitmap具有相同的尺寸和顏色深度
- *
- * 然後我們需要一個Canvas對象,一個Canvas簡單說,就是一個畫布,存放Bitmap,在構造時,就可以傳入Bitmap對象
- * 同時,Canvas中定義了很多便捷的畫圖方法,方便我們繪制各種圖形
- * 接下來,如果我們需要處理顏色和對比度,我們需要一個Paint對象,通過Paint我們可以設置畫筆的各種特性。
- *
- * 最後,我們調用Canvas的drawBitmap就可以將原Bitmap繪制在dstBitmap上了
- *
- */
- private Bitmap getDstImage(Matrix matrix){
- Bitmap bmp = null;
- //下面這個Bitmap中創建的函數就可以創建一個空的Bitmap
- //返回的是一個可以改變的Bitmap對象,這樣我們後面就可以對其進行變換和顏色調整等操作了
- bmp = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), srcBitmap.getConfig());
- //創建Canvas對象,
- Canvas canvas = new Canvas(bmp);
- //創建Paint對象,這裡先不用
- Paint paint = new Paint();
- //在Canvas上繪制一個已經存在的Bitmap。這樣,dstBitmap就和srcBitmap一摸一樣了
- if(matrix != null){
- //如果matrix存在,則采用變換
- canvas.drawBitmap(dstBitmap, matrix, paint);
- }else{
- canvas.drawBitmap(srcBitmap, 0, 0, paint);
- }
- return bmp;
- }
- /**
- * 重載getDstImage函數,傳入定制的Paint對象
- * @param matrix
- * @param paint
- * @return
- */
- private Bitmap getDstImage(Matrix matrix, Paint paint){
- Bitmap bmp = null;
- //下面這個Bitmap中創建的函數就可以創建一個空的Bitmap
- //返回的是一個可以改變的Bitmap對象,這樣我們後面就可以對其進行變換和顏色調整等操作了
- bmp = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), srcBitmap.getConfig());
- //創建Canvas對象,
- Canvas canvas = new Canvas(bmp);
- //在Canvas上繪制一個已經存在的Bitmap。這樣,dstBitmap就和srcBitmap一摸一樣了
- if(matrix != null){
- //如果matrix存在,則采用變換
- canvas.drawBitmap(dstBitmap, matrix, paint);
- }else{
- canvas.drawBitmap(srcBitmap, 0, 0, paint);
- }
- return bmp;
- }
- /**
- * 為了放大縮小、旋轉圖像,我們要使用Matrix類。Matrix類是一個三維矩陣。
- * 在Android屏幕中,圖像的每個像素對應都是一個坐標,一個坐標由x/y/z組成
- * ------------------------
- * cosX -sinX translateX
- * sinX cosX translateY
- * 0 0 scale
- * ------------------------
- * 第一行的值,影響著x坐標。比如 1 0 0 =>x = 1*x + 0*y + 0*z
- * 第二行的值,影響著y坐標。比如0 1 0 => y = 0*x + 1*y + 0*z
- * 第三行的值,影響著z坐標。比如 0 0 1 => z = 0*x + 0*y + 1*z
- *
- * 我們自己計算一個矩陣然後通過Matrax.setValues設置。
- * 這樣,在調用canvas的drawBitmap方法時,傳入matrix
- *
- * Matrix類並不提倡我們使用這種方式來操作變換,Matrix針對不同的變換都相應的有pre,set,post三種方法
- * 可以使用。
- * pre是矩陣前乘
- * set是直接設置
- * post是矩陣後乘
- */
- private Bitmap transferImage(){
- Matrix matrix = new Matrix();
- matrix.setValues(new float[]{
- .5f,0,0,//這裡只會影響到x軸,所以,圖片的長度將是原來的一半
- 0,1,0,
- 0,0,1
- });
- return this.getDstImage(matrix);
- }
- /**
- * 該方法中我們將對圖像的顏色,亮度,對比度等進行設置
- * 需要用到ColorMatrix類。ColorMatrix類是一個四行五列的矩陣
- * 每一行影響著[R,G,B,A]中的一個
- * -------------------------
- * a1 b1 c1 d1 e1
- * a2 b2 c2 d2 e2
- * a3 b3 c3 d3 e3
- * a4 b4 c4 d4 e4
- * -------------------------
- * Rnew => a1*R+b1*G+c1*B+d1*A+e1
- * Gnew => a2*R+b2*G+c2*B+d2*A+e2
- * Bnew => a3*R+b3*G+c3*B+d3*A+e3
- * Gnew => a4*R+b4*G+c4*B+d4*A+e4
- * 其中R,G,B的值是128,A的值是0
- *
- * 最後將顏色的修改,通過Paint.setColorFilter應用到Paint對象中。
- * 主要對於ColorMatrix,需要將其包裝成ColorMatrixColorFilter對象,再傳給Paint對象
- *
- * 同樣的,ColorMatrix提供給我們相應的方法,setSaturation()就可以設置一個飽和度
- */
- private Bitmap ajustImage(){
- ColorMatrix cMatrix = new ColorMatrix();
- // int brightIndex = -25;
- // int doubleColor = 2;
- // cMatrix.set(new float[]{
- // doubleColor,0,0,0,brightIndex, //這裡將1改為2則我們讓Red的值為原來的兩倍
- // 0,doubleColor,0,0,brightIndex,//改變最後一列的值,我們可以不改變RGB同道顏色的基礎上,改變亮度
- // 0,0,doubleColor,0,brightIndex,
- // 0,0,0,doubleColor,0
- // });
- //cMatrix.setSaturation(2.0f);//設置飽和度
- cMatrix.setScale(2.0f, 2.0f, 2.0f, 2.0f);//設置顏色同道色彩縮放
- Paint paint = new Paint();
- paint.setColorFilter(new ColorMatrixColorFilter(cMatrix));
- return this.getDstImage(null, paint);
- }
- /**
- * 圖像的合成,可以通過在同一個Canvas中繪制兩張圖片。
- * 只是在繪制第二章圖片的時候,需要給Paint指定一個變幻模式TransferMode。
- * 在Android中有一個XFermode所有的變幻模式都是這個類的子類
- * 我們需要用到它的一個子類PorterDuffXfermode,關於這個類,其中用到PorterDuff類
- * 這個類很簡單,就包含一個Enum是Mode,其中定義了一組規則,這組規則就是如何將
- * 一張圖像和另一種圖像進行合成
- * 關於圖像合成有四種模式,LIGHTEN,DRAKEN,MULTIPLY,SCREEN
- */
- private Bitmap compositeImages(){
- Bitmap bmp = null;
- //下面這個Bitmap中創建的函數就可以創建一個空的Bitmap
- bmp = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), srcBitmap.getConfig());
- Paint paint = new Paint();
- Canvas canvas = new Canvas(bmp);
- //首先繪制第一張圖片,很簡單,就是和方法中getDstImage一樣
- canvas.drawBitmap(srcBitmap, 0, 0, paint);
- //在繪制第二張圖片的時候,我們需要指定一個Xfermode
- //這裡采用Multiply模式,這個模式是將兩張圖片的對應的點的像素相乘
- //,再除以255,然後以新的像素來重新繪制顯示合成後的圖像
- paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.MULTIPLY));
- canvas.drawBitmap(dstBitmap, 0, 0, paint);
- return bmp;
- }
- public void onActivityResult(int requestCode, int resultCode, Intent data){
- super.onActivityResult(requestCode, resultCode, data);
- Log.v("Result OK Value:", resultCode+"");
- Log.v("RequestCode Value", requestCode+"");
- if(resultCode == RESULT_OK){
- imageUri = data.getData();
- if(requestCode == FIRST_PIC){
- //在Gallery中選中一個圖片時,返回來的Intent中的Data就是選擇圖片的Uri
- srcBitmap = getSrcImage(imageUri);
- srcImageView.setImageBitmap(srcBitmap);
- }else if(requestCode == SECOND_PIC){
- //這裡處理用戶選擇的第二張圖片
- dstBitmap = getSrcImage(imageUri);
- dstImageView.setImageBitmap(dstBitmap);
- }
- }
- }
- /**
- * 需要加載的圖片可能是大圖,我們需要對其進行合適的縮小處理
- * @param imageUri
- */
- private Bitmap getSrcImage(Uri imageUri){
- //Display display = this.getWindowManager().getDefaultDisplay();
- try {
- BitmapFactory.Options ops = new BitmapFactory.Options();
- ops.inJustDecodeBounds = true;
- Bitmap bmp = BitmapFactory.decodeStream(this.getContentResolver().openInputStream(imageUri),null,ops);
- int wRatio = (int)Math.ceil(ops.outWidth/(float)MAX_WIDTH);
- int hRatio = (int)Math.ceil(ops.outHeight/(float)MAX_HEIGHT);
- if(wRatio > 1 && hRatio > 1){
- if(wRatio > hRatio){
- ops.inSampleSize = wRatio;
- }else{
- ops.inSampleSize = hRatio;
- }
- }
- ops.inJustDecodeBounds = false;
- bmp = BitmapFactory.decodeStream(this.getContentResolver().openInputStream(imageUri),null,ops);
- return bmp;
- } catch (FileNotFoundException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- Log.e(this.getClass().getName(), e.getMessage());
- }
- return null;
- }
- }
實現定時器有很多種方式,在這裡我簡單的介紹幾種方式 (1)使用Handler + Runnable的方式 代碼如下: Handler handler = new
本文實例講述了Android編程之界面跳動提示動畫效果實現方法。分享給大家供大家參考,具體如下: 上一個效果圖: 先上布局: <RelativeLa
今天要實現的功能是實現專輯倒影效果,這個功能已經屬於圖像處理方面的了,對圖像處理我不怎麼在行,等一下會介紹一個很實用的工具類,專門用來進行圖像處理的。這個工具類不
Android應用程序可以在許多不同地區的許多設備上運行。為了使應用程序更具交互性,應用程序應該處理以適合應用程序將要使用的語言環境方面的文字,數字,文件等。在本章中,我