2015-12-05 4 views
11

Piszę program, w którym robię zdjęcie, a następnie chcę zapisać obraz na kartę SD iw końcu próbuję zmienić rozmiar istniejącego obrazu (a następnie nadpisuję go starym).

Mój kod działa poprawnie prawie na wszystkich urządzeniach, ale w obliczu tego problemu tylko na urządzeniach Samsung.

Kiedy jestem przechwytywania obrazu nie jestem w stanie przechowywać obraz do SDCard

Logcat:

12-05 18:23:15.407: E/AndroidRuntime(2378): FATAL EXCEPTION: main 
12-05 18:23:15.407: E/AndroidRuntime(2378): java.lang.NullPointerException 
12-05 18:23:15.407: E/AndroidRuntime(2378):  at android.graphics.Bitmap.createScaledBitmap(Bitmap.java:461) 
12-05 18:23:15.407: E/AndroidRuntime(2378):  at com.example.kdh.TakePhotoActivity$1.onPictureTaken(TakePhotoActivity.java:325) 
12-05 18:23:15.407: E/AndroidRuntime(2378):  at android.hardware.Camera$EventHandler.handleMessage(Camera.java:789) 
12-05 18:23:15.407: E/AndroidRuntime(2378):  at android.os.Handler.dispatchMessage(Handler.java:99) 
12-05 18:23:15.407: E/AndroidRuntime(2378):  at android.os.Looper.loop(Looper.java:137) 
12-05 18:23:15.407: E/AndroidRuntime(2378):  at android.app.ActivityThread.main(ActivityThread.java:4921) 
12-05 18:23:15.407: E/AndroidRuntime(2378):  at java.lang.reflect.Method.invokeNative(Native Method) 
12-05 18:23:15.407: E/AndroidRuntime(2378):  at java.lang.reflect.Method.invoke(Method.java:511) 
12-05 18:23:15.407: E/AndroidRuntime(2378):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1036) 
12-05 18:23:15.407: E/AndroidRuntime(2378):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:803) 
12-05 18:23:15.407: E/AndroidRuntime(2378):  at dalvik.system.NativeStart.main(Native Method) 

Kod:

private void createCamera() { 
       // Create an instance of Camera 
       mCamera = getCameraInstance(); 

       // Setting the right parameters in the camera 
       Camera.Parameters params = mCamera.getParameters(); 

       List<Size> allSizes = params.getSupportedPictureSizes(); 
       Camera.Size size = allSizes.get(0); // get top size 
       for (int i = 0; i < allSizes.size(); i++) { 
        if (allSizes.get(i).width > size.width) 
         size = allSizes.get(i); 
       } 
       //set max Picture Size 
       params.setPictureSize(size.width, size.height); 
       params.setPictureFormat(PixelFormat.JPEG); 
       params.setJpegQuality(85); 
       mCamera.setParameters(params); 

       // Create our Preview view and set it as the content of our activity. 
       mPreview = new CameraPreview(TakePhotoActivity.this, mCamera); 
       FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview); 

       // Calculating the width of the preview so it is proportional. 
       float widthFloat = (float) (deviceHeight) * 4/3; 
       int width = Math.round(widthFloat); 

       // Resizing the LinearLayout so we can make a proportional preview. This 
       // approach is not 100% perfect because on devices with a really small 
       // screen the the image will still be distorted - there is place for 
       // improvment. 
       RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(width, deviceHeight); 
       preview.setLayoutParams(layoutParams); 

       // Adding the camera preview after the FrameLayout and before the button 
       // as a separated element. 
       preview.addView(mPreview, 0); 
      } 

      @Override 
      protected void onResume() { 
       super.onResume(); 

       // Test if there is a camera on the device and if the SD card is 
       // mounted. 
       if (!checkCameraHardware(this)) { 
        finish(); 
       } else if (!checkSDCard()) {      
        finish(); 
       } 

       // Creating the camera 
       createCamera(); 

       // Register this class as a listener for the accelerometer sensor 
       sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL); 
      } 

      @Override 
      protected void onPause() { 
       super.onPause(); 
       // release the camera immediately on pause event 
       releaseCamera(); 

       // removing the inserted view - so when we come back to the app we 
       // won't have the views on top of each other. 

       preview.removeViewAt(0); 
      } 

      private void releaseCamera() { 
       if (mCamera != null) { 
        mCamera.stopPreview(); 
        mCamera.setPreviewCallback(null); 
        mCamera.release(); // release the camera for other applications 
        mCamera = null; 
       } 
      } 

      /** Check if this device has a camera */ 
      private boolean checkCameraHardware(Context context) { 
       if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)) { 
        // this device has a camera 
        return true; 
       } else { 
        // no camera on this device 
        return false; 
       } 
      } 

      private boolean checkSDCard() { 
       boolean state = false; 

       String sd = Environment.getExternalStorageState(); 
       if (Environment.MEDIA_MOUNTED.equals(sd)) { 
        state = true; 
       } 

       return state; 
      } 

      /** 
      * A safe way to get an instance of the Camera object. 
      */ 
      public static Camera getCameraInstance() { 
       Camera c = null; 
       try { 
        // attempt to get a Camera instance 
        c = Camera.open(); 
       } catch (Exception e) { 
        // Camera is not available (in use or does not exist) 
       } 

       // returns null if camera is unavailable 
       return c; 
      } 

      private PictureCallback mPicture = new PictureCallback() { 

       public void onPictureTaken(byte[] data, Camera camera) { 

        // Replacing the button after a photho was taken. 
        linearLayout1.setVisibility(View.GONE); 
        linearLayout2.setVisibility(View.VISIBLE); 

        File directory = new File(Environment.getExternalStoragePublicDirectory 
          (Environment.DIRECTORY_PICTURES) 
           +"/Data/" + stringFolderName);     

        fileName = String.format("%d.jpg", System.currentTimeMillis()); 
        File outFile = new File(directory, fileName); 

        try { 
         FileOutputStream purge = new FileOutputStream(outFile); 
         purge.write(data); 
         purge.close();      
        } catch (FileNotFoundException e) { 
         Log.d("DG_DEBUG", "File not found: " + e.getMessage()); 
        } catch (IOException e) { 
         Log.d("DG_DEBUG", "Error accessing file: " + e.getMessage()); 
        } 

        String cPath = Environment.getExternalStoragePublicDirectory 
          (Environment.DIRECTORY_PICTURES) 
          +"/Data/" + stringFolderName + "/"+ fileName; 

        Bitmap bMap= BitmapFactory.decodeFile(cPath); 
        Bitmap out = Bitmap.createScaledBitmap(bMap, 1024, 768, true); 
        //Bitmap adjustedBitmap = Bitmap.createBitmap(out, 0, 0, 1024, 768, matrix, true); 
        Log.d("image-name:-", fileName); 
        File resizedFile = new File(directory, fileName); 

        OutputStream fOut=null; 
        try { 
         fOut = new BufferedOutputStream(new FileOutputStream(resizedFile)); 
         out.compress(Bitmap.CompressFormat.JPEG, 85, fOut); 
         fOut.flush(); 
         fOut.close(); 
         bMap.recycle(); 
         out.recycle(); 

        } catch (Exception e) { // TODO 

        } 


        // Adding Exif data for the orientation. For some strange reason the 
        // ExifInterface class takes a string instead of a file. 
        try { 
         exif = new ExifInterface(directory + "/"+fileName); 
         exif.setAttribute(ExifInterface.TAG_ORIENTATION, "" + orientation); 
         exif.saveAttributes(); 
        } catch (IOException e) { 
         e.printStackTrace(); 
        } 

       } 
      }; 
+1

check starannie plikami że obrazy to czy nie – Hits

+0

@ Hitesh542 tak jak napisałem, nie dostaję obrazu na kartę SD podczas przechwytywania, tylko w przypadku urządzeń Samsung – Sophie

Odpowiedz

6

Gdy dane nie dose created.You nie można użyć bitmapy.

Oznacza to, że trochę czasu potrzebę stworzenia image.so bitmapcreate zwróci null.

myślę PictureCallback przebiega jak nić

Aby rozwiązać ten problem. zmienić kod

Bitmap bMap= BitmapFactory.decodeFile(cPath); 
    Bitmap out = Bitmap.createScaledBitmap(bMap, 1024, 768, true); 

do

Bitmap bMap = BitmapFactory.decodeByteArray(data, 0,.length); 
    Bitmap out = Bitmap.createScaledBitmap(bMap, 1024, 768, true); 

że kod konwersji bajt [] do bitmapy (patrz dane w picturecallback);

Odniesienie kamera API: Camera API tutorials

7

Spróbuj ten kod i spróbuj zapisać zdjęcie lub wideo w tle wątku zamiast UI

private PictureCallback mPicture = new PictureCallback() { 
      @Override 
      public void onPictureTaken(final byte[] data, Camera camera) { 
       final File pictureFile = getOutputMediaFile(); 
       if (pictureFile == null) { 
        return; 
       } 

       Thread thread = new Thread() { 
        @Override 
        public void run() { 
         try { 
          FileOutputStream fos = new FileOutputStream(pictureFile); 
          fos.write(data); 
          fos.close(); 
         } catch (Exception e) { 
          e.printStackTrace(); 
         } 
        } 
       }; 

       thread.start(); 


      } 
     }; 


     private File getOutputMediaFile() { 
      File mediaStorageDir = new File(
        Environment.getExternalStorageDirectory(), 
        "/Images"); 
      if (!mediaStorageDir.exists()) { 
       if (!mediaStorageDir.mkdirs()) { 
        Log.d("Camera", "failed to create directory"); 
        return null; 
       } 
      } 
      // Create a media file name 
      String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss") 
        .format(new Date()); 
      File mediaFile; 
      String image_path = mediaStorageDir.getPath() + File.separator 
        + "IMG_" + timeStamp + ".jpg"; 
      mediaFile = new File(image_path); 
      return mediaFile; 
     } 
Powiązane problemy