简体   繁体   中英

How to get current path from another class (Camera)

I am develop app that take a picture from my custom camera class and than take the path and put into imageView on Activity like a preview image , now i created a class that handle the Camera feature and send to the activity the path for the preview result . but my result is not the right picture i captured. example : At the first time i taking a picture my "currentPicpath" is null, but in the second time i take a picture it gives me the first image i captured before.

so, in the class 2 i created a method that get the Current path but steel not give null Unless a new picture taken.

and one more question.Why after the images are saved they are in the opposite? my classes:

MainActivity:
@Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.dialog_additem);

        d_image_pre1 = (ImageView) findViewById(R.id.d_image1);


        d_BTakePicture = (Button) findViewById(R.id.d_bTakePicture);
        bOpenCamera = (Button) findViewById(R.id.bOpenCamera);
        d_BTakePicture.setOnClickListener(this);
        bOpenCamera.setOnClickListener(this);

        take = new TakeApicture(this);

    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.bOpenCamera:
        take.openCam();
            break;
        case R.id.d_bTakePicture:

            take.makeFolder("myTest");
            take.captureImage();
            String path = take.getCurrentPicPath(); 

            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inSampleSize = 2;
            Bitmap bm = BitmapFactory.decodeFile(path, options);
            d_image_pre1.setImageBitmap(bm); 

            break;

        default:
            break;
        }       
    }

class 2 :

public class TakeApicture implements SurfaceHolder.Callback{

    Activity context;

    Camera camera;
    SurfaceView surface;
    SurfaceHolder holder;

    PictureCallback jpegCallback;

    File myGeneralFolder;
    FileOutputStream outStream = null;

    private String fullPathFolder;
    String currentPicPath = "No image path";


    @SuppressWarnings("deprecation")
    public TakeApicture(Activity context) {
        super();
        this.context = context;

        surface  = (SurfaceView)context.findViewById(R.id.surfaceView);
        holder = surface.getHolder();
        holder.addCallback(this);
         holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

           jpegCallBack();


    }


       public void captureImage() {
            camera.takePicture(null, null, jpegCallback);
        }



    public void makeFolder(String itemFolderName) {
        fullPathFolder = Environment.getExternalStorageDirectory()+File.separator+"mySalesImages"+File.separator+itemFolderName;
        myGeneralFolder = new  File(fullPathFolder);
        myGeneralFolder.mkdirs();
    }



    public void jpegCallBack(){
        jpegCallback = new PictureCallback() {
            @Override
            public void onPictureTaken(byte[] data, Camera camera) {
                    try {
                        getPicPath(data);

            } catch (IOException e) {
            e.printStackTrace();
            }
            }
        };
    }



    public void getPicPath(byte[] data) throws IOException{
        currentPicPath = String.format(myGeneralFolder+"/%d.jpg",(System.currentTimeMillis()));
        outStream = new FileOutputStream(currentPicPath);
        outStream.write(data); 
        outStream.close();
    }

    public String getCurrentPicPath() {
        return currentPicPath;
    }


    @SuppressWarnings("deprecation")
    public void openCam(){
        try {
        camera = Camera.open();
        Camera.Parameters param;
        param = camera.getParameters();
        //modify parameter
        camera.setDisplayOrientation(90);
        param.setPreviewFrameRate(20);
        param.setPreviewSize(176, 144);
        camera.setParameters(param);

        camera.setPreviewDisplay(holder);
        camera.startPreview();

        } catch (Exception e) {
            // TODO: handle exception
        }

    }


    public void closeCam(){
        camera.stopPreview();
        camera.release();
    }




    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        // TODO Auto-generated method stub

    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width,
            int height) {
        // TODO Auto-generated method stub

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        closeCam();
    }


}

This is the right solutions???

    take.captureImage();

    new Handler().postDelayed(new Runnable() {
        @Override
        public void run() {
    String path = take.getCurrentPicPath(); 


    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inSampleSize = 2;
    Bitmap bm = BitmapFactory.decodeFile(path, options);
    d_image_pre1.setImageBitmap(bm); 

        }
    }, 1000);

The line take.captureImage(); starts an asynchronous process of capturing a photo. After some while, the Android system will call your onPictureTaken() callback and you will compute a new image path (and write the photo accordingly). But the line

String path = take.getCurrentPicPath(); 

will have been already executed.

You can calculate the path synchronously, but even then your Activity must wait for the actual image to be written to disk. Therefore you have no choice but extract the piece

String path = take.getCurrentPicPath(); 

BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2;
Bitmap bm = BitmapFactory.decodeFile(path, options);
d_image_pre1.setImageBitmap(bm); 

into a separate method. You can call this new method directly from onPictureTaken() or you can use post() (no need to postDelayed() from onPictureTaken() ) to execute it asynchronously.


So, quick-and-dirty fix (exception handling removed for brevity) would be as follows:

in MainActivity.java :

public void onClick(View v) {
  switch (v.getId()) {
    case R.id.bOpenCamera:
      take.openCam();
      break;
    case R.id.d_bTakePicture:
      take.makeFolder("myTest");
      take.captureImage();
      break;
  }       
}

public void setImage(String path) {
  BitmapFactory.Options options = new BitmapFactory.Options();
  options.inSampleSize = 2;
  Bitmap bm = BitmapFactory.decodeFile(path, options);
  d_image_pre1.setImageBitmap(bm); 
}

in TakeApicture.java :

public void jpegCallBack() {
  jpegCallback = new PictureCallback() {
    public void onPictureTaken(byte[] data, Camera camera) {
      getPicPath(data);
      (MainActivity)context.setImage(currentPicPath);
    }
  };
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM