手机相机应用拍摄图片的旋转处理
讲解之前我说段废话,当你选择了语言开发时,你就要永远的学习下去,没有终点,除非你选择转行,要不然你不能停止。
好了,我们开始进入讲解过程:
我之所以讲相机的原因是在网上很多人也说过了相机的应用,但是他们漏掉了一个问题就是我们在做相机应用时,会出现一个问题,那就是拍摄出来的图片,不管我们怎么用手机拍摄出来的照片都是横向的,对于这个问题很多人没有在意,而我在做过相关项目时发现了这个小问题,但是大多数人都会忽略的问题。
下面我贴出代码解释一下:
为了很直观的看懂代码,我直接就写在一个Activity里面,其实在开发过程中这是一种不好代码编写方式,但是在以后我会按照开发过程中的代码编写方式来展现给大家。
今后看代码的时候,千万不要看着代码很长,就没有想看的心思,这样会对你又很大的局限,当你走上编程之路时,那才是真正的长,所以要学会强迫自己去看
我直接贴出代码:有几个要注意的地方我注释一下
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.PixelFormat;
import android.graphics.drawable.BitmapDrawable;
import android.hardware.Camera;
import android.hardware.Camera.AutoFocusCallback;
import android.hardware.Camera.PictureCallback;
import android.os.Bundle;
import android.os.Environment;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
public class MainActivity extends Activity implements OnClickListener,Callback,AutoFocusCallback{//这里的Callback一定是这包下的import android.view.SurfaceHolder.Callback的
private SurfaceHolder surfaceHolder;
private SurfaceView surfaceView;
private ImageView disImageView;
private Button paiButton;
private boolean isClick;
private Camera camera;
private Bitmap reBitmap;
private BitmapDrawable drawable;
private String picPath = Environment.getExternalStorageDirectory().getAbsolutePath().toString()+"x"+System.currentTimeMillis()+".jpg";
/**
* 描述:将图片旋转到竖直方向并保存图片
* 这里就是将图片旋转处理的地方
* 我们先将图片旋转后在写入到sdcard里面去
*/
PictureCallback jpeg = new PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
try{
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
//旋转图片的显示方向
int scale_t = 1,scale_a = 1;
final int width = bitmap.getWidth();
final int height = bitmap.getHeight();
int newWidth = width*scale_t;
int newHeight = height*scale_a;
float scaleWidth = ((float)newWidth)/width;
float scaleHeight = ((float)newHeight)/height;
Matrix matrix = new Matrix();//使用这个类将图片旋转90度
matrix.postScale(scaleWidth, scaleHeight);
matrix.setRotate(90*scale_a);//其实这里的scale_a可以不用,只是这样写,看起来高大上
reBitmap = Bitmap.createBitmap(bitmap,0,0,width,height);
//存储图片
File file = new File(picPath);
BufferedOutputStream bStream = new BufferedOutputStream(new FileOutputStream(file));
reBitmap.compress(Bitmap.CompressFormat.JPEG,100,bStream);
bStream.flush();
bStream.close();
}catch(Exception ex){
ex.printStackTrace();
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
inifindView();//初始化组件
}
/**
* 描述:初始化组件
*/
@SuppressWarnings("deprecation")
private void inifindView() {
surfaceView = (SurfaceView) findViewById(R.id.cameras);
disImageView = (ImageView) findViewById(R.id.dis_imag);
paiButton = (Button) findViewById(R.id.camera_bt);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
paiButton.setOnClickListener(this);
}
@SuppressWarnings("deprecation")
@Override
public void onClick(View v) {
if(!isClick){
camera.autoFocus(this);
Toast.makeText(this,"自动聚焦",Toast.LENGTH_SHORT).show();
isClick = true;
}else{
camera.startPreview();
if(reBitmap != null){
drawable = new BitmapDrawable(reBitmap);
disImageView.setBackgroundDrawable(drawable);
}else{
disImageView.setBackgroundColor(Color.WHITE);
}
isClick = false;
}
}
/**
* 描述:照相时,请求调焦
*/
@SuppressWarnings("deprecation")
@Override
public void onAutoFocus(boolean success, Camera camera) {
if(success){
//设置参数
Camera.Parameters parameters = camera.getParameters();
parameters.setPictureFormat(PixelFormat.JPEG);
parameters.setPictureSize(800,480);//这里请大家注意,这里的数字不是越大越好,如果过大,就会抛出异常,我自己的手机刚好这个数值上,如果你使用了我写的这数值而报错的话,请你将其数值改小
camera.setParameters(parameters);
camera.setDisplayOrientation(90);//这里必须写上,这是旋转90度,如果少了这个设置,即使我上面使用Matrix处理,图片依旧是横向的
camera.takePicture(null, null, jpeg);
}
}
/**
* 描述:创建并打开默认摄像(一般是指后置摄像头)
*/
@Override
public void surfaceCreated(SurfaceHolder holder) {
if(camera == null){
camera = Camera.open();//camera = Camera.open(cameraId);据说是打开和切换前后摄像头的方法,我在公司开发中没有用的过前置摄像头,所以我就没去弄过
try{
camera.setPreviewDisplay(surfaceHolder);//将其显示加载到SurfaceView上
}catch(Exception e){
e.printStackTrace();
}
}
}
@SuppressWarnings("deprecation")
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
//配置摄像的参数
Camera.Parameters parameters = camera.getParameters();
parameters.setPictureFormat(PixelFormat.JPEG);//图片的格式
parameters.setPictureSize(800,480);//图片的大小,一定的注意,这里的数字不要太大,否则会报异常
camera.setDisplayOrientation(90);//旋转90度
camera.startPreview();
}
/**
* 描述:结束照相时,调用的
*/
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
camera.stopPreview();
camera.release();
camera = null;
}
}
接下来就是简单的布局文件了
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<SurfaceView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/cameras"
/>
<Button
android:layout_width="50dp"
android:layout_height="50dp"
android:id="@+id/camera_bt"
android:layout_gravity="center_horizontal|bottom"
android:text="拍照"
android:background="@drawable/btn_round_n"
android:textSize="13sp"
android:layout_margin="2dp"
/>
<ImageView
android:layout_width="60dp"
android:layout_height="60dp"
android:id="@+id/dis_imag"
android:background="#E9F6E8"
android:layout_gravity="bottom|right"
android:layout_margin="3dp"
/>
</FrameLayout>
其次是权限配置
<!-- 在SDCard中创建与删除文件权限 -->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<!-- 往SDCard写入数据权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<uses-feature android:name="android.hardware.camera" />
最后是有图有真相
源代码下载地址:http://download.youkuaiyun.com/detail/qq_22183039/9477394
拍照的那个按钮我做了处理,如果想要源代码的可以到我博客上下载,我会上传到我的博客上
如果你真的想学好安卓,我建议还是去买点书或者其他的学习工具,我以前就买过这本书,我觉得可以,很详细,不妨去看看http://s.click.taobao.com/t?e=m%3D2%26s%3De%2FjSd5R7sk4cQipKwQzePOeEDrYVVa64K7Vc7tFgwiFRAdhuF14FMZYMEx%2BUAxGj1aH1Hk3GeOi1upsGVP%2BE7bIieqNcnEROPzWt%2BD5CzV2G%2FOj6X2BCoBtlrJbLMDAQEzj78aukG9UXhGhiqu2JwsYMXU3NNCg%2F&pvid=50_113.91.67.120_431_1459356271854