2014-01-14 123 views
1

我使用相机API拍照我必须根据我的图像视图大小打开不同大小的相机。我正在按照我们在名为“ApiDemo”的Android sdk/sample/adroid-18中获得的示例项目进行操作,但我已更改的内容未在setcontentview上设置相机。我已经在Frame Layout上设置了相机。起初我的相机预览被弄糊了,所以我得到了相机OptimalPreviewSize,并将FrameLayout参数的宽度和高度设置为wrap-content.Now相机预览比ImageView小(我想要的大小)。如果我将FrameLayout参数的大小设置为match-parent,那么相机View就是stretch.How来解决这个问题。中心裁剪图像在适当的大小设置ImageView

找到此链接更多规格。 Android camera preview look strange

UPDATE

我的相机预览大小是好的,现在我使用的布局方法的想法是我有更大的布局,然后我的ImageView,现在相机预览看起来很不错。 现在我面临的问题是设置合适的大小的图像,我必须将裁切和缩放中心放在同一大小中,就像我的ImageView.This图片我通过TakePicture方法获取并保存在SD卡中。

为了这个,我用这个方法: -

public Bitmap scaleCenterCrop(Bitmap source, int newHeight, int newWidth) { 
    int sourceWidth = source.getWidth(); 
    int sourceHeight = source.getHeight(); 

    // Compute the scaling factors to fit the new height and width, respectively. 
    // To cover the final image, the final scaling will be the bigger 
    // of these two. 
    float xScale = (float) newWidth/sourceWidth; 
    float yScale = (float) newHeight/sourceHeight; 
    float scale = Math.max(xScale, yScale); 

    // Now get the size of the source bitmap when scaled 
    float scaledWidth = scale * sourceWidth; 
    float scaledHeight = scale * sourceHeight; 

    // Let's find out the upper left coordinates if the scaled bitmap 
    // should be centered in the new size give by the parameters 
    float left = (newWidth - scaledWidth)/2; 
    float top = (newHeight - scaledHeight)/2; 

     // The target rectangle for the new, scaled version of the source bitmap will now 
     // be 
     RectF targetRect = new RectF(left+50, top, left + scaledWidth, top + scaledHeight+50); 
//  RectF targetRect = new RectF(0, 0, newWidth, newHeight/2); 
     // Finally, we create a new bitmap of the specified size and draw our new, 
     // scaled bitmap onto it. 
     Bitmap dest = Bitmap.createBitmap(newWidth, newHeight, source.getConfig()); 
     Canvas canvas = new Canvas(dest); 
     canvas.drawBitmap(source, null, targetRect, null); 

     return dest; 
} 

但结果图像质量不good.Height角从顶部和底部,结果图像质量切割不good.Pixels被拉伸。

不要告诉我使用scaleType = Center_crop我不能在我的情况下使用它,并且不希望向用户显示裁剪帧,这个全部过程不应该显示在UI上。

UPDATE

我从中心和规模,根据我的ImageView大小

Bitmap dstBmp = ThumbnailUtils.extractThumbnail(source, newWidth, newHeight); 

,但我得到的位图不看同在的FrameLayout显示相机预览用于农作物图像的打击方法。因为相机预览很大。我认为这些代码裁剪了大面积。 我试图减少宽度和改变高度,但没有得到我想要的比例相同的裁剪图像。

一个更多的想法,我有后图片裁剪自动FrameLayout上设置的最后一帧图像。我们可以从框架布局中获得该设置的框架吗?这怎么可能?

这里是像这样的问题How to retrieve the visible part of a SurfaceView in Android做任何一个有解决办法。

我想通过这条线ThumbnailUtils.extractThumbnail(source, newWidth, newHeight);来实现这一点,并通过这条线我得到像图中描述的图像的src。

什么改变这一行恰好?

enter image description here

+0

发布您看到的图像的快照 – Prem

+0

完成!请检查更新后的帖子 –

+0

令人难以置信的简单解决方案:http://stackoverflow.com/a/17733530/294884 – Fattie

回答

0

@Akanksha请使用下面的代码,你只需要通过保存的图像文件的路径,我们的ImageView的HIGHT和宽度。这段代码适合我。


    import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 

public class ImageHandler { 
    /** 
    * Decode and sample down a bitmap from a file to the requested width and 
    * height. 
    * 
    * @param filename 
    *   The full path of the file to decode 
    * @param reqWidth 
    *   The requested width of the resulting bitmap 
    * @param reqHeight 
    *   The requested height of the resulting bitmap 
    * @return A bitmap sampled down from the original with the same aspect 
    *   ratio and dimensions that are equal to or greater than the 
    *   requested width and height 
    */ 


public static Bitmap decodeSampledBitmapFromFile(String filename, 
      int reqWidth, int reqHeight) { 

     // First decode with inJustDecodeBounds=true to check dimensions 
     final BitmapFactory.Options options = new BitmapFactory.Options(); 
     options.inJustDecodeBounds = true; 
     BitmapFactory.decodeFile(filename, options); 

     // Calculate inSampleSize 
     options.inSampleSize = calculateInSampleSize(options, reqWidth, 
       reqHeight); 

     // Decode bitmap with inSampleSize set 
     options.inJustDecodeBounds = false; 
     return BitmapFactory.decodeFile(filename, options); 
    } 



public static int calculateInSampleSize(BitmapFactory.Options options, 
      int reqWidth, int reqHeight) { 
     // Raw height and width of image 
     final int height = options.outHeight; 
     final int width = options.outWidth; 
     int inSampleSize = 1; 

     if (height > reqHeight || width > reqWidth) { 
      if (width > height) { 
       inSampleSize = Math.round((float) height/(float) reqHeight); 
      } else { 
       inSampleSize = Math.round((float) width/(float) reqWidth); 
      } 

      // This offers some additional logic in case the image has a 
      // strange 
      // aspect ratio. For example, a panorama may have a much larger 
      // width than height. In these cases the total pixels might 
      // still 
      // end up being too large to fit comfortably in memory, so we 
      // should 
      // be more aggressive with sample down the image (=larger 
      // inSampleSize). 

      final float totalPixels = width * height; 

      // Anything more than 2x the requested pixels we'll sample down 
      // further. 
      final float totalReqPixelsCap = reqWidth * reqHeight * 2; 

      while (totalPixels/(inSampleSize * inSampleSize) > totalReqPixelsCap) { 
       inSampleSize++; 
      } 
     } 
     return inSampleSize; 
    } 
} 

我叫异步任务里面这个方法,因为它可能需要太多UImemory和时间 这是我如何调用它。


class Asyncing extends AsyncTask { 

     private int reqWidth; 
     private int reqHeight; 
     private ImageView iv; 
     private String fileName; 
     private ProgressDialog pd; 

     public Asyncing(int reqWidth, int reqHeight, ImageView iv, 
       String fileName) { 
      super(); 
      this.reqWidth = reqWidth; 
      this.reqHeight = reqHeight; 
      this.fileName = fileName; 
      this.iv = iv; 
     } 

     @Override 
     protected Bitmap doInBackground(String... params) { 
      return ImageHandler.decodeSampledBitmapFromFile(params[0], 
        reqWidth, reqHeight); 

     } 

     @Override 
     protected void onPostExecute(Bitmap result) { 
      iv.setImageBitmap(result); 
      if (pd.isShowing()) { 
       pd.setMessage(getString(R.string.completed)); 
       pd.dismiss(); 
      } 

      super.onPostExecute(result); 
     } 

     @Override 
     protected void onProgressUpdate(Void... values) { 

      super.onProgressUpdate(values); 
     } 

     @Override 
     protected void onPreExecute() { 
      pd = ProgressDialog.show(CustomerDetailsActivity.this, "", 
        getString(R.string.processing_signature)); 
      super.onPreExecute(); 
     } 

    } 

这就是你需要调用的AsyncTask


signedImagePath = data.getExtras().getString("imagePath"); 

      new Asyncing(signature_img.getWidth(), signature_img.getHeight(), 
        signature_img, "spenTest.png").execute(signedImagePath); 

上面的代码是根据我的要求写的,您可以根据您的修改。

+0

这里signedImagePath是图像文件的路径,spentest.png是图像文件的名称。 –

0

中心裁剪图像可能会帮助你这个。

public Bitmap scaleCenterCrop(Bitmap source, int newHeight, int newWidth) { 
    int sourceWidth = source.getWidth(); 
    int sourceHeight = source.getHeight(); 

    // Compute the scaling factors to fit the new height and width, respectively. 
    // To cover the final image, the final scaling will be the bigger 
    // of these two. 
    float xScale = (float) newWidth/sourceWidth; 
    float yScale = (float) newHeight/sourceHeight; 
    float scale = Math.max(xScale, yScale); 

    // Now get the size of the source bitmap when scaled 
    float scaledWidth = scale * sourceWidth; 
    float scaledHeight = scale * sourceHeight; 

    // Let's find out the upper left coordinates if the scaled bitmap 
    // should be centered in the new size give by the parameters 
    float left = (newWidth - scaledWidth)/2; 
    float top = (newHeight - scaledHeight)/2; 

    // The target rectangle for the new, scaled version of the source bitmap will now 
    // be 
    RectF targetRect = new RectF(left, top, left + scaledWidth, top + scaledHeight); 

    // Finally, we create a new bitmap of the specified size and draw our new, 
    // scaled bitmap onto it. 
    Bitmap dest = Bitmap.createBitmap(newWidth, newHeight, source.getConfig()); 
    Canvas canvas = new Canvas(dest); 
    canvas.drawBitmap(source, null, targetRect, null); 

    return dest; 
}