center Crop Image In proper size to set on ImageView

荒凉一梦 提交于 2020-01-15 18:39:05

问题


I am using camera API to take picture i have to open camera in different sizes according to my Image view size. I am following the sample project which we get inside Android sdk/sample/adroid-18 at the name "ApiDemo" the thing i have changed is not set camera on setcontentview. I have set the camera on Frame Layout. at first my camera preview was starched so i got the camera OptimalPreviewSize and make FrameLayout parameter width and height as wrap-content.Now the camera preview is smaller then ImageView (The size i want). If i make the size of FrameLayout parameter as match-parent then camera View is stretch.How to resolve this issue.

find this link for more specification. Android camera preview look strange

UPDATE

My camera preview size is fine now i use the on Layout method the idea was i have the bigger layout then my ImageView and now camera preview is looking good. Now the Problem I am facing is set the image of proper size for this I have to center crop and scale in same size in like my ImageView.this Image i get by TakePicture method and saved in sdcard.

For this I am using this method:-

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

But the result image quality is not good.Height Corners are cutting from top and bottom, and result image quality is not good.Pixels are stretching.

Don't tell me to use scaleType=Center_crop i can't use it in my case,and don't want to show cropping frame to user,this all process should not show on UI.

UPDATE

I used blow method for crop image from center and scale according to my imageView size

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

But the bitmap i got is not looking same the camera preview shown on FrameLayout. because camera preview is big.I think these code cropped the large area. I tried to reduce the width and change the height but not getting the same cropped image in which ratio i want.

One more idea i have after picture crop a last image frame set automatically on FrameLayout. can we get that set frame from Frame Layout. How is this possible?

Here is question like this How to retrieve the visible part of a SurfaceView in Android do any one have solution.

I want to achieve this by this line ThumbnailUtils.extractThumbnail(source, newWidth, newHeight);and by this line i am getting src like image described in diagram .

What to change in this line exactly ????


回答1:


@Akanksha Please use this below code, you just need to pass the path of the saved image, and the hight and width of our imageview. This code works perfectly for me.


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

I call this method inside async task because it may take too much UImemory and time Here is how I call it.


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

    }

This is how you need to call the asynctask


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

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

above code is written according to my requirements,you modify it according to yours.




回答2:


Center crop an image may be help you this.

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


来源:https://stackoverflow.com/questions/21107208/center-crop-image-in-proper-size-to-set-on-imageview

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!