Ошибка сохранения изображения с камеры (cwac camera)
Я пытаюсь реализовать библиотеку cwac camera для фотографирования и хранения их. Когда я тестировал код на htc desire hd, было несколько осложнений. Это скриншот предварительного просмотра камеры.
И когда я делаю снимок, он показывает предварительный просмотр изображения как
Коды, которые я имею для этого, следующие. Это действие для реализации фрагмента предварительного просмотра камеры.
public class Camera extends ActionBarActivity implements CameraPreviewFragment.Contract {
private static final String STATE_SINGLE_SHOT="single_shot";
private static final String STATE_LOCK_TO_LANDSCAPE=
"lock_to_landscape";
private static final int CONTENT_REQUEST=1337;
private CameraPreviewFragment std=null;
private CameraPreviewFragment ffc=null;
private CameraPreviewFragment current=null;
private boolean hasTwoCameras=(android.hardware.Camera.getNumberOfCameras() > 1);
private boolean singleShot=false;
private boolean isLockedToLandscape=false;
private Toolbar mToolbar;
private void setToolBar(int toolbarId){
mToolbar = (Toolbar) findViewById(toolbarId);
if (mToolbar != null) {
setSupportActionBar(mToolbar);
getSupportActionBar().setLogo(R.drawable.ic_launcher);
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera);
setToolBar(R.id.toolbar);
if (savedInstanceState == null) {
CameraPreviewFragment frag = new CameraPreviewFragment();
frag = CameraPreviewFragment.newInstance(false);
getFragmentManager().beginTransaction()
.add(R.id.container, frag)
.commit();
}
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
setSingleShotMode(savedInstanceState.getBoolean(STATE_SINGLE_SHOT));
isLockedToLandscape=
savedInstanceState.getBoolean(STATE_LOCK_TO_LANDSCAPE);
if (current != null) {
current.lockToLandscape(isLockedToLandscape);
}
}
@Override
protected void onSaveInstanceState(Bundle outState) {
outState.putBoolean(STATE_SINGLE_SHOT, isSingleShotMode());
outState.putBoolean(STATE_LOCK_TO_LANDSCAPE, isLockedToLandscape);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_menu_camera, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
public boolean isSingleShotMode() {
return true;
}
@Override
public void setSingleShotMode(boolean mode) {
}
}
И вот мой фрагмент предварительного просмотра камеры (для загрузки камеры и имеет кнопку для съемки)
public class CameraPreviewFragment extends CameraFragment implements SeekBar.OnSeekBarChangeListener, View.OnClickListener{
private static final String DEBUG = CameraPreviewFragment.class.getSimpleName();
private static final String KEY_USE_FFC=
"com.commonsware.cwac.camera.demo.USE_FFC";
private MenuItem singleShotItem=null;
private boolean singleShotProcessing=false;
private static final int FLASH_ALWAYS_OFF = 0;
private static final int FLASH_ALWAYS_ON = 1;
private static final int FLASH_AUTO_MODE = 2;
private SeekBar zoom=null;
private View mCameraView;
private ImageButton mTakePicture;
private Button mFlashButton;
private Button mGridButton;
private ImageView mGridLines;
private long lastFaceToast=0L;
private int flashState = 2;
String flashMode=null, autoFlashMode=null, noFlashMode= null;
private DemoCameraHost cameraHost;
static CameraPreviewFragment newInstance(boolean useFFC) {
CameraPreviewFragment f=new CameraPreviewFragment();
Bundle args=new Bundle();
args.putBoolean(KEY_USE_FFC, useFFC);
f.setArguments(args);
return(f);
}
@Override
public void onCreate(Bundle state) {
super.onCreate(state);
setHasOptionsMenu(true);
cameraHost = new DemoCameraHost(getActivity());
SimpleCameraHost.Builder builder=
new SimpleCameraHost.Builder(cameraHost);
setHost(builder.useFullBleedPreview(true).build());
}
@Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
mCameraView=
super.onCreateView(inflater, container, savedInstanceState);
View results=inflater.inflate(R.layout.fragment_camera, container, false);
mCameraView.setOnClickListener(this);
mGridLines = (ImageView) results.findViewById(R.id.ivGridLines);
mTakePicture = (ImageButton) results.findViewById(R.id.ibCaptureButton);
mTakePicture.setOnClickListener(this);
mFlashButton = (Button) results.findViewById(R.id.bFlash);
mFlashButton.setOnClickListener(this);
mGridButton = (Button) results.findViewById(R.id.bGrid);
mGridButton.setOnClickListener(this);
((ViewGroup) results.findViewById(R.id.camera)).addView(mCameraView);
zoom=(SeekBar)results.findViewById(R.id.sbZoomControl);
zoom.setKeepScreenOn(true);
return(results);
}
@Override
public void onPause() {
super.onPause();
getActivity().invalidateOptionsMenu();
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu_camera, menu);
singleShotItem=menu.findItem(R.id.single_shot);
singleShotItem.setChecked(getContract().isSingleShotMode());
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.single_shot:
item.setChecked(!item.isChecked());
getContract().setSingleShotMode(item.isChecked());
return(true);
case R.id.show_zoom:
item.setChecked(!item.isChecked());
zoom.setVisibility(item.isChecked() ? View.VISIBLE : View.GONE);
return(true);
}
return(super.onOptionsItemSelected(item));
}
boolean isSingleShotProcessing() {
return(singleShotProcessing);
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
if (fromUser) {
zoom.setEnabled(false);
zoomTo(zoom.getProgress()).onComplete(new Runnable() {
@Override
public void run() {
zoom.setEnabled(true);
}
}).go();
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
// ignore
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
// ignore
}
Contract getContract() {
return((Contract)getActivity());
}
void takeSimplePicture() {
if (singleShotItem!=null && singleShotItem.isChecked()) {
singleShotProcessing=true;
mTakePicture.setEnabled(false);
}
PictureTransaction xact=new PictureTransaction(getHost());
xact.flashMode(getFlashMode());
takePicture(xact);
}
@Override
public void onClick(View v) {
if(v == mTakePicture){
takeSimplePicture();
}
if(v == mFlashButton){
if(flashState == FLASH_ALWAYS_OFF){
//flash to be always on
flashState = FLASH_ALWAYS_ON;
setFlashMode(flashMode);
Toast.makeText(getActivity(), "Flash! on", Toast.LENGTH_SHORT).show();
}else if(flashState == FLASH_ALWAYS_ON){
flashState = FLASH_AUTO_MODE;
setFlashMode(autoFlashMode);
Toast.makeText(getActivity(), "Flash! auto", Toast.LENGTH_SHORT).show();
}else if(flashState == FLASH_AUTO_MODE){
flashState = FLASH_ALWAYS_OFF;
setFlashMode(noFlashMode);
Toast.makeText(getActivity(), "Flash! off", Toast.LENGTH_SHORT).show();
}
}
if(v == mCameraView){
Log.i(DEBUG,"OnClick autofocus");
autoFocus();
}
if(v == mGridButton){
if(mGridLines.getVisibility() == View.VISIBLE){
mGridLines.setVisibility(View.GONE);
}else if(mGridLines.getVisibility() == View.GONE){
mGridLines.setVisibility(View.VISIBLE);
}
}
}
interface Contract {
boolean isSingleShotMode();
void setSingleShotMode(boolean mode);
}
class DemoCameraHost extends SimpleCameraHost implements
android.hardware.Camera.FaceDetectionListener {
boolean supportsFaces=false;
public DemoCameraHost(Context _ctxt) {
super(_ctxt);
}
@Override
protected File getPhotoDirectory() {
return CameraUtility.getOutputDirectory(CameraUtility.DIRECTORY_TYPE_CAMERA);
}
@Override
public boolean useFrontFacingCamera() {
if (getArguments() == null) {
return(false);
}
return(getArguments().getBoolean(KEY_USE_FFC));
}
@Override
public boolean useSingleShotMode() {
if (singleShotItem == null) {
return(false);
}
return(singleShotItem.isChecked());
}
@Override
public Camera.Size getPictureSize(PictureTransaction xact, Camera.Parameters parameters) {
return super.getPictureSize(xact, parameters);
}
@Override
public void saveImage(PictureTransaction xact, byte[] image) {
if (useSingleShotMode()) {
singleShotProcessing=false;
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
mTakePicture.setEnabled(true);
}
});
ImagePreviewActivity.imageToShow=image;
startActivity(new Intent(getActivity(), ImagePreviewActivity.class));
}
else {
String path = getPhotoFilename();
super.saveImage(xact, image);
}
}
@Override
public void autoFocusAvailable() {
if (supportsFaces)
startFaceDetection();
}
@Override
public void autoFocusUnavailable() {
stopFaceDetection();
}
@Override
public void onCameraFail(CameraHost.FailureReason reason) {
super.onCameraFail(reason);
Toast.makeText(getActivity(),
"Sorry, but you cannot use the camera now!",
Toast.LENGTH_LONG).show();
}
@Override
public android.hardware.Camera.Parameters adjustPreviewParameters(android.hardware.Camera.Parameters parameters) {
autoFlashMode =
CameraUtils.findBestFlashModeMatch(parameters,
android.hardware.Camera.Parameters.FLASH_MODE_RED_EYE,
android.hardware.Camera.Parameters.FLASH_MODE_AUTO,
android.hardware.Camera.Parameters.FLASH_MODE_ON);
flashMode = CameraUtils.findBestFlashModeMatch(parameters,
android.hardware.Camera.Parameters.FLASH_MODE_ON);
noFlashMode = CameraUtils.findBestFlashModeMatch(parameters,
Camera.Parameters.FLASH_MODE_OFF);
if (doesZoomReallyWork() && parameters.getMaxZoom() > 0) {
zoom.setMax(parameters.getMaxZoom());
zoom.setOnSeekBarChangeListener(CameraPreviewFragment.this);
}
else {
zoom.setEnabled(false);
}
if (parameters.getMaxNumDetectedFaces() > 0) {
supportsFaces=true;
}
else {
Toast.makeText(getActivity(),
"Face detection not available for this camera",
Toast.LENGTH_LONG).show();
}
return(super.adjustPreviewParameters(parameters));
}
@Override
public void onFaceDetection(android.hardware.Camera.Face[] faces, android.hardware.Camera camera) {
if (faces.length > 0) {
long now= SystemClock.elapsedRealtime();
if (now > lastFaceToast + 10000) {
Toast.makeText(getActivity(), "I see your face!",
Toast.LENGTH_LONG).show();
lastFaceToast=now;
}
}
}
@Override
protected File getPhotoPath() {
return super.getPhotoPath();
}
@Override
@TargetApi(16)
public void onAutoFocus(boolean success, android.hardware.Camera camera) {
super.onAutoFocus(success, camera);
mTakePicture.setEnabled(true);
}
}
}
Это для просмотра снятого изображения. ImagePreviewActivity
public class ImagePreviewActivity extends ActionBarActivity {
static byte[] imageToShow = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (imageToShow == null) {
Toast.makeText(this, R.string.no_image, Toast.LENGTH_LONG).show();
finish();
} else {
ImageView iv = new ImageView(this);
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inPurgeable = true;
opts.inInputShareable = true;
opts.inMutable = false;
opts.inSampleSize = 2;
iv.setScaleType(ImageView.ScaleType.FIT_CENTER);
iv.setImageBitmap(BitmapFactory.decodeByteArray(imageToShow,
0,
imageToShow.length,
opts));
imageToShow = null;
iv.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
setContentView(iv);
}
}
}
А что касается макетов XML у меня есть: для CameraPrevirewFragment
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.ballard.CWACCamera.Camera$PlaceholderFragment"
android:orientation="vertical"
android:weightSum="4">
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight="3">
<FrameLayout
android:id="@+id/camera"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@android:drawable/gallery_thumb"
android:id="@+id/ivGridLines"
android:visibility="gone"/>
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1">
<SeekBar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/sbZoomControl"
android:layout_alignParentTop="true"
android:background="@null"
android:layout_toLeftOf="@+id/bFlash"
android:layout_alignBottom="@+id/bFlash"
android:layout_toRightOf="@+id/bGrid"
android:layout_toEndOf="@+id/bGrid" />
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/ibCaptureButton"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:src="@android:drawable/ic_menu_camera"
android:background="@null"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Flash"
android:id="@+id/bFlash"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Grid"
android:id="@+id/bGrid"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
</RelativeLayout>
</LinearLayout>
и для камеры деятельности у меня есть
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:id="@+id/rlHomeLayout"
android:layout_width="match_parent" android:layout_height="match_parent"
tools:context="com.example.ballard.Login.Home" tools:ignore="MergeRootFrame"
>
<include
android:id="@+id/toolbar"
layout="@layout/toolbar"/>
<FrameLayout`enter code here`
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/toolbar">
</FrameLayout>
</RelativeLayout>
Я использую панель инструментов v7 в качестве панели действий и выглядит следующим образом (toolbar.xml)
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimaryDark"/>
Я попробовал демо-версию библиотеки и отлично работает на том же мобильном устройстве. Также, кажется, нет проблем, когда я тестировал ее на Nexus 5. Я пробую эту библиотеку впервые и не имею понятия, как решить эту проблему.