java 您如何获得适用于 Android 的简单相机程序?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7605904/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do you get a simple camera program working for Android?
提问by Metropolis
I just started programming in Java, and I need to get a simple application up that shows the camera, takes a picture, and sends that picture data somewhere.
我刚开始用 Java 编程,我需要创建一个简单的应用程序,它可以显示相机、拍照并将该图片数据发送到某个地方。
I have been searching all over the web trying to find a good camera tutorial that worked as expected, but apparently they all require some inner knowledge that I do not have yet.
我一直在网上搜索,试图找到一个按预期工作的好的相机教程,但显然它们都需要一些我还没有的内在知识。
On thispage, commonsWare pointed to code that had some sample code in it for using the camera. I have taken the PictureDemo code and got it running with no errors. However, it only brings up a black screen. I assume this is because the program is not actually activating the preview, or camera in the main function, but every time I try adding the code I think I need, I am getting exceptions.
在此页面上,commonsWare 指向的代码中包含一些用于使用相机的示例代码。我已经获取了 PictureDemo 代码并让它运行起来没有错误。但是,它只会出现黑屏。我认为这是因为该程序实际上并未在主函数中激活预览或相机,但是每次我尝试添加我认为需要的代码时,都会遇到异常。
So my question is, what do I need to add in the main function to get the camera going? Or is there a better tutorial somewhere that I can see simple basic code for getting the camera up?
所以我的问题是,我需要在主函数中添加什么才能让相机运行?或者是否有更好的教程可以让我看到用于安装相机的简单基本代码?
package assist.core;
import android.app.Activity;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.KeyEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.Toast;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
public class MainActivity extends Activity
{
private SurfaceView preview = null;
private SurfaceHolder previewHolder = null;
private Camera camera = null;
private boolean inPreview = false;
/**
*
*/
@Override
public void onCreate(Bundle savedInstanceState)
{
//Call the parent class
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
preview = (SurfaceView) findViewById(R.id.preview);
previewHolder = preview.getHolder();
previewHolder.addCallback(surfaceCallback);
previewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
@Override
public void onResume() {
super.onResume();
//Get the camera instance
camera = CameraFinder.INSTANCE.open();
}
@Override
public void onPause() {
if (inPreview) {
camera.stopPreview();
}
camera.release();
camera = null;
inPreview = false;
super.onPause();
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_CAMERA || keyCode == KeyEvent.KEYCODE_SEARCH) {
if (inPreview) {
camera.takePicture(null, null, photoCallback);
inPreview = false;
}
return(true);
}
return(super.onKeyDown(keyCode, event));
}
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("MainActivity-surfaceCallback", "Exception in setPreviewDisplay()", t);
Toast.makeText(MainActivity.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);
parameters.setPictureFormat(PixelFormat.JPEG);
camera.setParameters(parameters);
camera.startPreview();
inPreview = true;
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
// no-op
}
};
Camera.PictureCallback photoCallback = new Camera.PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
new SavePhotoTask().execute(data);
camera.startPreview();
inPreview = true;
}
};
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("MainActivity", "Exception in photoCallback", e);
}
return(null);
}
}
}
Update
更新
As for the exceptions I was getting, if I tried making the main function like the code below,
至于我得到的异常,如果我尝试像下面的代码一样制作 main 函数,
public void onCreate(Bundle savedInstanceState)
{
//Call the parent class
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
preview = (SurfaceView) findViewById(R.id.preview);
previewHolder = preview.getHolder();
previewHolder.addCallback(surfaceCallback);
previewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
Camera.Parameters parameters = camera.getParameters();
parameters.setPictureFormat(PixelFormat.JPEG);
camera.setParameters(parameters);
try {
//Start the camera preview display
camera.setPreviewDisplay(previewHolder);
camera.startPreview();
}
catch (IOException ex) {
Logger.getLogger(MainActivity.class.getName()).log(Level.SEVERE, null, ex);
}
}
I get "The application has stopped unexpectedly. Please Try again." I was basically trying to follow the steps that the android documentionspecifies. I also tried putting this code into the onResume function after the camera object is retrieved, and then calling this.onResume.
我收到“应用程序意外停止。请重试。” 我基本上是在尝试按照android 文档指定的步骤进行操作。我还尝试在检索到相机对象后将此代码放入 onResume 函数中,然后调用 this.onResume。
采纳答案by Terence Lui
If what you need is just open up a camera, take a picture, and get the image. then you can do: launch Camera using Intents
如果您需要的只是打开相机,拍照并获取图像。那么你可以这样做: 使用 Intents 启动相机
Your above code is the integrated version. That integrates the camera into your app. I am not sure if you have the real android device to test. The simulator will show either black or "android icon" screen in replacing the real camera.
你上面的代码是集成版本。这将相机集成到您的应用程序中。我不确定你是否有真正的 android 设备来测试。模拟器将在替换真实相机时显示黑色或“android 图标”屏幕。
so test it on real device if you weren't.
所以如果你不是,请在真实设备上测试它。
And could you be more specified on the exceptions you got?
你能更详细地说明你得到的例外情况吗?
回答by tony gil
this is a fully functional camera working with Intents (I am calling the camera immediately, you would obviously include a button or menu item). It saves the image to the gallery and to root as Pic.jpg and then displays the captured image.
这是一个与 Intents 一起使用的功能齐全的相机(我立即调用相机,您显然会包含一个按钮或菜单项)。它将图像保存到图库并作为 Pic.jpg 根目录,然后显示捕获的图像。
this answer is an expanded and complete version of this EXCELLENT snippet by Aleksander O.
这个答案是Aleksander O的这个 EXCELLENT 片段的扩展和完整版本。
import java.io.File;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.Toast;
public class CallCameraActivity extends Activity {
final int TAKE_PICTURE = 1;
private Uri imageUri;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
takePhoto();
}
public void takePhoto() {
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
File photo = new File(Environment.getExternalStorageDirectory(), "Pic.jpg");
intent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(photo));
imageUri = Uri.fromFile(photo);
startActivityForResult(intent, TAKE_PICTURE);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case TAKE_PICTURE:
if (resultCode == Activity.RESULT_OK) {
//Uri imageUri;
Uri selectedImage = imageUri;
getContentResolver().notifyChange(selectedImage, null);
ImageView imageView = (ImageView) findViewById(R.id.IMAGE);
ContentResolver cr = getContentResolver();
Bitmap bitmap;
try {
bitmap = android.provider.MediaStore.Images.Media
.getBitmap(cr, selectedImage);
imageView.setImageBitmap(bitmap);
Toast.makeText(this, "This file: "+selectedImage.toString(),
Toast.LENGTH_LONG).show();
} catch (Exception e) {
Toast.makeText(this, "Failed to load", Toast.LENGTH_SHORT)
.show();
Log.e("Camera", e.toString());
}
}
}
}
}
use this as your main.xml layout
使用它作为你的 main.xml 布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello" />
<ImageView
android:id="@+id/IMAGE"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_launcher" />
</LinearLayout>
strings.xml
字符串.xml
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<resources>
<string name="hello">Hello World, TonyPicturesInc!</string>
<string name="app_name">TGCam</string>
</resources>
回答by Dharmendra
Hey you have to look in this answer it may help you.
嘿,您必须查看此答案,它可能对您有所帮助。
or also you can use Intent to start inbuilt camera like below
或者您也可以使用 Intent 启动内置相机,如下所示
Intent i = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(i, CAMERA_RESULT);
And you have to get result from camera activity like below code
你必须像下面的代码一样从相机活动中得到结果
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK && requestCode == CAMERA_RESULT) {
Bundle extras = data.getExtras();
if(extras.containsKey("data")) {
Bitmap bmp = (Bitmap) extras.get("data");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.PNG, 100, baos);
byte[] image = baos.toByteArray();
if(image != null) {
BitmapFactory.Options options=new BitmapFactory.Options();
options.inSampleSize = 5;
Bitmap myImage = BitmapFactory.decodeByteArray(image , 0, image.length, options);
imageView.setImageBitmap(myImage);
}
}else {
Toast.makeText(getBaseContext(), "Please capture again", Toast.LENGTH_LONG).show();
}
}
}