0
我對Android非常陌生,正試圖做一些簡單的事情:使用相機API,我想捕獲圖像並將其保存到目錄。Android:保存時捕獲的圖像爲零字節
我認爲我的主要問題是picturecallback()類。通過此代碼,我可以將JPEG圖像保存到SD卡上的已知目錄中。我可以看到它在正確的位置;但是,文件大小爲0字節,無法打開。
這裏是我的代碼:
PictureCallback myPictureCallback_JPG = new PictureCallback(){
@Override
public void onPictureTaken(byte[] arg0, Camera arg1) {
// TODO Auto-generated method stub
if (arg0 == null){
Toast.makeText(AndroidCamera.this,
"Image not saved. ",
Toast.LENGTH_LONG).show();
return;
//Why is it returning NULL the first time and a 0-byte thing next...
}
File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
if (pictureFile == null){
System.out.println("Error creating media file, check storage permissions: ");
return;
}
//
Uri uriTarget = getContentResolver().insert(Media.EXTERNAL_CONTENT_URI, new ContentValues());
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(arg0);
fos.close();
Toast.makeText(AndroidCamera.this,
"Image saved: " + uriTarget.toString(),
Toast.LENGTH_LONG).show();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
camera.startPreview();
}};
當通過調試去,字節數組arg0中似乎包含了很多隨機數從-255到255,我不知道爲什麼任何圖像值將apear除了它們並沒有被正確捕獲到第一個位置(捕獲發生在oncreate)之外。
這裏是主類:
package com.example.androidcamera;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
//import com.example.androidcamera.R;
import android.app.Activity;
import android.content.ContentValues;
import android.content.pm.ActivityInfo;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.hardware.Camera.AutoFocusCallback;
import android.hardware.Camera.PictureCallback;
import android.hardware.Camera.ShutterCallback;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore.Images.Media;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.Toast;
public class AndroidCamera extends Activity implements SurfaceHolder.Callback{
Camera camera;
SurfaceView surfaceView;
SurfaceHolder surfaceHolder;
boolean previewing = false;
LayoutInflater controlInflater = null;
Button buttonTakePicture;
final int RESULT_SAVEIMAGE = 0;
public static final int MEDIA_TYPE_IMAGE = 1;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
getWindow().setFormat(PixelFormat.UNKNOWN);
surfaceView = (SurfaceView)findViewById(R.id.camerapreview);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
controlInflater = LayoutInflater.from(getBaseContext());
View viewControl = controlInflater.inflate(R.layout.control, null);
LayoutParams layoutParamsControl
= new LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.FILL_PARENT);
this.addContentView(viewControl, layoutParamsControl);
buttonTakePicture = (Button)findViewById(R.id.takepicture);
buttonTakePicture.setOnClickListener(new Button.OnClickListener(){
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
//camera.takePicture(myShutterCallback,
//myPictureCallback_JPG, myPictureCallback_JPG);
camera.takePicture(null, null, myPictureCallback_JPG);
}
});
LinearLayout layoutBackground = (LinearLayout)findViewById(R.id.background);
layoutBackground.setOnClickListener(new LinearLayout.OnClickListener(){
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
buttonTakePicture.setEnabled(false);
camera.autoFocus(myAutoFocusCallback);
//camera.
}});
}
AutoFocusCallback myAutoFocusCallback = new AutoFocusCallback(){
@Override
public void onAutoFocus(boolean arg0, Camera arg1) {
// TODO Auto-generated method stub
buttonTakePicture.setEnabled(true);
}};
ShutterCallback myShutterCallback = new ShutterCallback(){
@Override
public void onShutter() {
// TODO Auto-generated method stub
}};
PictureCallback myPictureCallback_RAW = new PictureCallback(){
@Override
public void onPictureTaken(byte[] arg0, Camera arg1) {
// TODO Auto-generated method stub
}};
PictureCallback myPictureCallback_JPG = new PictureCallback(){
@Override
public void onPictureTaken(byte[] arg0, Camera arg1) {
// TODO Auto-generated method stub
if (arg0 == null){
Toast.makeText(AndroidCamera.this,
"Image not saved. ",
Toast.LENGTH_LONG).show();
return;
//Why is it returning NULL the first time and a 0-byte thing next...
}
File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
if (pictureFile == null){
System.out.println("Error creating media file, check storage permissions: ");
return;
}
//
Uri uriTarget = getContentResolver().insert(Media.EXTERNAL_CONTENT_URI, new ContentValues());
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(arg0);
fos.close();
Toast.makeText(AndroidCamera.this,
"Image saved: " + uriTarget.toString(),
Toast.LENGTH_LONG).show();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
camera.startPreview();
}};
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
if(previewing){
camera.stopPreview();
previewing = false;
}
if (camera != null){
try {
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
previewing = true;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
camera = Camera.open();
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
camera.stopPreview();
camera.release();
camera = null;
previewing = false;
}
/** Create a File for saving an image or video */
private static File getOutputMediaFile(int type){
// To be safe, you should check that the SDCard is mounted
// using Environment.getExternalStorageState() before doing this.
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "MyCameraApp");
// This location works best if you want the created images to be shared
// between applications and persist after your app has been uninstalled.
// Create the storage directory if it does not exist
if (! mediaStorageDir.exists()){
if (! mediaStorageDir.mkdirs()){
Log.d("MyCameraApp", "failed to create directory");
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File mediaFile;
if (type == MEDIA_TYPE_IMAGE){
mediaFile = new File(mediaStorageDir.getPath() + File.separator +
"IMG_"+ timeStamp + ".jpg");
} else {
return null;
}
return mediaFile;
}
@Override
protected void onPause() {
super.onPause();
releaseCamera(); // release the camera immediately on pause event
}
private void releaseCamera(){
if (camera != null){
camera.release(); // release the camera for other applications
camera = null;
}
}
}
我AndroidManifest文件:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.androidcamera"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/ic_launcher" android:label="@string/app_name">
<activity android:name="AndroidCamera"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-sdk android:minSdkVersion="8" />
<uses-permission android:name="android.permission.CAMERA"></uses-permission>
<uses-feature android:name="android.hardware.camera" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-feature android:name="android.hardware.camera.autofocus" />
</manifest>
最後我主要的XML文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/background"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="bottom"
>
<Button
android:id="@+id/takepicture"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=" * Take Picture "
android:layout_gravity="right"
android:layout_margin="10dp"
/>
</LinearLayout>
提前非常感謝。
謝謝,果然實際的圖像在別處結束了。令人困惑的是,在我重啓手機之前,我實際上無法看到其他目錄中的圖像!這是正常的嗎? – user3502402
這不是_normal_,但預計。要「查看」添加的照片,[運行MediaScanner](http://developer.android.com/training/camera/photobasics.html#TaskGallery)。 –