【问题标题】:Crop image in Android using perfect aspect ratio在 Android 中使用完美的纵横比裁剪图像
【发布时间】:2016-03-26 07:40:50
【问题描述】:

我一直在开发一个 android 应用程序。我的应用程序中有一个功能需要具有设备屏幕精确尺寸的图像,为此我正在使用此代码,

Intent cropIntent = new Intent("com.android.camera.action.CROP");
cropIntent.setDataAndType(picUri, "image/*");
cropIntent.putExtra("crop", "true");
cropIntent.putExtra("aspectX", 0);
cropIntent.putExtra("aspectY", 0);
cropIntent.putExtra("outputX", width);
cropIntent.putExtra("outputY", height);
cropIntent.putExtra("return-data", true);

但此代码的问题在于,由于纵横比已设置为零,因此在某些设备(如三星)中,裁剪窗口为方形,无法调整。那么如何在 aspectX 和 aspectY 字段中设置纵横比,以便图像裁剪没有问题,

我还编写了一个 java 程序来计算纵横比,但它似乎不适用于所有分辨率。

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;

class AspectRatio
{   public static void main(String args[])
    {   BufferedReader buff=new BufferedReader(new InputStreamReader(System.in));
        int width=0,height=0;
        try
        {   System.out.print("Enter the width of the screen:");
            width=Integer.parseInt(buff.readLine());
            System.out.println("Enter the height of the screen:");
            height=Integer.parseInt(buff.readLine());
        }
        catch(IOException e)
        {   e.printStackTrace();
        }
        int factor=0;
        for(int i=2;i<new AspectRatio().minimum(width,height)/2;i++)
        {   if(width%i==0&&height%1==0)
            {   factor=i;
            }
        }
        System.out.println("The aspect ratio is:"+width/factor+":"+height/factor);
    }

    public int minimum(int a,int b)
    {   return (a<b?a:b);
    }
}

【问题讨论】:

    标签: java android screen screen-resolution aspect-ratio


    【解决方案1】:

    您可以使用下一个 Class 从系统中获取宽度和高度: DisplayMetrics

    查看链接,它还将给出如何使用此类的示例。

    【讨论】:

    • 那么宽高比呢..?
    • 我已经在使用此代码来获取宽度和高度,并且它仅适用于少数设备
    • 首先,如果您想保留图像 AspectRatio,只需使用 AspectRatioImageView 假设您要在 ImageView 中显示此图像.. 并且对于一个大的灵魂,使用系统为您提供的东西,如 DisplayMetric 这里是链接对于 AspectRatioImageView :gist.github.com/JakeWharton/2856179
    【解决方案2】:

    这是我的帮助类,用于以完美的比例减少任何图像,它适用于从相机拍摄的图像和设备上的 img:

     public class ImageUtils {
        private static final String TAG = "ImageUtils";
        private static final float maxHeight = 1280.0f;
        private static final float maxWidth = 1280.0f;
    
        public static byte[] compressImage(String imagePath) {
            Bitmap scaledBitmap = null;
    
    
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inJustDecodeBounds = true;
            Bitmap bmp = BitmapFactory.decodeFile(imagePath, options);
    
            int actualHeight = options.outHeight;
            int actualWidth = options.outWidth;
            float imgRatio = (float) actualWidth / (float) actualHeight;
            float maxRatio = maxWidth / maxHeight;
    
            if (actualHeight > maxHeight || actualWidth > maxWidth) {
                if (imgRatio < maxRatio) {
                    imgRatio = maxHeight / actualHeight;
                    actualWidth = (int) (imgRatio * actualWidth);
                    actualHeight = (int) maxHeight;
                } else if (imgRatio > maxRatio) {
                    imgRatio = maxWidth / actualWidth;
                    actualHeight = (int) (imgRatio * actualHeight);
                    actualWidth = (int) maxWidth;
                } else {
                    actualHeight = (int) maxHeight;
                    actualWidth = (int) maxWidth;
    
                }
            }
    
            options.inSampleSize = ImageUtils.calculateInSampleSize(options, actualWidth, actualHeight);
            options.inJustDecodeBounds = false;
            options.inDither = false;
            options.inPurgeable = true;
            options.inInputShareable = true;
            options.inTempStorage = new byte[16 * 1024];
    
            try {
                bmp = BitmapFactory.decodeFile(imagePath, options);
            } catch (OutOfMemoryError exception) {
                exception.printStackTrace();
    
            }
            try {
                scaledBitmap = Bitmap.createBitmap(actualWidth, actualHeight, Bitmap.Config.ARGB_8888);
            } catch (OutOfMemoryError exception) {
                exception.printStackTrace();
            }
    
            float ratioX = actualWidth / (float) options.outWidth;
            float ratioY = actualHeight / (float) options.outHeight;
            float middleX = actualWidth / 2.0f;
            float middleY = actualHeight / 2.0f;
    
            Matrix scaleMatrix = new Matrix();
            scaleMatrix.setScale(ratioX, ratioY, middleX, middleY);
    
            Canvas canvas = new Canvas(scaledBitmap);
            canvas.setMatrix(scaleMatrix);
            canvas.drawBitmap(bmp, middleX - bmp.getWidth() / 2, middleY - bmp.getHeight() / 2, new Paint(Paint.FILTER_BITMAP_FLAG));
    
            ExifInterface exif;
            try {
                exif = new ExifInterface(imagePath);
                int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 0);
                Matrix matrix = new Matrix();
                if (orientation == 6) {
                    matrix.postRotate(90);
                } else if (orientation == 3) {
                    matrix.postRotate(180);
                } else if (orientation == 8) {
                    matrix.postRotate(270);
                }
                scaledBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0, scaledBitmap.getWidth(), scaledBitmap.getHeight(), matrix, true);
            } catch (IOException e) {
                e.printStackTrace();
            }
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            scaledBitmap.compress(Bitmap.CompressFormat.JPEG, 85, out);
            return out.toByteArray();
        }
        public static boolean compressImage(Bitmap image, FileOutputStream fos){
            Bitmap scaledBitmap = null;
    
            int actualHeight = image.getHeight();
            int actualWidth = image.getWidth();
            float imgRatio = (float) actualWidth / (float) actualHeight;
            float maxRatio = maxWidth / maxHeight;
    
            if (actualHeight > maxHeight || actualWidth > maxWidth) {
                if (imgRatio < maxRatio) {
                    imgRatio = maxHeight / actualHeight;
                    actualWidth = (int) (imgRatio * actualWidth);
                    actualHeight = (int) maxHeight;
                } else if (imgRatio > maxRatio) {
                    imgRatio = maxWidth / actualWidth;
                    actualHeight = (int) (imgRatio * actualHeight);
                    actualWidth = (int) maxWidth;
                } else {
                    actualHeight = (int) maxHeight;
                    actualWidth = (int) maxWidth;
    
                }
            }
    
            Log.d(TAG, "ActualHeight " + actualHeight);
            Log.d(TAG, "ActualHidht " + actualWidth);
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inSampleSize = ImageUtils.calculateInSampleSize(options, actualWidth, actualHeight);
            options.inJustDecodeBounds = false;
            options.inDither = false;
            options.inPurgeable = true;
            options.inInputShareable = true;
            options.inTempStorage = new byte[16 * 1024];
    
            Bitmap bmp = null;
            try {
    //            int bytes = byteSizeOf(image);
    //            //or we can calculate bytes this way. Use a different value than 4 if you don't use 32bit images.
    //            //int bytes = b.getWidth()*b.getHeight()*4;
    //            ByteBuffer buffer = ByteBuffer.allocate(bytes); //Create a new buffer
    //            image.copyPixelsToBuffer(buffer); //Move the byte data to the buffer
    //            byte[] array = buffer.array(); //Get the underlying array containing the data.
    //            bmp = BitmapFactory.decodeByteArray(array, 0, array.length, options);
    
                ByteArrayOutputStream blob = new ByteArrayOutputStream();
                image.compress(Bitmap.CompressFormat.PNG, 0 /*ignored for PNG*/, blob);
                byte[] bitmapdata = blob.toByteArray();
                bmp = BitmapFactory.decodeByteArray(bitmapdata , 0, bitmapdata.length);
            } catch (OutOfMemoryError exception) {
                exception.printStackTrace();
            }
    
            try {
                scaledBitmap = Bitmap.createBitmap(actualWidth, actualHeight, Bitmap.Config.ARGB_8888);
            } catch (OutOfMemoryError exception) {
                exception.printStackTrace();
            }
    
            float ratioX = actualWidth / (float) options.outWidth;
            float ratioY = actualHeight / (float) options.outHeight;
            float middleX = actualWidth / 2.0f;
            float middleY = actualHeight / 2.0f;
    
            Matrix scaleMatrix = new Matrix();
            scaleMatrix.setScale(ratioX, ratioY, middleX, middleY);
    
            Canvas canvas = new Canvas(scaledBitmap);
            canvas.setMatrix(scaleMatrix);
            canvas.drawBitmap(bmp, middleX - bmp.getWidth() / 2, middleY - bmp.getHeight() / 2, new Paint(Paint.FILTER_BITMAP_FLAG));
    
    //        ExifInterface exif;
    //        try {
    ////            exif = new ExifInterface(imagePath);
    ////            int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 0);
    ////            Matrix matrix = new Matrix();
    ////            if (orientation == 6) {
    ////                matrix.postRotate(90);
    ////            } else if (orientation == 3) {
    ////                matrix.postRotate(180);
    ////            } else if (orientation == 8) {
    ////                matrix.postRotate(270);
    ////            }
    //
    //        } catch (IOException e) {
    //            e.printStackTrace();
    //        }
            scaledBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0, scaledBitmap.getWidth(), scaledBitmap.getHeight(), null, true);
            scaledBitmap.compress(Bitmap.CompressFormat.JPEG, 85, fos);
            return true;
        }
        public static void compressImage(String imagePath, FileOutputStream fos) {
            Bitmap scaledBitmap = null;
    
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inJustDecodeBounds = true;
            Bitmap bmp = BitmapFactory.decodeFile(imagePath, options);
    
            int actualHeight = options.outHeight;
            int actualWidth = options.outWidth;
            float imgRatio = (float) actualWidth / (float) actualHeight;
            float maxRatio = maxWidth / maxHeight;
    
            if (actualHeight > maxHeight || actualWidth > maxWidth) {
                if (imgRatio < maxRatio) {
                    imgRatio = maxHeight / actualHeight;
                    actualWidth = (int) (imgRatio * actualWidth);
                    actualHeight = (int) maxHeight;
                } else if (imgRatio > maxRatio) {
                    imgRatio = maxWidth / actualWidth;
                    actualHeight = (int) (imgRatio * actualHeight);
                    actualWidth = (int) maxWidth;
                } else {
                    actualHeight = (int) maxHeight;
                    actualWidth = (int) maxWidth;
    
                }
            }
    
            options.inSampleSize = ImageUtils.calculateInSampleSize(options, actualWidth, actualHeight);
            options.inJustDecodeBounds = false;
            options.inDither = false;
            options.inPurgeable = true;
            options.inInputShareable = true;
            options.inTempStorage = new byte[16 * 1024];
    
            try {
                bmp = BitmapFactory.decodeFile(imagePath, options);
            } catch (OutOfMemoryError exception) {
                exception.printStackTrace();
    
            }
            try {
                scaledBitmap = Bitmap.createBitmap(actualWidth, actualHeight, Bitmap.Config.ARGB_8888);
            } catch (OutOfMemoryError exception) {
                exception.printStackTrace();
            }
    
            float ratioX = actualWidth / (float) options.outWidth;
            float ratioY = actualHeight / (float) options.outHeight;
            float middleX = actualWidth / 2.0f;
            float middleY = actualHeight / 2.0f;
    
            Matrix scaleMatrix = new Matrix();
            scaleMatrix.setScale(ratioX, ratioY, middleX, middleY);
    
            Canvas canvas = new Canvas(scaledBitmap);
            canvas.setMatrix(scaleMatrix);
            canvas.drawBitmap(bmp, middleX - bmp.getWidth() / 2, middleY - bmp.getHeight() / 2, new Paint(Paint.FILTER_BITMAP_FLAG));
    
            ExifInterface exif;
            try {
                exif = new ExifInterface(imagePath);
                int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 0);
                Matrix matrix = new Matrix();
                if (orientation == 6) {
                    matrix.postRotate(90);
                } else if (orientation == 3) {
                    matrix.postRotate(180);
                } else if (orientation == 8) {
                    matrix.postRotate(270);
                }
                scaledBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0, scaledBitmap.getWidth(), scaledBitmap.getHeight(), matrix, true);
            } catch (IOException e) {
                e.printStackTrace();
            }
            //ByteArrayOutputStream out = new ByteArrayOutputStream();
            scaledBitmap.compress(Bitmap.CompressFormat.JPEG, 85, fos);
        }
        public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
            final int height = options.outHeight;
            final int width = options.outWidth;
            int inSampleSize = 1;
    
            if (height > reqHeight || width > reqWidth) {
                final int heightRatio = Math.round((float) height / (float) reqHeight);
                final int widthRatio = Math.round((float) width / (float) reqWidth);
                inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
            }
            final float totalPixels = width * height;
            final float totalReqPixelsCap = reqWidth * reqHeight * 2;
    
            while (totalPixels / (inSampleSize * inSampleSize) > totalReqPixelsCap) {
                inSampleSize++;
            }
    
            return inSampleSize;
        }
        static protected int byteSizeOf(Bitmap data) {
            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB_MR1) {
                return data.getRowBytes() * data.getHeight();
            } else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
                return data.getByteCount();
            } else {
                return data.getAllocationByteCount();
            }
        }
    }
    
    
     /**
     * reduces the size of the image
     * @param image
     * @param maxSize
     * @return
     */
    public Bitmap getResizedBitmap(Bitmap image, int maxSize) {
        int width = image.getWidth();
        int height = image.getHeight();
    
        float bitmapRatio = (float)width / (float) height;
        if (bitmapRatio > 0) {
            width = maxSize;
            height = (int) (width / bitmapRatio);
        } else {
            height = maxSize;
            width = (int) (height * bitmapRatio);
        }
        return Bitmap.createScaledBitmap(image, width, height, true);
    }
    
    private void setVideoViewRatio(VideoView vv, int maxSize, int cWidth, int cHeight){
        int width = cWidth;
        int height = cHeight;
        float ratio = (float)cWidth / (float) height;
        if (ratio > 0) {
            width = maxSize;
            height = (int) (width / ratio);
        } else {
            height = maxSize;
            width = (int) (height * ratio);
        }
        vv.setMinimumWidth(width);
        vv.setMinimumHeight(height);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-18
      • 1970-01-01
      • 1970-01-01
      • 2013-08-31
      • 2012-05-14
      相关资源
      最近更新 更多