android.graphics.Camera實現圖像的旋轉、縮放

fmms 13年前發布 | 90K 次閱讀 Android Android開發 移動開發

android.graphics.Camera可以對圖像執行一些比較復雜的操作,諸如旋轉與綻放,與Matrix可實現圖像的傾斜。

個人總結Camera與Matrix的一些區別如下:

  1. Camera的rotate()相關方法是指定某一維度上旋轉指定的角度。
  2. Matrix的rotate()相關方法實現的效果是順時針旋轉指定的角度;與Camera指定Z軸旋轉效果相同,但方向相反。
  3. Camera的translate()方法根據某一維度上視點的位移實現圖像的縮放,與Matrix的scale()相關方法作用效果相似,只是Matrix的scale()相關方法是直接指定縮放比例。
  4. Camera不支持傾斜操作,Matrix可以直接實現傾斜操作。

本文為練習Camera的使用。實現效果圖如下:

android.graphics.Camera實現圖像的旋轉、縮放

Camera的處理結果只是生成一個Matrix,該Matrix用于Bitmap或Canvas繪制Bitmap時才能產生旋轉或縮放的效果。

代碼如下:

package lab.sodino.camera;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Camera;
import android.graphics.Matrix;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.util.Log;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;

/**
 * Camera與Matrix的比較:<br/>
 * Camera的rotate()相關方法是指定某一維度上旋轉指定的角度。<br/>
 * Matrix的rotate()相關方法實現的效果是順時針旋轉指定的角度;與Camera指定Z軸旋轉效果相同,但方向相反。<br/>
 * 
 * Camera的translate()方法根據某一維度上視點的位移實現圖像的縮放,與Matrix的scale()相關方法作用效果相似,
 * 只是Matrix的scale()相關方法是直接指定縮放比例。<br/>
 * 
 * Camera不支持傾斜操作,Matrix可以直接實現傾斜操作。<br/>
 * 
 * <a href="http://my.oschina.net/arthor" class="referer" target="_blank">@author</a> Sodino E-mail:sodinoopen@hotmail.com
 * @version Time:2011-9-26 下午04:17:49
 */
public class ActCamera extends Activity implements OnSeekBarChangeListener {
    private Camera camera;
    // views
    private SeekBar seekbarXRotate;
    private SeekBar seekbarYRotate;
    private SeekBar seekbarZRotate;
    private TextView txtXRotate;
    private TextView txtYRotate;
    private TextView txtZRotate;
    private SeekBar seekbarXSkew;
    private SeekBar seekbarYSkew;
    private SeekBar seekbarZTranslate;
    private TextView txtXTranslate;
    private TextView txtYTranslate;
    private TextView txtZTranslate;
    private ImageView imgResult;
    // integer params
    private int rotateX, rotateY, rotateZ;
    private float skewX, skewY;
    private int translateZ;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        // camera
        camera = new Camera();
        // initViews
        // rotate
        seekbarXRotate = (SeekBar) findViewById(R.id.seekbarXRotate);
        seekbarXRotate.setOnSeekBarChangeListener(this);
        seekbarYRotate = (SeekBar) findViewById(R.id.seekbarYRotate);
        seekbarYRotate.setOnSeekBarChangeListener(this);
        seekbarZRotate = (SeekBar) findViewById(R.id.seekbarZRotate);
        seekbarZRotate.setOnSeekBarChangeListener(this);
        txtXRotate = (TextView) findViewById(R.id.txtXRotate);
        txtYRotate = (TextView) findViewById(R.id.txtYRotate);
        txtZRotate = (TextView) findViewById(R.id.txtZRotate);
        // translate
        seekbarXSkew = (SeekBar) findViewById(R.id.seekbarXSkew);
        seekbarXSkew.setOnSeekBarChangeListener(this);
        seekbarYSkew = (SeekBar) findViewById(R.id.seekbarYSkew);
        seekbarYSkew.setOnSeekBarChangeListener(this);
        seekbarZTranslate = (SeekBar) findViewById(R.id.seekbarZTranslate);
        seekbarZTranslate.setOnSeekBarChangeListener(this);
        txtXTranslate = (TextView) findViewById(R.id.txtXSkew);
        txtYTranslate = (TextView) findViewById(R.id.txtYSkew);
        txtZTranslate = (TextView) findViewById(R.id.txtZTranslate);
        imgResult = (ImageView) findViewById(R.id.imgResult);
        // refresh
        refreshImage();
    }

    private void refreshImage() {
        // 獲取待處理的圖像
        BitmapDrawable tmpBitDra = (BitmapDrawable) getResources().getDrawable(R.drawable.honeycomb);
        Bitmap tmpBit = tmpBitDra.getBitmap();
        // 開始處理圖像
        // 1.獲取處理矩陣
        // 記錄一下初始狀態。save()和restore()可以將圖像過渡得柔和一些。
        // Each save should be balanced with a call to restore().
        camera.save();
        Matrix matrix = new Matrix();
        // rotate
        camera.rotateX(rotateX);
        camera.rotateY(rotateY);
        camera.rotateZ(rotateZ);
        // translate
        camera.translate(0, 0, translateZ);
        camera.getMatrix(matrix);
        // 恢復到之前的初始狀態。
        camera.restore();
        // 設置圖像處理的中心點
        matrix.preTranslate(tmpBit.getWidth() >> 1, tmpBit.getHeight() >> 1);
        matrix.preSkew(skewX, skewY);
        // matrix.postSkew(skewX, skewY);
        // 直接setSkew(),則前面處理的rotate()、translate()等等都將無效。
        // matrix.setSkew(skewX, skewY);
        // 2.通過矩陣生成新圖像(或直接作用于Canvas)
        Log.d(“ANDROID_LAB”, “width=” + tmpBit.getWidth() + “ height=” + tmpBit.getHeight());
        Bitmap newBit = null;
        try {
            // 經過矩陣轉換后的圖像寬高有可能不大于0,此時會拋出IllegalArgumentException
            newBit = Bitmap.createBitmap(tmpBit, 0, 0, tmpBit.getWidth(), tmpBit.getHeight(), matrix, true);
        } catch (IllegalArgumentException iae) {
            iae.printStackTrace();
        }
        if (newBit != null) {
            imgResult.setImageBitmap(newBit);
        }
    }

    @Override
    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
        if (seekBar == seekbarXRotate) {
            txtXRotate.setText(progress + “゜”);
            rotateX = progress;
        } else if (seekBar == seekbarYRotate) {
            txtYRotate.setText(progress + “゜”);
            rotateY = progress;
        } else if (seekBar == seekbarZRotate) {
            txtZRotate.setText(progress + “゜”);
            rotateZ = progress;
        } else if (seekBar == seekbarXSkew) {
            skewX = (progress - 100) * 1.0f / 100;
            txtXTranslate.setText(String.valueOf(skewX));
        } else if (seekBar == seekbarYSkew) {
            skewY = (progress - 100) * 1.0f / 100;
            txtYTranslate.setText(String.valueOf(skewY));
        } else if (seekBar == seekbarZTranslate) {
            translateZ = progress - 100;
            txtZTranslate.setText(String.valueOf(translateZ));
        }
        refreshImage();
    }

    @Override
    public void onStartTrackingTouch(SeekBar seekBar) {

    }

    @Override
    public void onStopTrackingTouch(SeekBar seekBar) {

    }
}
文章出處: DEVDIV博客

 本文由用戶 fmms 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!