2012-03-07 102 views
2

我正在嘗試Android上的openCV示例。當我試圖挽救使用下面的代碼每一個線程一個bmp文件到SD卡我:從線程保存一個BMP圖像到SD卡

String filePath = "/sdcard"; // some times it may be only /sdcard not /mnt/sdcard 
     filePath += "newFileName.jpg"; 
     try { 
      bmp.compress(Bitmap.CompressFormat.JPEG, 100, new FileOutputStream(new File(filePath))); 
     } catch (FileNotFoundException e) { 
        // TODO Auto-generated catch block 
     e.printStackTrace(); 
     Log.i(TAG, "IOException Occurred!!!"); 
     } 

日誌總是顯示了「發生IOException異常」,沒有文件已保存在SD卡。

完整的類代碼如下

public abstract class SampleCvViewBase extends SurfaceView implements SurfaceHolder.Callback, Runnable { 
private static final String TAG = "Sample::SurfaceView"; 

private SurfaceHolder  mHolder; 
private VideoCapture  mCamera; 
private FpsMeter   mFps; 

public SampleCvViewBase(Context context) { 
    super(context); 
    mHolder = getHolder(); 
    mHolder.addCallback(this); 
    mFps = new FpsMeter(); 
    Log.i(TAG, "Instantiated new " + this.getClass()); 
} 

public void surfaceChanged(SurfaceHolder _holder, int format, int width, int height) {//called immediately after the structural change of surface 
    Log.i(TAG, "surfaceCreated"); 
    synchronized (this) { 
     if (mCamera != null && mCamera.isOpened()) { 
      Log.i(TAG, "before mCamera.getSupportedPreviewSizes()"); 
      List<Size> sizes = mCamera.getSupportedPreviewSizes(); 
      Log.i(TAG, "after mCamera.getSupportedPreviewSizes()"); 
      int mFrameWidth = width; 
      int mFrameHeight = height; 

      // selecting optimal camera preview size 
      { 
       double minDiff = Double.MAX_VALUE; 
       for (Size size : sizes) { 
        if (Math.abs(size.height - height) < minDiff) { 
         mFrameWidth = (int) size.width; 
         mFrameHeight = (int) size.height; 
         minDiff = Math.abs(size.height - height); 
        } 
       } 
      } 

      mCamera.set(Highgui.CV_CAP_PROP_FRAME_WIDTH, mFrameWidth); 
      mCamera.set(Highgui.CV_CAP_PROP_FRAME_HEIGHT, mFrameHeight); 
     } 
    } 
} 

public void surfaceCreated(SurfaceHolder holder) { 
    Log.i(TAG, "surfaceCreated"); 
    mCamera = new VideoCapture(Highgui.CV_CAP_ANDROID); 
    if (mCamera.isOpened()) { 
     (new Thread(this)).start();  //new thread 
    } else { 
     mCamera.release(); 
     mCamera = null; 
     Log.e(TAG, "Failed to open native camera"); 
    } 
} 

public void surfaceDestroyed(SurfaceHolder holder) { 
    Log.i(TAG, "surfaceDestroyed"); 
    if (mCamera != null) { 
     synchronized (this) { 
      mCamera.release();      
      mCamera = null; 
     } 
    } 
} 

protected abstract Bitmap processFrame(VideoCapture capture) throws IOException; 

public void run() { 
    Log.i(TAG, "Starting processing thread");  //send out log notice 
    mFps.init();        //instance of Fps meter  

    while (true) { 
     Bitmap bmp = null; 

     synchronized (this) { 
      if (mCamera == null)     //instance of video capture 
       break; 

      if (!mCamera.grab()) { 
       Log.e(TAG, "mCamera.grab() failed"); 
       break; 
      } 

      try { 
       bmp = processFrame(mCamera); 
      } catch (IOException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 

      mFps.measure(); 
     } 

     if (bmp != null) { 
      Canvas canvas = mHolder.lockCanvas(); 
      if (canvas != null) { 
       canvas.drawBitmap(bmp, (canvas.getWidth() - bmp.getWidth())/2, (canvas.getHeight() - bmp.getHeight())/2, null); 
       mFps.draw(canvas, (canvas.getWidth() - bmp.getWidth())/2, 0); 
       mHolder.unlockCanvasAndPost(canvas); 
      } 
      String filePath = "/sdcard"; // some times it may be only /sdcard not /mnt/sdcard 
      filePath += "newFileName.jpg"; 
      try { 
       bmp.compress(Bitmap.CompressFormat.JPEG, 100, new FileOutputStream(new File(filePath))); 
      } catch (FileNotFoundException e) { 
         // TODO Auto-generated catch block 
      e.printStackTrace(); 
      Log.i(TAG, "IOExcpetion Occurred!!!"); 
      } 
     } 

這裏是我有在DDMS:

03-07 08:58:11.639: W/TextLayoutCache(986): computeValuesWithHarfbuzz -- need to force to single run 
03-07 08:58:11.709: W/System.err(986): java.io.FileNotFoundException: /sdcardnewFileName.jpg: open failed: EROFS (Read-only file system) 
03-07 08:58:11.769: W/System.err(986): at libcore.io.IoBridge.open(IoBridge.java:406) 
03-07 08:58:11.769: W/System.err(986): at java.io.FileOutputStream.<init>(FileOutputStream.java:88) 
03-07 08:58:11.809: W/System.err(986): at java.io.FileOutputStream.<init>(FileOutputStream.java:73) 
03-07 08:58:11.829: W/System.err(986): at org.opencv.samples.fd.SampleCvViewBase.run(SampleCvViewBase.java:125) 
03-07 08:58:11.829: W/System.err(986): at org.opencv.samples.fd.FdView.run(FdView.java:107) 
03-07 08:58:11.829: W/System.err(986): at java.lang.Thread.run(Thread.java:856) 
03-07 08:58:11.829: W/System.err(986): Caused by: libcore.io.ErrnoException: open failed: EROFS (Read-only file system) 
03-07 08:58:11.859: W/System.err(986): at libcore.io.Posix.open(Native Method) 
03-07 08:58:11.859: W/System.err(986): at libcore.io.BlockGuardOs.open(BlockGuardOs.java:98) 
03-07 08:58:11.889: W/System.err(986): at libcore.io.IoBridge.open(IoBridge.java:390) 
03-07 08:58:11.889: W/System.err(986): ... 5 more 

03-07 08:58:11.919: I/Sample::SurfaceView(986): IOExcpetion Occurred!!! 

03-07 08:58:12.489: D/dalvikvm(986): GC_FOR_ALLOC freed 1209K, 14% free 9902K/11399K, paused 29ms 
03-07 08:58:12.489: I/dalvikvm-heap(986): Grow heap (frag case) to 10.925MB for 1228816-byte allocation 
03-07 08:58:12.619: D/dalvikvm(986): GC_CONCURRENT freed <1K, 3% free 11102K/11399K, paused 3ms+45ms 

我想盡快救一個BMP圖像的檢測已經完成一旦。任何人都可以幫助我嗎?謝謝

回答

4

您正試圖寫入文件系統根目錄,因爲您在文件路徑中錯過了正斜槓:您使用/sdcardnewFileName.jpg而不是/sdcard/newFileName.jpg。 但你沒有寫入權限,所以你會得到一個異常。

另外:請不要像這樣硬編碼到SD卡的路徑。請使用Environment.getExternalStorageDirectory()。有些設備將卡安裝在不同的路徑上,或者使用閃存。此方法始終返回正確的路徑。如果你不這樣做,你將在多個設備上使用你的應用程序時遇到問題。