您的位置:首页 > 移动开发 > Android开发

Android Camera开发:给摄像头预览界面加个ZoomBar(附完整代码下载)

2014-08-13 14:09 453 查看
原文地址:http://www.cnblogs.com/android100/p/Android-Camera.html

源码:http://files.cnblogs.com/android100/StandardCamera2013-10-18.zip

废话不说了,就是加个seekbar,拖动的话能够调节焦距,让画面变大或缩小。下面是核心程序:

一,camera的布局文件

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:orientation="vertical" >



<TextView

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="@string/BestWish"

tools:context=".StandardCamera" />



<RelativeLayout

android:layout_width="wrap_content"

android:layout_height="wrap_content" >



<FrameLayout

android:layout_width="wrap_content"

android:layout_height="wrap_content" >



<SurfaceView

android:id="@+id/previewSV"

android:layout_width="fill_parent"

android:layout_height="wrap_content" />

</FrameLayout>



<LinearLayout

android:id="@+id/zoomLayout"

android:layout_width="wrap_content"

android:layout_height="40dp"

android:layout_centerInParent="true"

android:layout_centerHorizontal="true"

android:orientation="horizontal" >



<TextView

android:id="@+id/textView1"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="-"

android:textColor="#ffffff"

android:textSize="30dip"/>



<SeekBar

android:id="@+id/seekbar_zoom"

android:layout_width="300dp"

android:layout_height="wrap_content"

android:layout_gravity="center_vertical"

android:progressDrawable="@drawable/seekbar_style"

android:thumb="@drawable/ic_launcher"

android:thumbOffset="0dp" />



<TextView

android:id="@+id/textView2"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="+"

android:textColor="#ffffff"

android:textSize="30dip" />

</LinearLayout>

</RelativeLayout>







<ImageButton

android:id="@+id/photoImgBtn"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_gravity="center"

android:background="@drawable/photo_img_btn" />



</LinearLayout>

其中里面嵌套的LinearLayout就是那个ZoomBar,最外面我用了相对布局,发现相对布局用起来还是很好用的。为了方便以后扩展,Camera的SurfaceView用的帧布局。注意SeekBar的几个参数,其中的progressDrawable是指那个横条的形状,可以直接用个图片,也可以写个xml文件。这里用的是xml,当然用图片很简单。seekbar_style.xml文件如下:

<?xml version="1.0" encoding="UTF-8"?>

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

<item android:id="@android:id/background">

<shape>

<corners android:radius="5dip" />

<gradient

android:startColor="#ff9d9e9d"

android:centerColor="#ff5a5d5a"

android:centerY="0.75"

android:endColor="#ff747674"

android:angle="270"

/>

</shape>

</item>

</layer-list>

下面的android:thumb是滑动的那个手柄,本来我是写了一个xml文件,名字为thumb.xml如下:

<?xml version="1.0" encoding="UTF-8"?>

<selector xmlns:android="http://schemas.android.com/apk/res/android">



<!-- 按下状态 -->

<item android:state_focused="true" android:state_pressed="true"><shape android:shape="oval">

<gradient android:angle="0" android:centerColor="#FF00FF00" android:endColor="#000000" android:gradientRadius="8" android:startColor="#FFFF0000" android:type="radial" />



<size android:height="20dip" android:width="20dip"></size>

</shape></item>





</selector>

无奈啥也显示不出来,索性直接找了个粗糙的图片,见谅哈!

二,整个程序的主代码:

package yan.guoqi.camera;

import java.io.BufferedOutputStream;

import java.io.File;

import java.io.FileOutputStream;

import java.io.IOException;

import java.util.List;



import yan.guoqi.rectphoto.R;

import android.app.Activity;

import android.content.Context;

import android.graphics.Bitmap;

import android.graphics.BitmapFactory;

import android.graphics.ColorMatrixColorFilter;

import android.graphics.Matrix;

import android.graphics.PixelFormat;

import android.hardware.Camera;

import android.hardware.Camera.AutoFocusCallback;

import android.hardware.Camera.Parameters;

import android.hardware.Camera.PictureCallback;

import android.hardware.Camera.PreviewCallback;

import android.hardware.Camera.ShutterCallback;

import android.os.Bundle;

import android.util.Log;

import android.view.Display;

import android.view.MotionEvent;

import android.view.SurfaceHolder;

import android.view.SurfaceView;

import android.view.View;

import android.view.View.OnClickListener;

import android.view.View.OnTouchListener;

import android.view.ViewGroup.LayoutParams;

import android.view.Window;

import android.view.WindowManager;

import android.widget.ImageButton;

import android.widget.SeekBar;

import android.widget.SeekBar.OnSeekBarChangeListener;



public class StandardCamera extends Activity implements SurfaceHolder.Callback, PreviewCallback{

private static final String tag="StandardCamera";

private boolean isPreview = false;

private SurfaceView mPreviewSV = null; //棰勮SurfaceView

private SurfaceHolder mySurfaceHolder = null;

private ImageButton mPhotoImgBtn = null;

private Camera myCamera = null;

private Bitmap mBitmap = null;

private AutoFocusCallback myAutoFocusCallback = null;

boolean flag = true;



private SeekBar mZoomBar = null;



@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

requestWindowFeature(Window.FEATURE_NO_TITLE);

int flag = WindowManager.LayoutParams.FLAG_FULLSCREEN;

Window myWindow = this.getWindow();

myWindow.setFlags(flag, flag);



setContentView(R.layout.activity_rect_photo);



initView();

mySurfaceHolder = mPreviewSV.getHolder();

mySurfaceHolder.setFormat(PixelFormat.TRANSLUCENT);

mySurfaceHolder.addCallback(this);

mySurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);





myAutoFocusCallback = new AutoFocusCallback() {



public void onAutoFocus(boolean success, Camera camera) {

// TODO Auto-generated method stub

if(success)

{

Log.i(tag, "myAutoFocusCallback: success...");





}

else

{

Log.i(tag, "myAutoFocusCallback: 澶辫触浜�?.");



}





}

};



//添加ZoomBar

mZoomBar = (SeekBar)findViewById(R.id.seekbar_zoom);

mZoomBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {



public void onStopTrackingTouch(SeekBar seekBar) {

// TODO Auto-generated method stub



}



public void onStartTrackingTouch(SeekBar seekBar) {

// TODO Auto-generated method stub



}



public void onProgressChanged(SeekBar seekBar, int progress,

boolean fromUser) {

// TODO Auto-generated method stub

Parameters p = myCamera.getParameters();

p.setZoom(progress);

myCamera.setParameters(p);

}

});







}



public void initView(){

mPreviewSV = (SurfaceView)findViewById(R.id.previewSV);

WindowManager wm = (WindowManager)getSystemService(Context.WINDOW_SERVICE);

Display display = wm.getDefaultDisplay();

LayoutParams lpSV = mPreviewSV.getLayoutParams();

lpSV.width = display.getWidth();

lpSV.height = (int) ((float)display.getHeight()*0.75);

mPreviewSV.setLayoutParams(lpSV);





mPhotoImgBtn = (ImageButton)findViewById(R.id.photoImgBtn);

LayoutParams lp = mPhotoImgBtn.getLayoutParams();

lp.width = 240;

lp.height = 240;

mPhotoImgBtn.setLayoutParams(lp);

mPhotoImgBtn.setOnClickListener(new PhotoOnClickListener());

mPhotoImgBtn.setOnTouchListener(new MyOnTouchListener());

}



public void surfaceChanged(SurfaceHolder holder, int format, int width,int height)

{

// TODO Auto-generated method stub

Log.i(tag, "SurfaceHolder.Callback:surfaceChanged!");

initCamera();



}





public void surfaceCreated(SurfaceHolder holder)

{

// TODO Auto-generated method stub

myCamera = Camera.open();

try {

myCamera.setPreviewDisplay(mySurfaceHolder);

Log.i(tag, "SurfaceHolder.Callback: surfaceCreated!");

} catch (IOException e) {

// TODO Auto-generated catch block

if(null != myCamera){

myCamera.release();

myCamera = null;

}

e.printStackTrace();

}







}





public void surfaceDestroyed(SurfaceHolder holder)



{

// TODO Auto-generated method stub

Log.i(tag, "SurfaceHolder.Callback锛歋urface Destroyed");

if(null != myCamera)

{

myCamera.setPreviewCallback(null);



myCamera.stopPreview();

isPreview = false;

myCamera.release();

myCamera = null;

}



}



public void initCamera(){

if(isPreview){

myCamera.stopPreview();

}

if(null != myCamera){

Camera.Parameters myParam = myCamera.getParameters();





myParam.setPictureFormat(PixelFormat.JPEG);//璁剧疆鎷嶇収鍚庡瓨鍌ㄧ殑鍥剧墖鏍煎紡





//List<Size> pictureSizes = myParam.getSupportedPictureSizes();

//List<Size> previewSizes = myParam.getSupportedPreviewSizes();

// for(int i=0; i<pictureSizes.size(); i++){

// Size size = pictureSizes.get(i);

// Log.i(tag, "initCamera:pictureSizes: width = "+size.width+"height = "+size.height);

// }

// for(int i=0; i<previewSizes.size(); i++){

// Size size = previewSizes.get(i);

// Log.i(tag, "initCamera:鎽勫儚澶存敮鎸佺殑previewSizes: width = "+size.width+"height = "+size.height);

//

// }







myParam.setPictureSize(1280, 960); //

myParam.setPreviewSize(960, 720); //

//myParam.set("rotation", 90);

myCamera.setDisplayOrientation(90);

List<String> focuseMode = (myParam.getSupportedFocusModes());

for(int i=0; i<focuseMode.size(); i++){

Log.i(tag, focuseMode.get(i));

if(focuseMode.get(i).contains("continuous")){

myParam.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);

}

else{

myParam.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);



}

}

//设置mZoomBar的最大值

mZoomBar.setMax(myParam.getMaxZoom());

myCamera.setParameters(myParam);

myCamera.startPreview();

myCamera.autoFocus(myAutoFocusCallback);

isPreview = true;

}

}



ShutterCallback myShutterCallback = new ShutterCallback()

{



public void onShutter() {

// TODO Auto-generated method stub

Log.i(tag, "myShutterCallback:onShutter...");



}

};

PictureCallback myRawCallback = new PictureCallback()

{



public void onPictureTaken(byte[] data, Camera camera) {

// TODO Auto-generated method stub

Log.i(tag, "myRawCallback:onPictureTaken...");



}

};

PictureCallback myJpegCallback = new PictureCallback()

{



public void onPictureTaken(byte[] data, Camera camera) {

// TODO Auto-generated method stub

Log.i(tag, "myJpegCallback:onPictureTaken...");

if(null != data){

mBitmap = BitmapFactory.decodeByteArray(data, 0, data.length);//data鏄瓧鑺傛暟鎹紝灏嗗叾瑙f瀽鎴愪綅鍥� myCamera.stopPreview();

isPreview = false;

}

Matrix matrix = new Matrix();

matrix.postRotate((float)90.0);

Bitmap rotaBitmap = Bitmap.createBitmap(mBitmap, 0, 0, mBitmap.getWidth(), mBitmap.getHeight(), matrix, false);

if(null != rotaBitmap)

{

saveJpeg(rotaBitmap);

}



myCamera.startPreview();

isPreview = true;

}

};

public class PhotoOnClickListener implements OnClickListener{



public void onClick(View v) {

// TODO Auto-generated method stub

if(isPreview && myCamera!=null){

myCamera.takePicture(myShutterCallback, null, myJpegCallback);

}



}



}



public void saveJpeg(Bitmap bm){

String savePath = "/mnt/sdcard/rectPhoto/";

File folder = new File(savePath);

if(!folder.exists()) {

folder.mkdir();

}

long dataTake = System.currentTimeMillis();

String jpegName = savePath + dataTake +".jpg";

Log.i(tag, "saveJpeg:jpegName--" + jpegName);

//File jpegFile = new File(jpegName);

try {

FileOutputStream fout = new FileOutputStream(jpegName);

BufferedOutputStream bos = new BufferedOutputStream(fout);



// Bitmap newBM = bm.createScaledBitmap(bm, 600, 800, false);



bm.compress(Bitmap.CompressFormat.JPEG, 100, bos);

bos.flush();

bos.close();

} catch (IOException e) {

// TODO Auto-generated catch block



e.printStackTrace();

}

}





public class MyOnTouchListener implements OnTouchListener{



public final float[] BT_SELECTED=new float[]

{ 2, 0, 0, 0, 2,

0, 2, 0, 0, 2,

0, 0, 2, 0, 2,

0, 0, 0, 1, 0 };



public final float[] BT_NOT_SELECTED=new float[]

{ 1, 0, 0, 0, 0,

0, 1, 0, 0, 0,

0, 0, 1, 0, 0,

0, 0, 0, 1, 0 };

public boolean onTouch(View v, MotionEvent event) {

// TODO Auto-generated method stub

if(event.getAction() == MotionEvent.ACTION_DOWN){

v.getBackground().setColorFilter(new ColorMatrixColorFilter(BT_SELECTED));

v.setBackgroundDrawable(v.getBackground());

}

else if(event.getAction() == MotionEvent.ACTION_UP){

v.getBackground().setColorFilter(new ColorMatrixColorFilter(BT_NOT_SELECTED));

v.setBackgroundDrawable(v.getBackground());



}

return false;

}



}



@Override

public void onBackPressed()

{

// TODO Auto-generated method stub

super.onBackPressed();

StandardCamera.this.finish();

}







class UpdateThread implements Runnable{



public void run() {

// TODO Auto-generated method stub

while(flag){

if(myCamera!=null && isPreview)

myCamera.autoFocus(myAutoFocusCallback); //鑷姩鑱氱劍

myCamera.setOneShotPreviewCallback(StandardCamera.this); //onPreviewFrame閲屼細鎺ュ彈鍒版暟鎹�? myCamera.stopPreview(); //鍋滄棰勮

flag = false;



try {

Thread.sleep(1000);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}



}







public void onPreviewFrame(byte[] data, Camera camera) {

// TODO Auto-generated method stub



}

}

需要注意的有以下几点:

1,为了让程序适用不同的手机,onCreate函数里用如下代码初始化SurfaceView的大小,避免以前写死的方法:

public void initView(){

mPreviewSV = (SurfaceView)findViewById(R.id.previewSV);

WindowManager wm = (WindowManager)getSystemService(Context.WINDOW_SERVICE);

Display display = wm.getDefaultDisplay();

LayoutParams lpSV = mPreviewSV.getLayoutParams();

lpSV.width = display.getWidth();

lpSV.height = (int) ((float)display.getHeight()*0.75);

mPreviewSV.setLayoutParams(lpSV);

mPhotoImgBtn = (ImageButton)findViewById(R.id.photoImgBtn);

LayoutParams lp = mPhotoImgBtn.getLayoutParams();

lp.width = 240;

lp.height = 240;

mPhotoImgBtn.setLayoutParams(lp);

mPhotoImgBtn.setOnClickListener(new PhotoOnClickListener());

mPhotoImgBtn.setOnTouchListener(new MyOnTouchListener());

}

2,关于ZoomBar的代码片段很简短,如下:

mPhotoImgBtn = (ImageButton)findViewById(R.id.photoImgBtn);

LayoutParams lp = mPhotoImgBtn.getLayoutParams();

lp.width = 240;

lp.height = 240;

mPhotoImgBtn.setLayoutParams(lp);

mPhotoImgBtn.setOnClickListener(new PhotoOnClickListener());

mPhotoImgBtn.setOnTouchListener(new MyOnTouchListener());

}

//添加ZoomBar

mZoomBar = (SeekBar)findViewById(R.id.seekbar_zoom);

mZoomBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {



public void onStopTrackingTouch(SeekBar seekBar) {

// TODO Auto-generated method stub



}



public void onStartTrackingTouch(SeekBar seekBar) {

// TODO Auto-generated method stub



}



public void onProgressChanged(SeekBar seekBar, int progress,

boolean fromUser) {

// TODO Auto-generated method stub

Parameters p = myCamera.getParameters();

p.setZoom(progress);

myCamera.setParameters(p);

}

});

3,在initCamera函数里,查询camera支持的聚焦模式,如果带连续视频聚焦则使用连续视频聚焦,否则使用自动聚焦:

mPhotoImgBtn = (ImageButton)findViewById(R.id.photoImgBtn);

LayoutParams lp = mPhotoImgBtn.getLayoutParams();

lp.width = 240;

lp.height = 240;

mPhotoImgBtn.setLayoutParams(lp);

mPhotoImgBtn.setOnClickListener(new PhotoOnClickListener());

mPhotoImgBtn.setOnTouchListener(new MyOnTouchListener());

}

List<String> focuseMode = (myParam.getSupportedFocusModes());

for(int i=0; i<focuseMode.size(); i++){

Log.i(tag, focuseMode.get(i));

if(focuseMode.get(i).contains("continuous")){

myParam.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);

}

else{

myParam.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);

}

}

4,同样在initCamera函数里,设置ZoomBar的最大值:

//设置mZoomBar的最大值

mZoomBar.setMax(myParam.getMaxZoom());

后续将写专文分析Camera4.0的源码,并且模仿到自己的代码中!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐