Android 定制相机安卓
我想在活动中使用Android 定制相机安卓,android,camera,surfaceview,android-camera,Android,Camera,Surfaceview,Android Camera,我想在活动中使用相机预览。我想添加图像(曲面视图上的透明帧)。我尝试了以下代码,以便能够轻松地定制xml布局: package com.demo; import java.io.IOException; import android.app.Activity; import android.graphics.PixelFormat; import android.hardware.Camera; import android.os.Bundle; import android.view.S
相机预览
。我想添加图像(曲面视图上的透明帧)。我尝试了以下代码,以便能够轻松地定制xml布局:
package com.demo;
import java.io.IOException;
import android.app.Activity;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.Toast;
public class CameraDemoActivity extends Activity implements SurfaceHolder.Callback{
/** Called when the activity is first created. */
Camera camera;
SurfaceView surfaceView;
SurfaceHolder surfaceHolder;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
getWindow().setFormat(PixelFormat.UNKNOWN);
surfaceView = (SurfaceView)findViewById(R.id.surfaceview);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
camera = Camera.open();
if(camera!=null){
try {
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
} catch (IOException e) {
Toast.makeText(this, (CharSequence) e, Toast.LENGTH_LONG).show();
}
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
}
}
这是我的舱单:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.demo"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="8" />
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".CameraDemoActivity"
android:label="@string/app_name" android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-permission android:name="android.permission.CAMERA"/>
<uses-feature android:name="android:hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
</manifest>
这是我的布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<SurfaceView
android:id="@+id/surfaceview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
</LinearLayout>
不知道为什么不显示相机的预览?使用此代码
PreviewDemo.java
public class PreviewDemo extends Activity implements OnClickListener {
private SurfaceView preview = null;
private SurfaceHolder previewHolder = null;
private Camera camera = null;
private boolean inPreview = false;
ImageView image;
Bitmap bmp, itembmp;
static Bitmap mutableBitmap;
PointF start = new PointF();
PointF mid = new PointF();
float oldDist = 1f;
File imageFileName = null;
File imageFileFolder = null;
private MediaScannerConnection msConn;
Display d;
int screenhgt, screenwdh;
ProgressDialog dialog;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.preview);
image = (ImageView) findViewById(R.id.image);
preview = (SurfaceView) findViewById(R.id.surface);
previewHolder = preview.getHolder();
previewHolder.addCallback(surfaceCallback);
previewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
previewHolder.setFixedSize(getWindow().getWindowManager()
.getDefaultDisplay().getWidth(), getWindow().getWindowManager()
.getDefaultDisplay().getHeight());
}
@Override
public void onResume() {
super.onResume();
camera = Camera.open();
}
@Override
public void onPause() {
if (inPreview) {
camera.stopPreview();
}
camera.release();
camera = null;
inPreview = false;
super.onPause();
}
private Camera.Size getBestPreviewSize(int width, int height, Camera.Parameters parameters) {
Camera.Size result = null;
for (Camera.Size size: parameters.getSupportedPreviewSizes()) {
if (size.width <= width && size.height <= height) {
if (result == null) {
result = size;
} else {
int resultArea = result.width * result.height;
int newArea = size.width * size.height;
if (newArea > resultArea) {
result = size;
}
}
}
}
return (result);
}
SurfaceHolder.Callback surfaceCallback = new SurfaceHolder.Callback() {
public void surfaceCreated(SurfaceHolder holder) {
try {
camera.setPreviewDisplay(previewHolder);
} catch (Throwable t) {
Log.e("PreviewDemo-surfaceCallback",
"Exception in setPreviewDisplay()", t);
Toast.makeText(PreviewDemo.this, t.getMessage(), Toast.LENGTH_LONG)
.show();
}
}
public void surfaceChanged(SurfaceHolder holder,
int format, int width,
int height) {
Camera.Parameters parameters = camera.getParameters();
Camera.Size size = getBestPreviewSize(width, height,
parameters);
if (size != null) {
parameters.setPreviewSize(size.width, size.height);
camera.setParameters(parameters);
camera.startPreview();
inPreview = true;
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
// no-op
}
};
Camera.PictureCallback photoCallback = new Camera.PictureCallback() {
public void onPictureTaken(final byte[] data, final Camera camera) {
dialog = ProgressDialog.show(PreviewDemo.this, "", "Saving Photo");
new Thread() {
public void run() {
try {
Thread.sleep(1000);
} catch (Exception ex) {}
onPictureTake(data, camera);
}
}.start();
}
};
public void onPictureTake(byte[] data, Camera camera) {
bmp = BitmapFactory.decodeByteArray(data, 0, data.length);
mutableBitmap = bmp.copy(Bitmap.Config.ARGB_8888, true);
savePhoto(mutableBitmap);
dialog.dismiss();
}
class SavePhotoTask extends AsyncTask < byte[], String, String > {@Override
protected String doInBackground(byte[]...jpeg) {
File photo = new File(Environment.getExternalStorageDirectory(), "photo.jpg");
if (photo.exists()) {
photo.delete();
}
try {
FileOutputStream fos = new FileOutputStream(photo.getPath());
fos.write(jpeg[0]);
fos.close();
} catch (java.io.IOException e) {
Log.e("PictureDemo", "Exception in photoCallback", e);
}
return (null);
}
}
public void savePhoto(Bitmap bmp) {
imageFileFolder = new File(Environment.getExternalStorageDirectory(), "Rotate");
imageFileFolder.mkdir();
FileOutputStream out = null;
Calendar c = Calendar.getInstance();
String date = fromInt(c.get(Calendar.MONTH)) + fromInt(c.get(Calendar.DAY_OF_MONTH)) + fromInt(c.get(Calendar.YEAR)) + fromInt(c.get(Calendar.HOUR_OF_DAY)) + fromInt(c.get(Calendar.MINUTE)) + fromInt(c.get(Calendar.SECOND));
imageFileName = new File(imageFileFolder, date.toString() + ".jpg");
try {
out = new FileOutputStream(imageFileName);
bmp.compress(Bitmap.CompressFormat.JPEG, 100, out);
out.flush();
out.close();
scanPhoto(imageFileName.toString());
out = null;
} catch (Exception e) {
e.printStackTrace();
}
}
public String fromInt(int val) {
return String.valueOf(val);
}
public void scanPhoto(final String imageFileName) {
msConn = new MediaScannerConnection(PreviewDemo.this, new MediaScannerConnectionClient() {
public void onMediaScannerConnected() {
msConn.scanFile(imageFileName, null);
Log.i("msClient obj in Photo Utility", "connection established");
}
public void onScanCompleted(String path, Uri uri) {
msConn.disconnect();
Log.i("msClient obj in Photo Utility", "scan completed");
}
});
msConn.connect();
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_MENU && event.getRepeatCount() == 0) {
onBack();
}
return super.onKeyDown(keyCode, event);
}
public void onBack() {
Log.e("onBack :", "yes");
camera.takePicture(null, null, photoCallback);
inPreview = false;
}
@Override
public void onClick(View v) {
}
}
公共类PreviewDemo扩展活动实现OnClickListener{
private SurfaceView preview=null;
private SurfaceHolder previewHolder=null;
私人摄像机=空;
private boolean inPreview=false;
图像视图图像;
位图bmp,项目bmp;
静态位图可变位图;
PointF start=新的PointF();
PointF mid=新的PointF();
浮动oldDist=1f;
文件imageFileName=null;
File-imageFileFolder=null;
专用MediaScannerConnection msConn;
显示d;
int screenhgt,screenwdh;
进程对话;
@凌驾
创建时的公共void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.preview);
image=(ImageView)findviewbyd(R.id.image);
预览=(SurfaceView)findViewById(R.id.surface);
previewHolder=preview.getHolder();
previewHolder.addCallback(surfaceCallback);
previewHolder.setType(SurfaceHolder.SURFACE类型推送缓冲区);
previewHolder.setFixedSize(getWindow().getWindowManager())
.getDefaultDisplay().getWidth(),getWindow().getWindowManager()
.getDefaultDisplay().getHeight());
}
@凌驾
恢复时公开作废(){
super.onResume();
camera=camera.open();
}
@凌驾
公共无效暂停(){
如果(审查){
camera.stopPreview();
}
相机。释放();
摄像机=零;
inPreview=false;
super.onPause();
}
私人相机。大小getBestPreviewSize(整数宽度、整数高度、相机。参数){
Camera.Size结果=null;
对于(Camera.Size:parameters.getSupportedPreviewSizes()){
如果(size.width{@Override
受保护的字符串doInBackground(字节[]…jpeg){
File photo=新文件(Environment.getExternalStorageDirectory(),“photo.jpg”);
if(photo.exists()){
photo.delete();
}
试一试{
FileOutputStream fos=新的FileOutputStream(photo.getPath());
fos.write(jpeg[0]);
fos.close();
}捕获(java.io.ioe异常){
Log.e(“PictureDemo”,“photoCallback中的异常”,e);
}
返回(空);
}
}
公共void保存照片(位图bmp){
imageFileFolder=新文件(Environment.getExternalStorageDirectory(),“Rotate”);
imageFileFolder.mkdir();
FileOutputStream out=null;
Calendar c=Calendar.getInstance();
字符串date=fromInt(c.get(Calendar.MONTH))+fromInt(c.get(Calendar.DAY_OF u MONTH))+fromInt(c.get(Calendar.YEAR))+fromInt(Calendar.HOUR OF u DAY))+fromInt(c.get(Calendar.SECOND));
imageFileName=新文件(imageFileFolder,date.toString()+“.jpg”);
试一试{
out=新文件输出流(imageFileName);
bmp.compress(Bitmap.CompressFormat.JPEG,100,out);
out.flush();
out.close();
扫描照片(imageFileName.toString());
out=null;
}捕获(例外e){
e、 printStackTrace();
}
}
公共字符串fromInt(int val){
返回字符串.valueOf(val);
}
公共空白扫描照片(最终字符串imageFileName){
msConn=新MediaScannerConnection(PreviewDemo.this,新MediaScannerConnectionClient()){
MediaScannerconnected()上的公共无效{
msConn.scanFile(imageFileName,null);
Log.i(“照片实用程序中的msClient obj”,“已建立连接”);
}
已完成的公共void(字符串路径,Uri){
msConn.disconnect();
Log.i(“照片实用程序中的msClient obj”,“扫描完成”);
}
});
msConn.connect();
}
@凌驾
公共布尔onKeyDown(int-keyCode,KeyEvent事件){
if(keyCode==KeyEvent.keyCode\u菜单和&event.getRepeatCount()==0){
onBack();
}
返回super.onKeyDown(keyCode,event);
}
公开作废回拨(){
Log.e(“onBack:,“yes”);
照相/摄像(空、空、光反馈);
inPreview=false;
}
@凌驾
公共void onClick(视图v){
}
}
Preview.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<android.view.SurfaceView
android:id="@+id/surface"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
</RelativeLayout>
使用设备菜单按钮拍照
在清单文件中添加权限
检查Gallery中的Rotate文件夹以获取捕获的图像。你能给我一个完整的zip项目吗?只需这个基本的摄像头提要,并单击一个按钮?你能给我完整的工作项目吗?我无法获得上面的全部代码。非常好的代码。我用2.3.3检查了它。行中有“new MediaScannerConnectionClient()“必须将其更改为”新建MediaScannerConnection.MediaScannerConnectionClient()在kitkat nexus 4中尝试了此代码…相机预览设置为90德基..惊讶地发现您有image=(ImageView)findViewById(R.id.image);未使用此代码