2015-02-25 2 views
0

Я хочу сделать приложение, которое снимает изображение с камеры устройства, сохраняет изображение во внутренней памяти и затем отображает это изображение в следующем действии. Предварительный просмотр работает отлично, но когда я нажимаю кнопку Capture, приложение переходит к следующему действию и отображает только пустой белый экран. Может быть, я не пишу или не читаю файл правильно?Приложение для Android-камеры неправильно отображает изображение

Вот Основная деятельность:

public class MainActivity extends ActionBarActivity { 
public final static String EXTRA_MESSAGE = "File_name"; 
private Camera mCamera; 
@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    // Create an instance of Camera 
    mCamera = getCameraInstance(); 

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

    // Add a listener to the Capture button 
    Button captureButton = (Button) findViewById(R.id.button_capture); 
    captureButton.setOnClickListener(new View.OnClickListener() { 
     @Override 
       public void onClick(View v) { 
       // get an image from the camera 
        mCamera.takePicture(null, null, mPicture); 
         } 
       } 
    ); 

} 

////////////////////// 
public void sendInfo(String pathway) { 
    Intent intent = new Intent(this, show_image.class); 
    intent.putExtra(EXTRA_MESSAGE,pathway); 
    startActivity(intent); 
} 
///////////////// 
private Camera.PictureCallback mPicture = new Camera.PictureCallback() { 

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

     Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length); 

     ContextWrapper cw = new ContextWrapper(getApplicationContext()); 
     // path to /data/data/yourapp/app_data/imageDir 
     File directory = cw.getDir("imageDir", Context.MODE_PRIVATE); 
     // Create imageDir 
     File mypath=new File(directory,"pic.jpg"); 
     FileOutputStream fos = null; 

     if (directory == null){ 
      Log.d("Logtag", "Error creating media file, check storage permissions: "); 
      return; 
     } 

     try { 
      fos = new FileOutputStream(mypath); 
      bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos); 
      fos.close(); 
      String path = directory.getAbsolutePath(); 
      sendInfo(path); 
     } catch (FileNotFoundException e) { 
      Log.d("Logtag", "File not found: " + e.getMessage()); 
     } catch (IOException e) { 
      Log.d("Logtag", "Error accessing file: " + e.getMessage()); 
     } 
    } 
}; 

@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    // Inflate the menu; this adds items to the action bar if it is present. 
    getMenuInflater().inflate(R.menu.menu_main, 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); 
} 

/** 
* A safe way to get an instance of the Camera object. 
*/ 
public Camera getCameraInstance() { 
    Camera c = null; 
    try { 
     c = Camera.open(); // attempt to get a Camera instance 
    } catch (Exception e) { 
     // Camera is not available (in use or does not exist) 
     Toast.makeText(getApplicationContext(), "Camera is not available (in use or does not exist)", 
       Toast.LENGTH_LONG).show(); 
    } 
    return c; // returns null if camera is unavailable 
} 
} 

Вот вторая деятельность, которая, как предполагается, чтобы отобразить изображение, которое было только что отснятый:

public class show_image extends ActionBarActivity { 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    Intent intent = getIntent(); 
    String path = intent.getStringExtra(MainActivity.EXTRA_MESSAGE); 

    try { 
     File f = new File(path, "pic.jpg"); 
     Bitmap b = BitmapFactory.decodeStream(new FileInputStream(f)); 
     ImageView img= new ImageView(this); 
     img.setImageBitmap(b); 
    } 
    catch (FileNotFoundException e) 
    { 
     e.printStackTrace(); 
    } 



} 

public static Bitmap decodeFile(File f, final int maxSize) { 

    Bitmap b = null; 
    // Decode image size 
    BitmapFactory.Options o = new BitmapFactory.Options(); 
    o.inJustDecodeBounds = true; 

    FileInputStream fis = null; 
    try { 
     fis = new FileInputStream(f); 
     BitmapFactory.decodeStream(fis, null, o); 
     fis.close(); 

     int scale = 1; 
     if (o.outHeight > maxSize || o.outWidth > maxSize) { 
      scale = (int) Math.pow(2, (int) Math.round(Math.log(maxSize/(double) Math.max(o.outHeight, o.outWidth))/Math.log(0.5))); 
     } 

     // Decode with inSampleSize 
     BitmapFactory.Options o2 = new BitmapFactory.Options(); 
     o2.inSampleSize = scale; 

     fis = new FileInputStream(f); 
     b = BitmapFactory.decodeStream(fis, null, o2); 

    } catch (Exception e) { 
     Log.e("Logtag", "Error processing bitmap", e); 
    } finally { 
     //FileUtil.closeQuietly(fis); 
    } 

    return b; 
} 




@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); 
} 

}

LogCat от Android Студия:

02-25 12:32:49.389 17041-17041/edu.ramapo.camer I/System.out﹕ debugger has settled (1496) 


02-25 12:32:49.620 17041-17041/edu.ramapo.camer I/dalvikvm﹕ Could not find method android.view.ViewGroup.onNestedScrollAccepted, referenced from method android.support.v7.internal.widget.ActionBarOverlayLayout.onNestedScrollAccepted 


02-25 12:32:49.620 17041-17041/edu.ramapo.camer W/dalvikvm﹕ VFY: unable to resolve virtual method 11360: Landroid/view/ViewGroup;.onNestedScrollAccepted (Landroid/view/View;Landroid/view/View;I)V 

02-25 12:32:49.620 17041-17041/edu.ramapo.camer D/dalvikvm﹕ VFY: replacing opcode 0x6f at 0x0000 

02-25 12:32:49.620 17041-17041/edu.ramapo.camer I/dalvikvm﹕ Could not find method android.view.ViewGroup.onStopNestedScroll, referenced from method android.support.v7.internal.widget.ActionBarOverlayLayout.onStopNestedScroll 

02-25 12:32:49.620 17041-17041/edu.ramapo.camer W/dalvikvm﹕ VFY: unable to resolve virtual method 11366: Landroid/view/ViewGroup;.onStopNestedScroll (Landroid/view/View;)V 

02-25 12:32:49.620 17041-17041/edu.ramapo.camer D/dalvikvm﹕ VFY: replacing opcode 0x6f at 0x0000 

02-25 12:32:49.630 17041-17041/edu.ramapo.camer I/dalvikvm﹕ Could not find method android.support.v7.internal.widget.ActionBarOverlayLayout.stopNestedScroll, referenced from method android.support.v7.internal.widget.ActionBarOverlayLayout.setHideOnContentScrollEnabled 

02-25 12:32:49.630 17041-17041/edu.ramapo.camer W/dalvikvm﹕ VFY: unable to resolve virtual method 9050: Landroid/support/v7/internal/widget/ActionBarOverlayLayout;.stopNestedScroll()V 

02-25 12:32:49.630 17041-17041/edu.ramapo.camer D/dalvikvm﹕ VFY: replacing opcode 0x6e at 0x000e 

02-25 12:32:49.660 17041-17041/edu.ramapo.camer I/dalvikvm﹕ Could not find method android.content.res.TypedArray.getChangingConfigurations, referenced from method 
android.support.v7.internal.widget.TintTypedArray.getChangingConfigurations 

02-25 12:32:49.660 17041-17041/edu.ramapo.camer W/dalvikvm﹕ VFY: unable to resolve virtual method 367: Landroid/content/res/TypedArray;.getChangingConfigurations()I 

02-25 12:32:49.660 17041-17041/edu.ramapo.camer D/dalvikvm﹕ VFY: replacing opcode 0x6e at 0x0002 

02-25 12:32:49.670 17041-17041/edu.ramapo.camer I/dalvikvm﹕ Could not find method android.content.res.TypedArray.getType, referenced from method android.support.v7.internal.widget.TintTypedArray.getType 

02-25 12:32:49.670 17041-17041/edu.ramapo.camer W/dalvikvm﹕ VFY: unable to resolve virtual method 389: Landroid/content/res/TypedArray;.getType (I)I 

02-25 12:32:49.670 17041-17041/edu.ramapo.camer D/dalvikvm﹕ VFY: replacing opcode 0x6e at 0x0002 

02-25 12:32:50.611 17041-17041/edu.ramapo.camer D/libEGL﹕ loaded /system/lib/egl/libEGL_adreno200.so 

02-25 12:32:50.621 17041-17041/edu.ramapo.camer D/libEGL﹕ loaded /system/lib/egl/libGLESv1_CM_adreno200.so 

02-25 12:32:50.621 17041-17041/edu.ramapo.camer D/libEGL﹕ loaded /system/lib/egl/libGLESv2_adreno200.so 

02-25 12:32:50.631 17041-17041/edu.ramapo.camer I/Adreno200-EGL﹕ <qeglDrvAPI_eglInitialize:265>: EGL 1.4 QUALCOMM build: HAREESHG_Nondeterministic_AU+PATCH[ES]_msm8960_JB_1.9.6_MR2_CL3219408_release_ENGG (CL3219408) 
    Build Date: 09/28/13 Sat 
    Local Branch: hhh 
    Remote Branch: quic/jb_1.9.6_1 
    Local Patches: 8d50ec23e42ef52b570aa6ff1650afac0b503d78 CL3219408: Fix in the Glreadpixels for negative offsets and larger dimensions. 
    801859126f6ca69482b39a34ca61447e3f7cded8 rb: fix panel settings to clear undrawn/undefined buffers 
    Reconstruct Branch: LOCAL_PATCH[ES] 

02-25 12:32:50.991 17041-17041/edu.ramapo.camer D/OpenGLRenderer﹕ Enabling debug mode 0 

02-25 12:32:51.552 17041-17041/edu.ramapo.camer I/Choreographer﹕ Skipped 59 frames! The application may be doing too much work on its main thread. 

02-25 12:32:56.037 17041-17047/edu.ramapo.camer D/dalvikvm﹕ Debugger has detached; object registry had 4113 entries 

02-25 12:33:18.651 17041-17041/edu.ramapo.camer D/dalvikvm﹕ GC_FOR_ALLOC freed 694K, 38% free 12155K/19420K, paused 29ms, total 32ms 

02-25 12:33:18.771 17041-17041/edu.ramapo.camer I/dalvikvm-heap﹕ Grow heap (frag case) to 45.705MB for 31961104-byte allocation 

02-25 12:33:24.507 17041-17041/edu.ramapo.camer D/dalvikvm﹕ GC_FOR_ALLOC freed 31627K, 40% free 11825K/19424K, paused 30ms, total 30ms 

02-25 12:33:24.587 17041-17041/edu.ramapo.camer I/dalvikvm-heap﹕ Grow heap (frag case) to 45.382MB for 31961104-byte allocation 
+0

Вы пытались вместо создания растрового изображения и сжатия, чтобы просто написать данные байта? fos = new FileOutputStream (mypath); fos.write (данные); fos.close(); – Raykud

+0

Я думаю, что эта ссылка может помочь вам, поскольку она делает все, что вы хотите :) http://developer.android.com/guide/topics/media/camera.html – Raykud

+0

Я пробовал писать байтовые данные и получать ту же проблему - вторая активность - просто пустой белый экран. – nnnnnnitters

ответ

2

Ну сейчас я сделал копию приложения, которое я послал вам ссылку уже здесь код:

public class GlassARTest extends FragmentActivity { 

    private static final String TAG = "CameraActivity"; 

    public static final int MEDIA_TYPE_IMAGE = 1; 
    private Camera mCamera; 
    private CameraPreview mPreview; 
    private Context mContext; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_test); 

     mContext = this; 

     if(checkCameraHardware(mContext)){ 
      // Create an instance of Camera 
      mCamera = getCameraInstance(); 

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

     // Add a listener to the Capture button 
      Button captureButton = (Button) findViewById(R.id.button_capture); 
      captureButton.setOnClickListener(
       new View.OnClickListener() { 
        @Override 
        public void onClick(View v) { 
         // get an image from the camera 
         mCamera.takePicture(null, null, mPicture); 
        } 
       } 
      ); 
     } 
    } 

    private PictureCallback mPicture = new PictureCallback() { 

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

      new AsyncTask<Void, Void, String>() { 

       @Override 
       protected String doInBackground(Void... params) { 
        File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE); 
        if (pictureFile == null){ 
         Log.d(TAG, "Error creating media file, check storage permissions: "); 
         return null; 
        } 

        try { 
         FileOutputStream fos = new FileOutputStream(pictureFile); 
         fos.write(data); 
         fos.close(); 
         return pictureFile.getPath(); 
        } catch (FileNotFoundException e) { 
         Log.d(TAG, "File not found: " + e.getMessage()); 
         return null; 
        } catch (IOException e) { 
         Log.d(TAG, "Error accessing file: " + e.getMessage()); 
         return null; 
        } 
       } 

       @Override 
       protected void onPostExecute(String result) { 
        super.onPostExecute(result); 
        if(result != null){ 
         Intent intent = new Intent(mContext, ImageDisplayActivity.class); 
         intent.putExtra(ImageDisplayActivity.KEY_PATH, result); 
         startActivity(intent); 
        } 
       } 

      }.execute(); 


     } 
    }; 


    /** A basic Camera preview class */ 
    public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback { 
     private SurfaceHolder mHolder; 
     private Camera mCamera; 

     public CameraPreview(Context context, Camera camera) { 
      super(context); 
      mCamera = camera; 

      // Install a SurfaceHolder.Callback so we get notified when the 
      // underlying surface is created and destroyed. 
      mHolder = getHolder(); 
      mHolder.addCallback(this); 
      // deprecated setting, but required on Android versions prior to 3.0 
      mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 
     } 

     public void surfaceCreated(SurfaceHolder holder) { 
      // The Surface has been created, now tell the camera where to draw the preview. 
      try { 
       mCamera.setPreviewDisplay(holder); 
       mCamera.startPreview(); 
      } catch (IOException e) { 
       Log.d(TAG, "Error setting camera preview: " + e.getMessage()); 
      } 
     } 

     public void surfaceDestroyed(SurfaceHolder holder) { 
      // empty. Take care of releasing the Camera preview in your activity. 
     } 

     public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { 
      // If your preview can change or rotate, take care of those events here. 
      // Make sure to stop the preview before resizing or reformatting it. 

      if (mHolder.getSurface() == null){ 
       // preview surface does not exist 
       return; 
      } 

      // stop preview before making changes 
      try { 
       mCamera.stopPreview(); 
      } catch (Exception e){ 
       // ignore: tried to stop a non-existent preview 
      } 

      // set preview size and make any resize, rotate or 
      // reformatting changes here 

      // start preview with new settings 
      try { 
       mCamera.setPreviewDisplay(mHolder); 
       mCamera.startPreview(); 

      } catch (Exception e){ 
       Log.d(TAG, "Error starting camera preview: " + e.getMessage()); 
      } 
     } 
    } 

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

    /** 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; 
     } 
    } 


    /** Create a File for saving an image or video */ 
    private static File getOutputMediaFile(int type){ 
     // To be safe, you should check that the SDCard is mounted 
     // using Environment.getExternalStorageState() before doing this. 

     File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
        Environment.DIRECTORY_PICTURES), "MyCameraApp"); 
     // This location works best if you want the created images to be shared 
     // between applications and persist after your app has been uninstalled. 

     // Create the storage directory if it does not exist 
     if (! mediaStorageDir.exists()){ 
      if (! mediaStorageDir.mkdirs()){ 
       Log.d("MyCameraApp", "failed to create directory"); 
       return null; 
      } 
     } 

     // Create a media file name 
     String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date()); 
     File mediaFile; 
     if (type == MEDIA_TYPE_IMAGE){ 
      mediaFile = new File(mediaStorageDir.getPath() + File.separator + 
      "IMG_"+ timeStamp + ".jpg"); 
     } else { 
      return null; 
     } 

     return mediaFile; 
    } 

} private SurfaceHolder mHolder; 
    private Camera mCamera; 

    public CameraPreview(Context context, Camera camera) { 
     super(context); 
     mCamera = camera; 

     // Install a SurfaceHolder.Callback so we get notified when the 
     // underlying surface is created and destroyed. 
     mHolder = getHolder(); 
     mHolder.addCallback(this); 
     // deprecated setting, but required on Android versions prior to 3.0 
     mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 
    } 

    public void surfaceCreated(SurfaceHolder holder) { 
     // The Surface has been created, now tell the camera where to draw the preview. 
     try { 
      mCamera.setPreviewDisplay(holder); 
      mCamera.startPreview(); 
     } catch (IOException e) { 
      Log.d(TAG, "Error setting camera preview: " + e.getMessage()); 
     } 
    } 

    public void surfaceDestroyed(SurfaceHolder holder) { 
     // empty. Take care of releasing the Camera preview in your activity. 
    } 

    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { 
     // If your preview can change or rotate, take care of those events here. 
     // Make sure to stop the preview before resizing or reformatting it. 

     if (mHolder.getSurface() == null){ 
      // preview surface does not exist 
      return; 
     } 

     // stop preview before making changes 
     try { 
      mCamera.stopPreview(); 
     } catch (Exception e){ 
      // ignore: tried to stop a non-existent preview 
     } 

     // set preview size and make any resize, rotate or 
     // reformatting changes here 

     // start preview with new settings 
     try { 
      mCamera.setPreviewDisplay(mHolder); 
      mCamera.startPreview(); 

     } catch (Exception e){ 
      Log.d(TAG, "Error starting camera preview: " + e.getMessage()); 
     } 
    } 
} 

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

/** 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; 
    } 
} 


/** Create a File for saving an image or video */ 
private static File getOutputMediaFile(int type){ 
    // To be safe, you should check that the SDCard is mounted 
    // using Environment.getExternalStorageState() before doing this. 

    File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
       Environment.DIRECTORY_PICTURES), "MyCameraApp"); 
    // This location works best if you want the created images to be shared 
    // between applications and persist after your app has been uninstalled. 

    // Create the storage directory if it does not exist 
    if (! mediaStorageDir.exists()){ 
     if (! mediaStorageDir.mkdirs()){ 
      Log.d("MyCameraApp", "failed to create directory"); 
      return null; 
     } 
    } 

    // Create a media file name 
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date()); 
    File mediaFile; 
    if (type == MEDIA_TYPE_IMAGE){ 
     mediaFile = new File(mediaStorageDir.getPath() + File.separator + 
     "IMG_"+ timeStamp + ".jpg"); 
    } else { 
     return null; 
    } 

    return mediaFile; 
} 

} 

и другая активность:

public class ImageDisplayActivity extends FragmentActivity{ 

    public static final String KEY_PATH = "path"; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_image_display); 
     final ImageView imageDisplay = (ImageView)findViewById(R.id.image_displayer); 
     final Bundle extras = getIntent().getExtras(); 
     if(extras != null){ 
      final String path = extras.getString(KEY_PATH); 
      File imgFile = new File(path); 
      Bitmap bitmap = decodeFile(imgFile); 
      imageDisplay.setImageBitmap(bitmap); 
     } 

    } 


    private Bitmap decodeFile(File f){ 
     Bitmap b = null; 
     try { 
      BitmapFactory.Options o = new BitmapFactory.Options(); 
      o.inJustDecodeBounds = true; 

      FileInputStream fis = new FileInputStream(f); 
      BitmapFactory.decodeStream(fis, null, o); 
      fis.close(); 

      int scale = 1; 
      if (o.outHeight > 50 || o.outWidth > 50) { 
       scale = (int)Math.pow(2, (int) Math.round(Math.log(50/(double) Math.max(o.outHeight, o.outWidth))/Math.log(0.5))); 
      } 

      BitmapFactory.Options o2 = new BitmapFactory.Options(); 
      o2.inSampleSize = scale; 
      fis = new FileInputStream(f); 
      b = BitmapFactory.decodeStream(fis, null, o2); 
      fis.close(); 
     } catch (IOException e) { 
     } 
     return b; 
    } 

} 

этот код работал, показывающим пикселизированное изображение что я сделал (что я просто расшифровываю его в низком качестве для целей тестирования). Надеюсь, это поможет вам.

+0

Мне жаль, что вы прислали мне ссылку уже? Вы имеете в виду в моем почтовом ящике? Я не вижу ссылки. – nnnnnnitters

+0

EDIT: О, я вижу, спасибо, я пытался сделать учебник, но у меня проблемы с подключением точек ... Спасибо за вашу помощь. Я сейчас попробую ваш код. – nnnnnnitters

Смежные вопросы