android.graphics.Camera实现图像的旋转、缩放

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的使用。实现效果图如下:

 

Camera的处理结果只是生成一个Matrix,该Matrix用于Bitmap或Canvas绘制Bitmap时才能产生旋转或缩放的效果。

代码如下:

  1. package lab.sodino.camera;
  2.  
  3. import android.app.Activity;
  4. import android.graphics.Bitmap;
  5. import android.graphics.Camera;
  6. import android.graphics.Matrix;
  7. import android.graphics.drawable.BitmapDrawable;
  8. import android.os.Bundle;
  9. import android.util.Log;
  10. import android.widget.ImageView;
  11. import android.widget.SeekBar;
  12. import android.widget.SeekBar.OnSeekBarChangeListener;
  13. import android.widget.TextView;
  14.  
  15. /**
  16.  * Camera与Matrix的比较:<br/>
  17.  * Camera的rotate()相关方法是指定某一维度上旋转指定的角度。<br/>
  18.  * Matrix的rotate()相关方法实现的效果是顺时针旋转指定的角度;与Camera指定Z轴旋转效果相同,但方向相反。<br/>
  19.  * 
  20.  * Camera的translate()方法根据某一维度上视点的位移实现图像的缩放,与Matrix的scale()相关方法作用效果相似,
  21.  * 只是Matrix的scale()相关方法是直接指定缩放比例。<br/>
  22.  * 
  23.  * Camera不支持倾斜操作,Matrix可以直接实现倾斜操作。<br/>
  24.  * 
  25.  * @author Sodino E-mail:sodinoopen@hotmail.com
  26.  * @version Time:2011-9-26 下午04:17:49
  27.  */
  28. public class ActCamera extends Activity implements OnSeekBarChangeListener {
  29.     private Camera camera;
  30.     // views
  31.     private SeekBar seekbarXRotate;
  32.     private SeekBar seekbarYRotate;
  33.     private SeekBar seekbarZRotate;
  34.     private TextView txtXRotate;
  35.     private TextView txtYRotate;
  36.     private TextView txtZRotate;
  37.     private SeekBar seekbarXSkew;
  38.     private SeekBar seekbarYSkew;
  39.     private SeekBar seekbarZTranslate;
  40.     private TextView txtXTranslate;
  41.     private TextView txtYTranslate;
  42.     private TextView txtZTranslate;
  43.     private ImageView imgResult;
  44.     // integer params
  45.     private int rotateX, rotateY, rotateZ;
  46.     private float skewX, skewY;
  47.     private int translateZ;
  48.  
  49.     /** Called when the activity is first created. */
  50.     @Override
  51.     public void onCreate(Bundle savedInstanceState) {
  52.         super.onCreate(savedInstanceState);
  53.         setContentView(R.layout.main);
  54.         // camera
  55.         camera = new Camera();
  56.         // initViews
  57.         // rotate
  58.         seekbarXRotate = (SeekBar) findViewById(R.id.seekbarXRotate);
  59.         seekbarXRotate.setOnSeekBarChangeListener(this);
  60.         seekbarYRotate = (SeekBar) findViewById(R.id.seekbarYRotate);
  61.         seekbarYRotate.setOnSeekBarChangeListener(this);
  62.         seekbarZRotate = (SeekBar) findViewById(R.id.seekbarZRotate);
  63.         seekbarZRotate.setOnSeekBarChangeListener(this);
  64.         txtXRotate = (TextView) findViewById(R.id.txtXRotate);
  65.         txtYRotate = (TextView) findViewById(R.id.txtYRotate);
  66.         txtZRotate = (TextView) findViewById(R.id.txtZRotate);
  67.         // translate
  68.         seekbarXSkew = (SeekBar) findViewById(R.id.seekbarXSkew);
  69.         seekbarXSkew.setOnSeekBarChangeListener(this);
  70.         seekbarYSkew = (SeekBar) findViewById(R.id.seekbarYSkew);
  71.         seekbarYSkew.setOnSeekBarChangeListener(this);
  72.         seekbarZTranslate = (SeekBar) findViewById(R.id.seekbarZTranslate);
  73.         seekbarZTranslate.setOnSeekBarChangeListener(this);
  74.         txtXTranslate = (TextView) findViewById(R.id.txtXSkew);
  75.         txtYTranslate = (TextView) findViewById(R.id.txtYSkew);
  76.         txtZTranslate = (TextView) findViewById(R.id.txtZTranslate);
  77.         imgResult = (ImageView) findViewById(R.id.imgResult);
  78.         // refresh
  79.         refreshImage();
  80.     }
  81.  
  82.     private void refreshImage() {
  83.         // 获取待处理的图像
  84.         BitmapDrawable tmpBitDra = (BitmapDrawable) getResources().getDrawable(R.drawable.honeycomb);
  85.         Bitmap tmpBit = tmpBitDra.getBitmap();
  86.         // 开始处理图像
  87.         // 1.获取处理矩阵
  88.         // 记录一下初始状态。save()和restore()可以将图像过渡得柔和一些。
  89.         // Each save should be balanced with a call to restore().
  90.         camera.save();
  91.         Matrix matrix = new Matrix();
  92.         // rotate
  93.         camera.rotateX(rotateX);
  94.         camera.rotateY(rotateY);
  95.         camera.rotateZ(rotateZ);
  96.         // translate
  97.         camera.translate(0, 0, translateZ);
  98.         camera.getMatrix(matrix);
  99.         // 恢复到之前的初始状态。
  100.         camera.restore();
  101.         // 设置图像处理的中心点
  102.         matrix.preTranslate(tmpBit.getWidth() >> 1, tmpBit.getHeight() >> 1);
  103.         matrix.preSkew(skewX, skewY);
  104.         // matrix.postSkew(skewX, skewY);
  105.         // 直接setSkew(),则前面处理的rotate()、translate()等等都将无效。
  106.         // matrix.setSkew(skewX, skewY);
  107.         // 2.通过矩阵生成新图像(或直接作用于Canvas)
  108.         Log.d(“ANDROID_LAB”, “width=” + tmpBit.getWidth() + “ height=” + tmpBit.getHeight());
  109.         Bitmap newBit = null;
  110.         try {
  111.             // 经过矩阵转换后的图像宽高有可能不大于0,此时会抛出IllegalArgumentException
  112.             newBit = Bitmap.createBitmap(tmpBit, 0, 0, tmpBit.getWidth(), tmpBit.getHeight(), matrix, true);
  113.         } catch (IllegalArgumentException iae) {
  114.             iae.printStackTrace();
  115.         }
  116.         if (newBit != null) {
  117.             imgResult.setImageBitmap(newBit);
  118.         }
  119.     }
  120.  
  121.     @Override
  122.     public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
  123.         if (seekBar == seekbarXRotate) {
  124.             txtXRotate.setText(progress + “゜”);
  125.             rotateX = progress;
  126.         } else if (seekBar == seekbarYRotate) {
  127.             txtYRotate.setText(progress + “゜”);
  128.             rotateY = progress;
  129.         } else if (seekBar == seekbarZRotate) {
  130.             txtZRotate.setText(progress + “゜”);
  131.             rotateZ = progress;
  132.         } else if (seekBar == seekbarXSkew) {
  133.             skewX = (progress - 100) * 1.0f / 100;
  134.             txtXTranslate.setText(String.valueOf(skewX));
  135.         } else if (seekBar == seekbarYSkew) {
  136.             skewY = (progress - 100) * 1.0f / 100;
  137.             txtYTranslate.setText(String.valueOf(skewY));
  138.         } else if (seekBar == seekbarZTranslate) {
  139.             translateZ = progress - 100;
  140.             txtZTranslate.setText(String.valueOf(translateZ));
  141.         }
  142.         refreshImage();
  143.     }
  144.  
  145.     @Override
  146.     public void onStartTrackingTouch(SeekBar seekBar) {
  147.  
  148.     }
  149.  
  150.     @Override
  151.     public void onStopTrackingTouch(SeekBar seekBar) {
  152.  
  153.     }
  154. }

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值