パブリッククラスMarkableImageCaptureActivityアクティビティはOnClickListenerを実装延び{ プライベート静的ロガーロガー= LoggerFactory.getLogger(MarkableImageCaptureActivity.class)。
@InjectView(R.id.top_menu_bar)
private LinearLayout topMenuLayout;
@InjectView(R.id.top_menu_title)
private TextView topMenuTitleTV;
@InjectView(R.id.image_desc_edittext)
private EditText imageDescEditText;
@InjectView(R.id.camerapreview_layout)
private FrameLayout cameraPreviewLayout;
@InjectView(R.id.btn_camera_capture)
private Button captureBtn;
@InjectView(R.id.btn_camera_save)
private Button saveBtn;
@InjectView(R.id.btn_camera_cancel)
private Button cancelBtn;
@InjectView(R.id.edit_captured_image_layout)
private RelativeLayout editCapturedImageLayout;
@InjectView(R.id.edit_captured_image)
private ImageView editCapturedImage;
@InjectView(R.id.color_container_layout)
private LinearLayout colorContainerLayout;
@InjectView(R.id.btn_markable_red)
private Button btnMarkableRed;
@InjectView(R.id.btn_markable_blue)
private Button btnMarkableBlue;
@InjectView(R.id.btn_markable_green)
private Button btnMarkableGreen;
@InjectView(R.id.btn_markable_white)
private Button btnMarkableWhite;
@InjectView(R.id.btn_markable_black)
private Button btnMarkableBlack;
@InjectView(R.id.btn_undo)
private TextView capturedImageUndo;
private MarkableImageView editableCapturedImageview;
@InjectView(R.id.flashSwitch)
private ToggleButton flashToggle;
private static final int DIALOG_CAPTURE_EXCEPTION = 2101;
private static final int DIALOG_CAPTURING_EXCEPTION = 2102;
private static final int DIALOG_SAVE_EXCEPTION = 0;
private String imageFileName = null;
private File imageFile = null;
private Stop targetStop = null;
private int stopId = DIntent.VALUE_INVALID_ID;
private float rotationDegrees = 0;
private Camera camera = null;
private CameraPreview cameraPreview;
private Bitmap rotatedBitmap;
private static final int PRIMARY_CAMERA_ID = 0;
private boolean imageCaptured = false;
private boolean inPreview = false;
private boolean isFlashSupports;
private boolean isCapturing = false;
private boolean isFlashOn;
private boolean isDocNameEditable;
private String imageDesc = "";
private Handler focusHandler = null;
private int captureType;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_start_camera_for_photo_capture);
setupTopMenuBar(topMenuLayout, null, getString(R.string.menuitem_back), getString(R.string.menuitem_done), true, true, new ImageCaptureTopMenuListener());
focusHandler = new Handler();
editableCapturedImageview = (MarkableImageView) findViewById(R.id.editable_captured_imageview);
Bundle intentBundle = getIntent().getExtras();
isDocNameEditable = getIntent().getBooleanExtra(DIntent.EXTRA_OBJECT_TYPE_DOCUMENT_EDITABLE, false);
imageDesc = getIntent().getStringExtra(DIntent.EXTRA_OBJECT_TYPE_DOCUMENT_NAME);
if (savedInstanceState != null) {
stopId = savedInstanceState.getInt(DIntent.EXTRA_STOP_ID);
imageDesc = savedInstanceState.getString(DIntent.EXTRA_IMAGE_DESC);
imageCaptured = savedInstanceState.getBoolean(DIntent.EXTRA_IS_IMAGE_CAPTURED);
inPreview = savedInstanceState.getBoolean(DIntent.EXTRA_IN_PREVIEW);
isFlashOn=savedInstanceState.getBoolean(DIntent.FLASH_MODE_ON);
if (imageCaptured) {
rotatedBitmap = savedInstanceState.getParcelable(DIntent.EXTRA_IMAGE_BITMAP);
}
}
captureType = intentBundle.getInt(DIntent.EXTRA_TYPE_CAPTURE);
if (captureType == DIntent.EXTRA_TYPE_IMAGE_CAPTURE) {
stopId = intentBundle.getInt(DIntent.EXTRA_STOP_ID);
try {
targetStop = getDbHelper().getStopDao().queryForId(stopId);
} catch (SQLException e) {
logger.error("Exception finding stop by Id!!", e);
}
}
isFlashSupports = getApplicationContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);
if (isFlashSupports) {
flashToggle.setVisibility(View.VISIBLE);
flashToggle.setOnClickListener(this);
} else {
flashToggle.setVisibility(View.GONE);
}
captureBtn.setOnClickListener(this);
saveBtn.setOnClickListener(this);
cancelBtn.setOnClickListener(this);
imageDescEditText.setText(imageDesc);
if (AndroidUtility.isValidTrimmedString(imageDesc)) {
if (!isDocNameEditable) {
imageDescEditText.setEnabled(false);
}
} else {
imageDescEditText.setEnabled(true);
}
editCapturedImage.setOnClickListener(this);
btnMarkableWhite.setOnClickListener(this);
btnMarkableRed.setOnClickListener(this);
btnMarkableBlue.setOnClickListener(this);
btnMarkableGreen.setOnClickListener(this);
btnMarkableBlack.setOnClickListener(this);
capturedImageUndo.setOnClickListener(this);
}
@Override
protected void onStart() {
super.onStart();
logger.info("onStart:imageCaptured" + imageCaptured);
boolean isImageCaptured = DeliverItApplication.getInstance().isImageCaptured();
if (!isImageCaptured) {
if (rotatedBitmap != null) {
activateCapturedImageView(rotatedBitmap);
} else {
activatePreviewLayout();
}
}
}
private void activateCapturedImageView(Bitmap rotatedBitmap) {
cameraPreviewLayout.setVisibility(View.GONE);
editableCapturedImageview.setCapturedBitmap(rotatedBitmap);
editableCapturedImageview.setVisibility(View.VISIBLE);
editCapturedImageLayout.setVisibility(View.VISIBLE);
captureBtn.setVisibility(View.GONE);
saveBtn.setVisibility(View.VISIBLE);
saveBtn.requestFocus();
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) editableCapturedImageview.getLayoutParams();
layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT, RelativeLayout.TRUE);
layoutParams.addRule(RelativeLayout.CENTER_VERTICAL, RelativeLayout.TRUE);
layoutParams.addRule(RelativeLayout.CENTER_HORIZONTAL, RelativeLayout.TRUE);
layoutParams.width = rotatedBitmap.getWidth();
layoutParams.height = rotatedBitmap.getHeight();
editableCapturedImageview.setLayoutParams(layoutParams);
logger.info("Inside activateCapturedImageView");
releaseCamera();
}
private void activatePreviewLayout() {
logger.info("Insie activatePreviewLayout");
cameraPreviewLayout.setVisibility(View.VISIBLE);
editableCapturedImageview.setVisibility(View.GONE);
editCapturedImageLayout.setVisibility(View.GONE);
captureBtn.setVisibility(View.VISIBLE);
captureBtn.requestFocus();
saveBtn.setVisibility(View.GONE);
}
@Override
protected void onResume() {
super.onResume();
logger.info("onResume");
if (rotatedBitmap == null || inPreview) {
activateCameraPreview();
}
}
public void activateCameraPreview() {
logger.info("activateCameraPreview");
camera = getCameraInstance(camera);
if (camera != null) {
cameraPreview = new CameraPreview(this, camera);
rotationDegrees = getCameraDisplayOrientation(this, PRIMARY_CAMERA_ID);
camera.setDisplayOrientation((int) rotationDegrees);
cameraPreviewLayout.addView(cameraPreview);
inPreview = true;
isCapturing = false;
Camera.Parameters params = camera.getParameters();
if (isFlashSupported(params)) {
logger.info("activateCameraPreview: Flash Mode:"+ isFlashOn);
if (isFlashOn) {
params.setFlashMode(Camera.Parameters.FLASH_MODE_ON);
} else {
params.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
}
} else {
flashToggle.setVisibility(View.GONE);
}
camera.setParameters(params);
enableAutoFocusMode(camera);
}
}
private Runnable doFocusRunnable = new Runnable() {
@Override
public void run() {
if (camera != null) {
focusHandler.removeCallbacks(doFocusRunnable);
if (CameraPreview.isCameraPreviewStarted) {
try {
camera.autoFocus(autoFocusCallback);
logger.info("doFocusRunnable autofocus set");
} catch (Exception e) {
logger.error("Error while calling autofocus in camera."+e);
}
} else {
logger.info("doFocusRunnable isCameraPreviewStarted false. Postdelay for 2 seconds");
focusHandler.postDelayed(doFocusRunnable, 2000);
}
}
}
};
Camera.AutoFocusCallback autoFocusCallback = new Camera.AutoFocusCallback(){
@Override
public void onAutoFocus(boolean arg0, Camera arg1) {
if (camera != null) {
logger.info("Excuting onAutoFocus callback");
focusHandler.postDelayed(doFocusRunnable, 2000);
}
}
};
public Camera getCameraInstance(Camera oldCamera) {
Camera newCamera = null;
try {
logger.info("attempt to get a Camera instance");
if (oldCamera == null) {
logger.info("oldCamera is null.Opening Camera");
newCamera = Camera.open(PRIMARY_CAMERA_ID);
} else {
logger.info("oldCamera is not null.Releasing it and Opening Camera");
oldCamera.release();
newCamera = Camera.open(PRIMARY_CAMERA_ID);
}
} catch (Exception e) {
logger.info("Camera is not available (in use or does not exist)");
}
return newCamera; // returns null if camera is unavailable
}
@Override
protected void onPause() {
super.onPause();
logger.info("onPause");
releaseCamera();
}
private void releaseCamera() {
if (null != camera) {
try {
focusHandler.removeCallbacks(doFocusRunnable);
CameraPreview.isCameraPreviewStarted = false;
camera.cancelAutoFocus();
camera.stopPreview();
camera.release();
camera = null;
cameraPreview.setVisibility(View.GONE);
cameraPreview = null;
inPreview = false;
logger.info("Camera released successfully ");
} catch (Exception e) {
logger.error("Error while releasing camera in releaseCamera()."+e);
}
}
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
logger.info("onSaveInstanceState");
outState.putInt(DIntent.EXTRA_STOP_ID, stopId);
outState.putBoolean(DIntent.EXTRA_IS_IMAGE_CAPTURED, imageCaptured);
outState.putBoolean(DIntent.EXTRA_IN_PREVIEW, inPreview);
outState.putString(DIntent.EXTRA_IMAGE_DESC, imageDesc);
}
@Override
protected void onDestroy() {
super.onDestroy();
logger.info("onDestroy");
DeliverItApplication.getInstance().setImageCaptured(false);
}
public float getCameraDisplayOrientation(Activity activity, int cameraId) {
CameraInfo info = new CameraInfo();
Camera.getCameraInfo(cameraId, info);
int displayOrientation = activity.getWindowManager().getDefaultDisplay().getRotation();
int infoOrientation = info.orientation;
float degrees = 0;
switch (displayOrientation) {
case Surface.ROTATION_0:
degrees = 0;
break;
case Surface.ROTATION_90:
degrees = 90;
break;
case Surface.ROTATION_180:
degrees = 180;
break;
case Surface.ROTATION_270:
degrees = 270;
break;
}
float result;
if (info.facing == CameraInfo.CAMERA_FACING_FRONT) {
logger.info("Camera.CameraInfo.CAMERA_FACING_FRONT");
result = (infoOrientation + degrees) % 360;
result = (360 - result) % 360; // compensate the mirror
} else { // back-facing
logger.info("Camera.CameraInfo.CAMERA_FACING_BACK");
result = (infoOrientation - degrees + 360) % 360;
}
logger.info("Display Rotation:" + displayOrientation + " & infoOrientation:" + infoOrientation + " & degrees:"
+ degrees + " & info.facing:" + info.facing + " & result:" + result);
return result;
}
private void captureImage() {
try {
if (camera != null) {
//camera.autoFocus(autoFocusCallback);
isCapturing = true;
logger.info("Taking picture while clicking Capture button");
camera.takePicture(null, null, pictureCallBack);
} else {
if (rotatedBitmap == null) {
showDialog(DIALOG_CAMERA_UNAVAILABLE);
}
}
} catch (Exception e) {
releaseCamera();
logger.error("Error in camera initialization in StartCaptureForPhoto screen.");
activatePreviewLayout();
activateCameraPreview();
}
}
private PictureCallback pictureCallBack = new PictureCallback() {
@Override
public void onPictureTaken(byte[] pData, Camera pCamera) {
BitmapFactory.Options bmFactoryOptions = new BitmapFactory.Options();
bmFactoryOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;
bmFactoryOptions.inMutable = true;
// bmFactoryOptions.inSampleSize = 2;
Bitmap originalCameraBitmap = BitmapFactory.decodeByteArray(pData, 0, pData.length, bmFactoryOptions);
logger.info("before resized bitmap width : "+originalCameraBitmap.getWidth() + " Hieght : "+ originalCameraBitmap.getHeight());
rotatedBitmap = getResizedBitmap(originalCameraBitmap, cameraPreviewLayout.getHeight(), cameraPreviewLayout.getWidth() - preSizePriviewHight(), (int) rotationDegrees);
logger.info("cameraPreviewLayout width : "+cameraPreviewLayout.getWidth() + " Hieght : "+ cameraPreviewLayout.getHeight());
if (rotatedBitmap != null) {
imageCaptured = true;
activateCapturedImageView(rotatedBitmap);
} else {
imageCaptured = false;
}
isCapturing = false;
originalCameraBitmap.recycle();
flashToggle.setVisibility(View.GONE);
}
};
public Bitmap getResizedBitmap(Bitmap bm, int newWidth, int newHeight, int angle) {
int width = bm.getWidth();
int height = bm.getHeight();
float scaleWidth = ((float) newWidth)/width;
float scaleHeight = ((float) newHeight)/height;
Matrix matrix = new Matrix();
matrix.postRotate(angle);
matrix.postScale(scaleWidth, scaleHeight);
Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, true);
DeliverItApplication.getInstance().setImageCaptured(true);
return resizedBitmap;
}
@Override
public void onClick(View pView) {
switch (pView.getId()) {
case R.id.btn_camera_capture:
if (!isCapturing) {
captureImage();
} else {
logger.error("Picture being captured.User clicked so fast.");
}
break;
case R.id.btn_camera_save:
if (imageCaptured) {
String description = imageDescEditText.getText().toString();
if (description != null && description.length() > 0) {
saveCapturedImage();
} else {
imageDescEditText.setError((getString(R.string.error_photo_desc)));
}
}
break;
case R.id.edit_captured_image:
colorContainerLayout.setVisibility(View.VISIBLE);
capturedImageUndo.setVisibility(View.VISIBLE);
editableCapturedImageview.setPaintBrushColor(Color.WHITE);
break;
case R.id.btn_markable_green:
editableCapturedImageview.setPaintBrushColor(Color.parseColor("#6AD523"));
break;
case R.id.btn_markable_blue:
editableCapturedImageview.setPaintBrushColor(Color.parseColor("#407FF0"));
break;
case R.id.btn_markable_red:
editableCapturedImageview.setPaintBrushColor(Color.parseColor("#B0321B"));
break;
case R.id.btn_markable_white:
editableCapturedImageview.setPaintBrushColor(Color.parseColor("#F7F5FA"));
break;
case R.id.btn_markable_black:
editableCapturedImageview.setPaintBrushColor(Color.parseColor("#2A2A2C"));
break;
case R.id.btn_undo:
editableCapturedImageview.onClickUndo();
break;
case R.id.btn_camera_cancel:
releaseCamera();
finish();
break;
case R.id.flashSwitch:
switchFlash();
default:
break;
}
}
@Override
protected Dialog onCreateDialog(int id, Bundle bundle) {
switch (id) {
case DIALOG_CAPTURE_EXCEPTION:
DIAlertDialog captureErrorDialog = new DIAlertDialog(this, getText(R.string.dialog_camera_error)
.toString(), getText(R.string.dialog_capture_exception).toString(), null, null);
return captureErrorDialog;
case DIALOG_SAVE_EXCEPTION:
DIAlertDialog imageSaveErrorDialog = new DIAlertDialog(this, getText(R.string.dialog_camera_error)
.toString(), getText(R.string.dialog_image_save_exception).toString(), null, null);
return imageSaveErrorDialog;
case DIALOG_CAPTURING_EXCEPTION:
DIAlertDialog capturingDialog = new DIAlertDialog(this, getText(R.string.dialog_camera_error)
.toString(), getText(R.string.dialog_capturing_exception).toString(), null, null);
return capturingDialog;
default:
return super.onCreateDialog(id, bundle);
}
}
private class ImageCaptureTopMenuListener implements OnClickListener {
@Override
public void onClick(View v) {
if (v.getVisibility() == View.VISIBLE && v.getId() == R.id.top_left_menu_item) {
onBackPressed();
} else if (v.getVisibility() == View.VISIBLE && v.getId() == R.id.top_right_menu_item) {
if (imageCaptured) {
String description = imageDescEditText.getText().toString();
if (description != null && description.length() > 0) {
saveCapturedImage();
} else {
imageDescEditText.setError((getString(R.string.error_photo_desc)));
}
}
}
}
}
private void switchFlash() {
if (camera == null) {
return;
}
if (!isFlashOn) {
Camera.Parameters params = camera.getParameters();
params.setFlashMode(Camera.Parameters.FLASH_MODE_ON);
camera.setParameters(params);
if (rotatedBitmap != null) {
activateCapturedImageView(rotatedBitmap);
} else {
activatePreviewLayout();
}
isFlashOn = true;
} else {
Camera.Parameters params = camera.getParameters();
params.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
camera.setParameters(params);
if (rotatedBitmap != null) {
activateCapturedImageView(rotatedBitmap);
} else {
activatePreviewLayout();
}
isFlashOn = false;
}
}
private int preSizePriviewHight() {
int defaultSize = 100;
switch (getResources().getDisplayMetrics().densityDpi) {
case DisplayMetrics.DENSITY_LOW:
defaultSize = 75;
break;
case DisplayMetrics.DENSITY_MEDIUM:
defaultSize = 80;
break;
case DisplayMetrics.DENSITY_HIGH:
defaultSize = 120;
break;
case DisplayMetrics.DENSITY_XHIGH:
defaultSize = 160;
break;
case DisplayMetrics.DENSITY_XXHIGH:
defaultSize = 430;
break;
case DisplayMetrics.DENSITY_XXXHIGH:
defaultSize = 460;
break;
default:
break;
}
return defaultSize;
}
private void enableAutoFocusMode(Camera camera) {
try {
Camera.Parameters params = camera.getParameters();
List<String> focusParameterList = params.getSupportedFocusModes();
if (focusParameterList != null && focusParameterList.size() > 0) {
logger.info("Supported focus mode:"+focusParameterList);
if (focusParameterList.contains(Camera.Parameters.FOCUS_MODE_AUTO)) {
logger.info("enableAutoFocusMode: Starting focus mode");
params.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
camera.setParameters(params);
/*
Below line commented due to crash issue in focus mode because of autoFocus call before start preview
So we are giving 2 sec delay for autoFocus.
*/
//camera.autoFocus(autoFocusCallback);
focusHandler.postDelayed(doFocusRunnable, 2000);
}
}
} catch (Exception e) {
logger.error("Error while setting AutoFocus in Camera."+e);
}
}
private boolean isFlashSupported(Camera.Parameters params) {
if (params != null) {
List<String> flashModes = params.getSupportedFlashModes();
if(flashModes == null) {
return false;
}
for(String flashMode : flashModes) {
if(Camera.Parameters.FLASH_MODE_ON.equals(flashMode)) {
return true;
}
}
}
return false;
}
@Override
protected void onStop() {
super.onStop();
if (editableCapturedImageview != null) {
editableCapturedImageview.resetCanvas();
}
}
}
パブリッククラスCameraPreviewはSurfaceViewがSurfaceHolder.Callback {
private static Logger logger = LoggerFactory.getLogger(CameraPreview.class);
private SurfaceHolder surfaceHolder;
private Camera camera;
private List<Size> cameraSizeList;
private Camera.Parameters cameraParameters;
public static boolean isCameraPreviewStarted = false;
public CameraPreview(Context context, Camera camera) {
super(context);
logger.info("Inside CameraPreview(Context context, Camera camera)");
this.camera = camera;
isCameraPreviewStarted = false;
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
surfaceHolder = getHolder();
surfaceHolder.addCallback(this);
// deprecated setting, but required on Android versions prior to 3.0
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void surfaceCreated(SurfaceHolder holder) {
try {
if (camera != null) {
logger.info("Camera Surface has been created, now tell the camera where to draw the preview.");
camera.setPreviewDisplay(holder);
camera.startPreview();
isCameraPreviewStarted = true;
}
} catch (IOException e) {
logger.error("Error occured in surfaceCreated.", e);
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
logger.info("Camera SurfaceView Destroyed.");
isCameraPreviewStarted = false;
}
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
if (surfaceHolder.getSurface() == null) {
if (logger.isDebugEnabled()) {
logger.debug("onsurfaceChanged : preview surface does not exist");
}
return;
}
try {
if (logger.isDebugEnabled()) {
logger.debug("onsurfaceChanged :stop preview before making resize/rotate/reformatting changes");
}
isCameraPreviewStarted = false;
camera.stopPreview();
} catch (Exception e) {
logger.error("onsurfaceChanged :Ignored surfaceChanged because tried to stop a non-existent preview", e);
}
if (camera != null) {
cameraParameters = camera.getParameters();
cameraSizeList = cameraParameters.getSupportedPreviewSizes();
cameraParameters.setPreviewSize(getMaxSupportedVideoSize().width, getMaxSupportedVideoSize().height);
surfaceHolder.setFixedSize(getMaxSupportedVideoSize().width, getMaxSupportedVideoSize().height);
camera.setParameters(cameraParameters);
if (logger.isDebugEnabled()) {
logger.debug("onsurfaceChanged : made resize/rotate/reformatting changes:preview size:"
+ String.valueOf(getMaxSupportedVideoSize().width) + ":"
+ String.valueOf(getMaxSupportedVideoSize().height));
}
}
try {
if (logger.isDebugEnabled()) {
logger.debug("onsurfaceChanged :start preview with new settings");
}
if (camera != null) {
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
logger.info("onsurfaceChanged :start preview with new settings");
isCameraPreviewStarted = true;
}
} catch (Exception e) {
logger.error("onsurfaceChanged :Error while resetting camera preview on surfaceChanged.", e);
}
}
public Size getMaxSupportedVideoSize() {
int maximum = cameraSizeList.get(0).width;
int position = 0;
for (int i = 0; i < cameraSizeList.size() - 1; i++) {
if (cameraSizeList.get(i).width > maximum) {
maximum = cameraSizeList.get(i).width; // new maximum
position = i - 1;
}
}
if (position == 0) {
int secondMax = cameraSizeList.get(1).width;
position = 1;
for (int j = 1; j < cameraSizeList.size() - 1; j++) {
if (cameraSizeList.get(j).width > secondMax) {
secondMax = cameraSizeList.get(j).width; // new maximum
position = j;
}
}
}
return cameraSizeList.get(position);
}
}
http://stackoverflow.com/questions/25244799/resizing-pictures-whileを実装延び安定した品質の中で これをチェックしてください。このgetscaledImage()メソッドでは、 float maxHeight = 800.0f; float maxWidth = 600.0f; あなたの要件に従ってそれを変更してください。 –
下記の私の答えを参照してください。 –