center Crop Image In proper size to set on ImageView
我正在使用相机API拍照,我必须根据我的图像视图尺寸打开不同尺寸的相机。我正在跟随我们在Android sdk / sample / adroid-18中进入的示例项目,名称为" ApiDemo ",但我更改的内容未在setcontentview上设置相机。我已将相机设置为"帧布局"。起初我的相机预览是混用的,所以我得到了相机OptimalPreviewSize并将FrameLayout参数的width和height作为wrap-content.Now相机预览比ImageView小(我想要的大小)。如果我将FrameLayout参数的大小设置为Match-parent,则Camera View处于拉伸状态。如何解决此问题。
找到此链接以获取更多规范。 Android相机预览看起来很奇怪
更新
我的相机预览大小很好,现在我使用on Layout方法,这个想法是我的布局比我的ImageView大,现在相机预览看起来也不错。
现在我面临的问题是为此设置了适当大小的图像,我必须像我的ImageView一样将裁切和缩放中心对准相同的大小。我通过TakePicture方法获取并保存在sdcard中的图像。
为此,我正在使用以下方法:-
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | 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; } |
但是结果图像质量不好。高度角从顶部和底部切开,结果图像质量不好。像素在拉伸。
不要告诉我使用scaleType = Center_crop我不能使用它,也不想向用户显示裁剪框,所有这些过程都不应在UI上显示。
更新
我根据我的imageView尺寸从中心和比例使用吹塑方法对作物图像进行了缩放
1 | Bitmap dstBmp = ThumbnailUtils.extractThumbnail(source, newWidth, newHeight); |
但是我得到的位图与FrameLayout上显示的相机预览不一样。因为相机预览很大。我认为这些代码裁剪了很大的区域。
我试图减小宽度并更改高度,但没有得到我想要的比例相同的裁剪图像。
图片裁剪后,我有另一个想法是在FrameLayout上自动设置最后一个图像帧。我们可以从"帧布局"中获取该设置的帧吗?这怎么可能?
这是一个类似的问题,如何在Android中检索SurfaceView的可见部分,任何人都有解决方法。
我想通过此行
此行中到底要更改什么????
集中裁剪图像可能会帮助您。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | 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; } |
@Akanksha请使用以下代码,您只需要传递保存图像的路径以及imageview的高度和宽度。这段代码对我来说是完美的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | 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; } } |
我在异步任务中调用此方法,因为它可能会占用过多的UI内存和时间
这就是我的称呼。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | 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
的方式
1 2 3 4 | signedImagePath = data.getExtras().getString("imagePath"); new Asyncing(signature_img.getWidth(), signature_img.getHeight(), signature_img,"spenTest.png").execute(signedImagePath); |
以上代码是根据我的要求编写的,您可以根据自己的要求进行修改。