转载请注明出处:http://blog.csdn.net/sw950729/article/details/51994735
本文出自:马云飞的博客
最近要整理的东西比较多,比较乱,一个一个来把,自定义layout实现recyclerview的下拉刷新和上拉加载还是没有什么思路。刚好前几天上司让我做几个关于camera的界面,我就先介绍下camera把,android4.0后更新了一个控件,textureview,个人感觉而言,它比surfaceview好用很多,不多说,上代码:
textureview.addOnLayoutChangeListener(this);
matrix = new Matrix();
textureview.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {
public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int i, int i1) {
camera = Camera.open(0);
RectF previewRect = new RectF(0, 0, mWidth, mHeight);
double aspect = (double) mPreviewWidth / mPreviewHeight;
if (getResources().getConfiguration().orientation
== Configuration.ORIENTATION_PORTRAIT) {
aspect = 1 / aspect;
}
if (mWidth < (mHeight * aspect)) {
mDisplayWidth = mWidth;
mDisplayHeight = (int) (mHeight * aspect + .5);
} else {
mDisplayWidth = (int) (mWidth / aspect + .5);
mDisplayHeight = mHeight;
}
RectF surfaceDimensions = new RectF(0, 0, mDisplayWidth, mDisplayHeight);
matrix.setRectToRect(previewRect, surfaceDimensions, Matrix.ScaleToFit.FILL);
// textureview.setTransform(matrix);
param = camera.getParameters();
int displayRotation = 0;
WindowManager windowManager = (WindowManager) PhotoActivity.this
.getSystemService(Context.WINDOW_SERVICE);
int rotation = windowManager.getDefaultDisplay().getRotation();
switch (rotation) {
case Surface.ROTATION_0:
displayRotation = 0;
break;
case Surface.ROTATION_90:
displayRotation = 90;
break;
case Surface.ROTATION_180:
displayRotation = 180;
break;
case Surface.ROTATION_270:
displayRotation = 270;
break;
}
Camera.CameraInfo info = new Camera.CameraInfo();
Camera.getCameraInfo(0, info);
if (info.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
orientation = (info.orientation - displayRotation + 360) % 360;
} else {
orientation = (info.orientation + displayRotation) % 360;
orientation = (360 - orientation) % 360;
}
param.setPreviewSize(mPreviewWidth, mPreviewHeight);
camera.setParameters(param);
camera.setDisplayOrientation(orientation);
try {
camera.setPreviewTexture(surfaceTexture);
} catch (IOException e) {
}
camera.startPreview();
// textureview.setAlpha(1.0f);
// textureview.setRotation(90.0f);
}
public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int i, int i1) {
}
public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
// camera.setPreviewCallback(null);
// camera.stopPreview();
// camera.release();
surfaceTexture.release();
camera = null;
return true;
}
public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {
}
});
上面代码主要是讲camera和textureview绑定起来,以及textureview的呈现区域不变形。
priview的宽高我设置的是640*480,正常比例是0.75(480*640).因为摄像头是要通过旋转90°来显示,所以我把他的宽高640*480.
下面代码主要是实现,主副摄像头的切换,以及开关闪光灯。
@OnClick({R.id.back, R.id.camera_head, R.id.light, R.id.shot})
public void onClick(View view) {
switch (view.getId()) {
case R.id.back:
finish();
break;
case R.id.camera_head:
if (!isFront) {
camera.stopPreview();
camera.release();
camera = Camera.open(1);
param = camera.getParameters();
param.setPreviewSize(mPreviewWidth, mPreviewHeight);
camera.setParameters(param);
camera.setDisplayOrientation(orientation);
try {
camera.setPreviewTexture(textureview.getSurfaceTexture());
} catch (IOException e) {
e.printStackTrace();
}
camera.startPreview();
isFront = true;
} else {
camera.stopPreview();
camera.release();
camera = Camera.open(0);
param = camera.getParameters();
param.setPreviewSize(mPreviewWidth, mPreviewHeight);
camera.setParameters(param);
camera.setDisplayOrientation(orientation);
try {
camera.setPreviewTexture(textureview.getSurfaceTexture());
} catch (IOException e) {
e.printStackTrace();
}
camera.startPreview();
isFront = false;
}
break;
case R.id.light:
if (!isLight) {
parameter = camera.getParameters();
parameter.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
camera.setParameters(parameter);
light.setImageResource(R.drawable.open_light);
isLight = true;
} else {
parameter.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
camera.setParameters(parameter);
light.setImageResource(R.drawable.close_light);
isLight = false;
}
break;
case R.id.shot:
camera.takePicture(null, null, this);
break;
}
camera.takepicture(),就是进行拍照了,这个很简单,把他保存在sd的路径就可以了。代码如下:
// data是字节数据,将其解析成位图
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
Matrix matrix = new Matrix();
// 使图片旋转90°
matrix.preRotate(90);
bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
bitmap.getHeight(), matrix, true);
// 保存图片到sdcard
// 获取SD卡的路径
File file = new File(Environment.getExternalStorageDirectory(),
System.currentTimeMillis() + ".jpg");
FileOutputStream outputStream = new FileOutputStream(file);
// 压缩图片,不压缩是100,表示压缩率为0
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
outputStream.close();
// 停止预览
camera.stopPreview();
camera.release();
camera = Camera.open(0);
param = camera.getParameters();
param.setPreviewSize(mPreviewWidth, mPreviewHeight);
camera.setParameters(param);
camera.setDisplayOrientation(orientation);
try {
camera.setPreviewTexture(textureview.getSurfaceTexture());
} catch (IOException e) {
e.printStackTrace();
}
camera.startPreview();// 处理完数据之后可以预览
Log.e("pig", file.getPath());
} catch (Exception e) {
e.printStackTrace();
}
当然,最后还有textureview的layout变化的宽高改变,以及一些权限,代码如下:
public void onLayoutChange(View v, int left, int top, int right,
int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
mWidth = right - left;
mHeight = bottom - top;
}
<uses-permission android:name="android.permission.FLASHLIGHT" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.RECORD_VIDEO"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
这样,一个camera拍照功能就解决了。比较麻烦就是textureview使camera变形的问题。
我的android交流群:232748032。