Ошибка сохранения изображения с камеры (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. Я пробую эту библиотеку впервые и не имею понятия, как решить эту проблему.

0 ответов

Другие вопросы по тегам