2012-06-16 84 views
4

我用下面的代碼來捕捉圖像。一切工作正常,當我捕捉圖像它有2592x1944大小和圖像捕捉橫向模式。現在我想捕捉大小爲534x534的圖像。我改變了這個參數值params.setPictureSize(534, 534);什麼都不會改變。我怎樣才能做到這一點。提前致謝。如何在android中捕捉固定大小的圖像?

DgCamActivity.java

public class DgCamActivity extends Activity implements SensorEventListener { 
    private Camera mCamera; 
    private CameraPreview mPreview; 
    private SensorManager sensorManager = null; 
    private int orientation; 
    private ExifInterface exif; 
    private int deviceHeight; 
    private Button ibRetake; 
    private Button ibUse; 
    private Button ibCapture; 
    // private FrameLayout flBtnContainer; 
    private File sdRoot; 
    private String dir; 
    private String fileName; 
    // private ImageView rotatingImage; 
    private int degrees = -1; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.test); 

     // Setting all the path for the image 
     sdRoot = Environment.getExternalStorageDirectory(); 
     dir = "/SimpleCamera/"; 

     // Getting all the needed elements from the layout 
     // rotatingImage = (ImageView) findViewById(R.id.imageView1); 
     ibRetake = (Button) findViewById(R.id.ibRetake); 
     ibUse = (Button) findViewById(R.id.ibUse); 
     ibCapture = (Button) findViewById(R.id.ibCapture); 
     // flBtnContainer = (FrameLayout) findViewById(R.id.flBtnContainer); 

     // Getting the sensor service. 
     sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE); 

     // Selecting the resolution of the Android device so we can create a 
     // proportional preview 
     Display display = ((WindowManager) getSystemService(Context.WINDOW_SERVICE)) 
       .getDefaultDisplay(); 
     deviceHeight = display.getHeight(); 

     // Add a listener to the Capture button 
     ibCapture.setOnClickListener(new View.OnClickListener() { 
      public void onClick(View v) { 
       mCamera.takePicture(null, null, mPicture); 
      } 
     }); 

     // Add a listener to the Retake button 
     ibRetake.setOnClickListener(new View.OnClickListener() { 
      public void onClick(View v) { 
       // Deleting the image from the SD card/ 
       File discardedPhoto = new File(sdRoot, dir + fileName); 
       discardedPhoto.delete(); 

       // Restart the camera preview. 
       mCamera.startPreview(); 

       // Reorganize the buttons on the screen 
       // flBtnContainer.setVisibility(LinearLayout.VISIBLE); 
       ibRetake.setVisibility(LinearLayout.GONE); 
       ibUse.setVisibility(LinearLayout.GONE); 
      } 
     }); 

     // Add a listener to the Use button 
     ibUse.setOnClickListener(new View.OnClickListener() { 
      public void onClick(View v) { 
       // Everything is saved so we can quit the app. 
       finish(); 
      } 
     }); 
    } 

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

     // Setting the right parameters in the camera 
     Camera.Parameters params = mCamera.getParameters(); 
     List<Camera.Size> sizes = params.getSupportedPictureSizes(); 
     Log.v("SUPORTED SIZE IS>>>>>.", params.getSupportedPictureSizes() + ""); 
     Log.v("SUPORTED SIZE IS>>>>>.", sizes.size() + ""); 
     params.setPictureSize(1600, 1200); 
     params.setPictureFormat(PixelFormat.JPEG); 
     params.setJpegQuality(100); 
     mCamera.setParameters(params); 

     // Create our Preview view and set it as the content of our activity. 
     mPreview = new CameraPreview(this, mCamera); 
     RelativeLayout preview = (RelativeLayout) 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); 

     RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(
       LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT); 
     preview.setLayoutParams(layoutParams); 
     preview.addView(mPreview, 0); 
    } 

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

     createCamera(); 

     sensorManager.registerListener(this, 
       sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), 
       SensorManager.SENSOR_DELAY_NORMAL); 
    } 

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

     releaseCamera(); 
     RelativeLayout preview = (RelativeLayout) findViewById(R.id.camera_preview); 
     preview.removeViewAt(0); 
    } 

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

    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) { 

      ibRetake.setVisibility(View.VISIBLE); 
      ibUse.setVisibility(View.VISIBLE); 

      // File name of the image that we just took. 
      fileName = "IMG_" 
        + new SimpleDateFormat("yyyyMMdd_HHmmss") 
          .format(new Date()).toString() + ".jpg"; 

      File mkDir = new File(sdRoot, dir); 
      mkDir.mkdirs(); 

      // Main file where to save the data that we recive from the camera 
      File pictureFile = new File(sdRoot, dir + fileName); 

      try { 
       FileOutputStream purge = new FileOutputStream(pictureFile); 
       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()); 
      } 

      try { 
       exif = new ExifInterface("/sdcard/" + dir + fileName); 
       exif.setAttribute(ExifInterface.TAG_ORIENTATION, "" 
         + orientation); 
       exif.saveAttributes(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 

     } 
    }; 

    /** 
    * Putting in place a listener so we can get the sensor data only when 
    * something changes. 
    */ 
    public void onSensorChanged(SensorEvent event) { 
     synchronized (this) { 
      if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) { 
       RotateAnimation animation = null; 
       if (event.values[0] < 4 && event.values[0] > -4) { 
        if (event.values[1] > 0 
          && orientation != ExifInterface.ORIENTATION_ROTATE_90) { 
         // UP 
         orientation = ExifInterface.ORIENTATION_ROTATE_90; 
         animation = getRotateAnimation(270); 
         degrees = 270; 
        } else if (event.values[1] < 0 
          && orientation != ExifInterface.ORIENTATION_ROTATE_270) { 
         // UP SIDE DOWN 
         orientation = ExifInterface.ORIENTATION_ROTATE_270; 
         animation = getRotateAnimation(90); 
         degrees = 90; 
        } 
       } else if (event.values[1] < 4 && event.values[1] > -4) { 
        if (event.values[0] > 0 
          && orientation != ExifInterface.ORIENTATION_NORMAL) { 
         // LEFT 
         orientation = ExifInterface.ORIENTATION_NORMAL; 
         animation = getRotateAnimation(0); 
         degrees = 0; 
        } else if (event.values[0] < 0 
          && orientation != ExifInterface.ORIENTATION_ROTATE_180) { 
         // RIGHT 
         orientation = ExifInterface.ORIENTATION_ROTATE_180; 
         animation = getRotateAnimation(180); 
         degrees = 180; 
        } 
       } 
       if (animation != null) { 
        // rotatingImage.startAnimation(animation); 
       } 
      } 

     } 
    } 

    /** 
    * Calculating the degrees needed to rotate the image imposed on the button 
    * so it is always facing the user in the right direction 
    * 
    * @param toDegrees 
    * @return 
    */ 
    private RotateAnimation getRotateAnimation(float toDegrees) { 
     float compensation = 0; 

     if (Math.abs(degrees - toDegrees) > 180) { 
      compensation = 360; 
     } 

     // When the device is being held on the left side (default position for 
     // a camera) we need to add, not subtract from the toDegrees. 
     if (toDegrees == 0) { 
      compensation = -compensation; 
     } 

     // Creating the animation and the RELATIVE_TO_SELF means that he image 
     // will rotate on it center instead of a corner. 
     RotateAnimation animation = new RotateAnimation(degrees, toDegrees 
       - compensation, Animation.RELATIVE_TO_SELF, 0.5f, 
       Animation.RELATIVE_TO_SELF, 0.5f); 

     // Adding the time needed to rotate the image 
     animation.setDuration(250); 

     // Set the animation to stop after reaching the desired position. With 
     // out this it would return to the original state. 
     animation.setFillAfter(true); 

     return animation; 
    } 

    /** 
    * STUFF THAT WE DON'T NEED BUT MUST BE HEAR FOR THE COMPILER TO BE HAPPY. 
    */ 
    public void onAccuracyChanged(Sensor sensor, int accuracy) { 
    } 
} 

CameraPreview.java

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); 
     mHolder.setSizeFromLayout(); 
     mHolder.setFixedSize(100, 100); 
    } 

    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("DG_DEBUG", "Error setting camera preview: " + e.getMessage()); 
     } 

    } 

    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { 
     // 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 
     } 

     // make any resize, rotate or reformatting changes here 

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

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

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

} 

的test.xml

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" > 

    <RelativeLayout 
     android:id="@+id/camera_preview" 
     android:layout_width="fill_parent" 
     android:layout_height="fill_parent" 
     android:layout_alignParentTop="true" 
     android:layout_centerHorizontal="true" > 
    </RelativeLayout> 

    <RelativeLayout 
     android:id="@+id/relativeLayout1" 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content" 
     android:layout_alignParentBottom="true" 
     android:layout_centerHorizontal="true" 
     android:layout_marginBottom="41dp" > 

     <Button 
      android:id="@+id/ibCapture" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_alignBottom="@+id/relativeLayout1" 
      android:layout_alignLeft="@+id/camera_preview" 
      android:text="Capture" /> 

     <Button 
      android:id="@+id/ibRetake" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_alignParentTop="true" 
      android:layout_marginLeft="36dp" 
      android:layout_toRightOf="@+id/ibCapture" 
      android:text="ReTake" /> 

     <Button 
      android:id="@+id/ibUse" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_alignParentRight="true" 
      android:layout_alignParentTop="true" 
      android:layout_marginRight="38dp" 
      android:text="Save" /> 
    </RelativeLayout> 

</RelativeLayout> 

回答

1

我相信ndroid在拍攝照片時不會允許任意圖像尺寸,因此應使用parameters.getSupportedPictureSizes()方法查詢支持的圖像尺寸。

我懷疑你必須選擇一個足夠大的尺寸來從你想要的534x534補丁中刪除。您可以通過使用BitmapFactory方法來解碼所拍攝的圖片,然後使用bitmap.getPixels()方法來提取所需的補丁大小,或者使用bitmap.createScaledBitmap()來將圖片縮放到所需大小。

當你有正確的大小的位圖後,如果這是最終的格式,你可以使用bitmap.compress()來保存圖像。

相關問題