如何在不使用意图的片段中拍摄和保存图片?

时间:2015-01-04 11:07:50

标签: android android-activity android-fragments android-camera

你好我想拍一张照片并将照片保存在片段中。 我的用户应该按一个按钮并拍照并保存,我的相机预览在我的片段中,所以我认为这些事情也应该在片段中发生,所以我试着把片段中的按钮带来但我得到了NullPointerException所以我试图得到位图并使用[this]将其发送到活动:Passing data between a fragment and its container activity但是它给了我阶级演员异常,我不知道该怎么做。 记住,我想拍摄并保存图片,任何帮助都会很精彩。谢谢 这是我在相机片段中的代码:

public class CameraFragment extends Fragment {
 private Preview mPreview;
 Camera mCamera;
 int mNumberOfCameras;
    // The first rear facing camera
    int mDefaultCameraId;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        Log.d("aron", "we are in oncreate");
        super.onCreate(savedInstanceState);
        // Create a container that will hold a SurfaceView for camera previews
        mPreview = new Preview(this.getActivity());
        Log.d("aron", "we are in oncreate and we made preview successfuly");
    }
    public interface OnDataPass {
        public void onDataPass(Bitmap data);
    }
    OnDataPass dataPasser;

    @Override
    public void onAttach(Activity a) {
        super.onAttach(a);
        Log.d("aron", "we are in onattach");
        dataPasser = (OnDataPass) a;
    }
    public void passData() {
        Bitmap data=mPreview.getBitmap();
        Log.d("aron", "we are in passdata");
        dataPasser.onDataPass(data);
    }
    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        // Add an up arrow to the "home" button, indicating that the button will go "up"
        // one activity in the app's Activity heirarchy.
        // Calls to getActionBar() aren't guaranteed to return the ActionBar when called
        // from within the Fragment's onCreate method, because the Window's decor hasn't been
        // initialized yet.  Either call for the ActionBar reference in Activity.onCreate()
        // (after the setContentView(...) call), or in the Fragment's onActivityCreated method.
       /* Activity activity = this.getActivity();
        ActionBar actionBar = activity.getActionBar();
        actionBar.setDisplayHomeAsUpEnabled(true);*/
        Log.d("aron", "we are in onactivitycreated and we are done with it");
    }
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        Log.d("aron", "we are in oncreateview");
        return mPreview;
    }
    @Override
    public void onResume() {
        super.onResume();
        // Use mCurrentCamera to select the camera desired to safely restore
        // the fragment after the camera has been changed
        mCamera = Camera.open();
        mPreview.setCamera(mCamera);
        Log.d("aron", "we are in onresume");
    }
    @Override
    public void onPause() {
        super.onPause();
        // Because the Camera object is a shared resource, it's very
        // important to release it when the activity is paused.
        if (mCamera != null) {
            mPreview.setCamera(null);
            mCamera.release();
            mCamera = null;
        }
        Log.d("aron", "we are in onpause");
    }
   /* @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        if (mNumberOfCameras > 1) {
            // Inflate our menu which can gather user input for switching camera
            inflater.inflate(R.menu.main, menu);
        } else {
            super.onCreateOptionsMenu(menu, inflater);
        }
    }
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle item selection
        switch (item.getItemId()) {
        case R.id.menu_switch_cam:
            // Release this camera -> mCameraCurrentlyLocked
            if (mCamera != null) {
                mCamera.stopPreview();
                mPreview.setCamera(null);
                mCamera.release();
                mCamera = null;
            }
            // Acquire the next camera and request Preview to reconfigure
            // parameters.
            mCurrentCamera = (mCameraCurrentlyLocked + 1) % mNumberOfCameras;
            mCamera = Camera.open(mCurrentCamera);
            mCameraCurrentlyLocked = mCurrentCamera;
            mPreview.switchCamera(mCamera);
            // Start the preview
            mCamera.startPreview();
            return true;
        case android.R.id.home:
            Intent intent = new Intent(this.getActivity(), MainActivity.class);
            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_SINGLE_TOP);
            startActivity(intent);
            return true;
        default:
            return super.onOptionsItemSelected(item);
        }
    }*/
}
// ----------------------------------------------------------------------
/**
 * A simple wrapper around a Camera and a SurfaceView that renders a centered
 * preview of the Camera to the surface. We need to center the SurfaceView
 * because not all devices have cameras that support preview sizes at the same
 * aspect ratio as the device's display.
 */
class Preview extends ViewGroup implements SurfaceHolder.Callback {
    private final String TAG = "Preview";
    SurfaceView mSurfaceView;
    SurfaceHolder mHolder;
    Bitmap cameraBitmap;
    Size mPreviewSize;
    List<Size> mSupportedPreviewSizes;
    Camera mCamera;
    boolean mSurfaceCreated = false;
    Preview(Context context) {
        super(context);
        mSurfaceView = new SurfaceView(context);
        addView(mSurfaceView);
        // Install a SurfaceHolder.Callback so we get notified when the
        // underlying surface is created and destroyed.
        mHolder = mSurfaceView.getHolder();
        mHolder.addCallback(this);
    }
    public void setCamera(Camera camera) {
        mCamera = camera;
        if (mCamera != null) {
            mSupportedPreviewSizes = mCamera.getParameters()
                    .getSupportedPreviewSizes();
            if (mSurfaceCreated) requestLayout();
        }
    }
    public void switchCamera(Camera camera) {
        setCamera(camera);
        try {
            camera.setPreviewDisplay(mHolder);
        } catch (IOException exception) {
            Log.e(TAG, "IOException caused by setPreviewDisplay()", exception);
        }
    }
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        // We purposely disregard child measurements because act as a
        // wrapper to a SurfaceView that centers the camera preview instead
        // of stretching it.
        final int width = resolveSize(getSuggestedMinimumWidth(),
                widthMeasureSpec);
        final int height = resolveSize(getSuggestedMinimumHeight(),
                heightMeasureSpec);
        setMeasuredDimension(width, height);
        if (mSupportedPreviewSizes != null) {
            mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width,
                    height);
        }
        if (mCamera != null) {
          Camera.Parameters parameters = mCamera.getParameters();
          parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
          mCamera.setParameters(parameters);
        }
    }
    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        if (getChildCount() > 0) {
            final View child = getChildAt(0);
            final int width = r - l;
            final int height = b - t;
            int previewWidth = width;
            int previewHeight = height;
            if (mPreviewSize != null) {
                previewWidth = mPreviewSize.width;
                previewHeight = mPreviewSize.height;
            }
            // Center the child SurfaceView within the parent.
            if (width * previewHeight > height * previewWidth) {
                final int scaledChildWidth = previewWidth * height
                        / previewHeight;
                child.layout((width - scaledChildWidth) / 2, 0,
                        (width + scaledChildWidth) / 2, height);
            } else {
                final int scaledChildHeight = previewHeight * width
                        / previewWidth;
                child.layout(0, (height - scaledChildHeight) / 2, width,
                        (height + scaledChildHeight) / 2);
            }
        }
    }
    public void surfaceCreated(SurfaceHolder holder) {
        // The Surface has been created, acquire the camera and tell it where
        // to draw.
        try {
            if (mCamera != null) {
                mCamera.setPreviewDisplay(holder);
            }
        } catch (IOException exception) {
            Log.e(TAG, "IOException caused by setPreviewDisplay()", exception);
        }
        if (mPreviewSize == null) requestLayout();
        mSurfaceCreated = true;
    }
    public void surfaceDestroyed(SurfaceHolder holder) {
        // Surface will be destroyed when we return, so stop the preview.
        if (mCamera != null) {
            mCamera.stopPreview();
        }
    }
    private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) {
        final double ASPECT_TOLERANCE = 0.1;
        double targetRatio = (double) w / h;
        if (sizes == null)
            return null;
        Size optimalSize = null;
        double minDiff = Double.MAX_VALUE;
        int targetHeight = h;
        // Try to find an size match aspect ratio and size
        for (Size size : sizes) {
            double ratio = (double) size.width / size.height;
            if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE)
                continue;
            if (Math.abs(size.height - targetHeight) < minDiff) {
                optimalSize = size;
                minDiff = Math.abs(size.height - targetHeight);
            }
        }
        // Cannot find the one match the aspect ratio, ignore the requirement
        if (optimalSize == null) {
            minDiff = Double.MAX_VALUE;
            for (Size size : sizes) {
                if (Math.abs(size.height - targetHeight) < minDiff) {
                    optimalSize = size;
                    minDiff = Math.abs(size.height - targetHeight);
                }
            }
        }
        return optimalSize;
    }
    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
        // Now that the size is known, set up the camera parameters and begin
        // the preview.
        Camera.Parameters parameters = mCamera.getParameters();
        parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
        requestLayout();
        Log.d("aron", "we are in surface changed");
        mCamera.setParameters(parameters);
        mCamera.startPreview();
    }
    public Bitmap getBitmap(){
        @SuppressWarnings("unused")
        PictureCallback pic=new PictureCallback() {
            @Override
            public void onPictureTaken(byte[] data, Camera arg1) {
                Log.d("aron", "onPicturetaken");
                cameraBitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
            }
        };
        return cameraBitmap;
    }
}

中表示ClassCastException
  

dataPasser =(OnDataPass)a;

请注意,由于项目的其他部分,我不想使用意图。 请帮帮我!!!

这是我的主持人活动:

public class MainActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    ImageButton capturebtn=(ImageButton)findViewById(R.id.capturebtn);
    Log.d("aron", "Image button is created");
    capturebtn.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View view) {
            @SuppressWarnings("unused")
            OnDataPass bitmapPasser=new OnDataPass() {
                @Override
                public void onDataPass(Bitmap cameraBitmap) {
                    Log.d("aron","we are in act on click and in datapass got bitmap");
                     int  wid = cameraBitmap.getWidth();
                     int  hgt = cameraBitmap.getHeight();
                     Bitmap newImage = Bitmap.createBitmap(wid, hgt, Bitmap.Config.ARGB_8888);
                     Canvas canvas = new Canvas(newImage); 
                     canvas.drawBitmap(cameraBitmap, 0f, 0f, null);
                     Log.d("aron","bitmap and canvas are made");
                     FrameLayout frm = (FrameLayout)findViewById(R.id.frameLayout1);
                     frm.setDrawingCacheEnabled(true);
                     frm.buildDrawingCache();
                     Bitmap bitmap = frm.getDrawingCache();
                     canvas.drawBitmap(bitmap, 0f, 0f, null);
                     Log.d("aron","framelayout dorost shod");
                }
            };
        }
    });
}
}

你可以看到我实现了OnDataPass。

1 个答案:

答案 0 :(得分:0)

所以一段时间后我自己解决了问题,可以使用

  

Camera.PictureCallback

我现在这样做。就像这样:

    @Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    View myActivityView=(RelativeLayout)getActivity().findViewById(R.id.parentContainer);
    ImageButton capturebtn=(ImageButton)myActivityView.findViewById(R.id.capturebtn);
    capturebtn.setOnClickListener(new View.OnClickListener() {
        @SuppressWarnings("UnusedDeclaration")
        @Override
        public void onClick(View v) {
            Log.d("aron", "this is in fragment and this is a damned button say halelooya");
            mPreview.TakePicture();
        }
    });
}

你可以在onActivity的片段中看到我调用了片段父活动并调用了拍照的方法。