问题
Below is the code for a custom camera app I'm working on. Everthing works fine, except when the images are taken with flash on. With flash on, the preview showed to the user to accept the image looks right, but the image saved to the sdcard is very dark (with only white objects slightly visible) and often just black. I've been trying to figure out the problem for days now. Any ideas what might be going on?
public class CustomCamera extends Activity implements SurfaceHolder.Callback{
Camera camera;
Surfaceview surfaceView;
SurfaceHolder surfaceHolder;
boolean previewing = false;
LayoutInflater controlInflater = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.main);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
getWindow().setFormat(PixelFormat.UNKNOWN);
surfaceView = (SurfaceView)findViewById(R.id.camerapreview);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
...
}
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
if(previewing){
camera.stopPreview();
previewing = false;
}
if (camera != null){
try {
Camera.Parameters parameters = camera.getParameters();
camera.setDisplayOrientation(90);
determineDisplayOrientation();
camera.setPreviewDisplay(surfaceHolder);
previewing = true;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB){
List<String> supportedFocusModes = parameters.getSupportedFocusModes();
if (supportedFocusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)){
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
} else{
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
}
}
if (parameters.getSupportedWhiteBalance().contains(
Parameters.WHITE_BALANCE_AUTO)) {
parameters.setWhiteBalance(Parameters.WHITE_BALANCE_AUTO);
}
if (parameters.getSupportedSceneModes().contains(
Parameters.SCENE_MODE_AUTO)) {
parameters.setSceneMode(Parameters.SCENE_MODE_AUTO);
}
camera.setParameters(parameters);
camera.startPreview();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
flashButton.setBackgroundResource(R.drawable.auto_flash);
camera = Camera.open(CURRENT_CAMERA_ID);
Camera.Parameters camParameters = camera.getParameters();
flashSupported = getApplicationContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);
if ( flashSupported){
camParameters.setFlashMode(Parameters.FLASH_MODE_AUTO);
lastFlashMode = AUTO_FLASH;
camera.setParameters(camParameters);
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
camera.stopPreview();
camera.release();
camera = null;
previewing = false;
}
//click listener for button to take picture
public void takePicture(View view){
if (camera != null){
orientationListener.rememberOrientation();
camera.takePicture(myShutterCallback, myPictureCallback_RAW, myPictureCallback_JPG);
showPicPreviewScreen();
}
}
Camera.ShutterCallback myShutterCallback = new Camera.ShutterCallback() {
@Override
public void onShutter() {
}
};
Camera.PictureCallback myPictureCallback_RAW = new Camera.PictureCallback(){
@Override
public void onPictureTaken(byte[] arg0, Camera arg1) {
}
};
Camera.PictureCallback myPictureCallback_JPG = new Camera.PictureCallback(){
@Override
public void onPictureTaken(byte[] arg0, Camera arg1) {
bitmapPicture = BitmapFactory.decodeByteArray(arg0, 0, arg0.length);
int rotation = (displayOrientation + orientationListener.getRememberedOrientation() + layoutOrientation) % 360;
if (rotation != 0){
Log.e("rotaion", "not 0, rotating");
Bitmap oldBitmap = bitmapPicture;
Matrix matrix = new Matrix();
matrix.postRotate(rotation);
bitmapPicture = Bitmap.createBitmap(bitmapPicture, 0, 0, bitmapPicture.getWidth(), bitmapPicture.getHeight(), matrix, false);
oldBitmap.recycle();
}
camera.stopPreview();
previewing = false;
ImageSaver imageSaver = new ImageSaver();
imageSaver.saveImage(getApplicationContext(), bitmapPicture);
}
};
}
And here's the class that saves the image
public class ImageSaver{
private Context context;
private String NameOfFolder = "/ProjectFolder";
String fileName;
String file_path;
public void saveImage(Context context,Bitmap ImageToSave){
context = context;
file_path = Environment.getExternalStorageDirectory().getAbsolutePath()+ NameOfFolder;
String CurrentDateAndTime= getCurrentDateAndTime();
File dir = new File(file_path);
if(!dir.exists()){
dir.mkdirs();
}
fileName = CurrentDateAndTime+ ".jpg";
File file = new File(dir, fileName);
try {
FileOutputStream fOut = new FileOutputStream(file);
ImageToSave.compress(Bitmap.CompressFormat.JPEG, 100, fOut); //85
fOut.flush();
fOut.close();
}
catch (FileNotFoundException e) {UnableToSave();}
catch (IOException e){UnableToSave();}
}
private String getCurrentDateAndTime() {
Calendar c = Calendar.getInstance();
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
String formattedDate = df.format(c.getTime());
return formattedDate;
}
}
Thanks a lot!
来源:https://stackoverflow.com/questions/25344770/android-save-image-taken-with-flash-on-nexus-4