繁体   English   中英

Android - 缩放,旋转并将位图保存到SD卡而不会降低质量

[英]Android - scale, rotate and save a bitmap to sdcard without losing quality

我正在做一个应用程序,用相机拍照,然后旋转它并缩放它。 我需要旋转图像,因为相机返回错误的旋转图像,我需要缩放它以减小其大小。 我首先在temp目录中保存相机返回的原始图像,然后我读取并进行修改,将新图像保存到新文件中。 我尝试使用矩阵旋转和缩放图片,但它失去了质量。 然后我尝试使用Bitmap.createScaledBitmap首先缩放它,然后用矩阵旋转它,但结果甚至比仅使用矩阵的结果更加丑陋。 然后我尝试先旋转它,然后使用Always Bitmap.createScaledBitmap调整它的大小。 图像不会失去质量,但是在旋转它并且宽度和高度被反转之后,它会被缩放。 试图根据所做的旋转反转高度和宽度,但它再次失去质量。 这是我写的最后一个代码:

in= new FileInputStream(tempDir+"/"+photo1_path);
            out = new FileOutputStream(file+"/picture.png");
            Bitmap src = BitmapFactory.decodeStream(in);
            int iwidth = src.getWidth();
            int iheight = src.getHeight();
            int newWidth = 0;
            int newHeight = 0;

                newWidth = 800;
                newHeight = 600;

              // calculate the scale - in this case = 0.4f
              float scaleWidth = ((float) newWidth) / iwidth;
              float scaleHeight = ((float) newHeight) / iheight;

              // createa matrix for the manipulation
              Matrix matrix = new Matrix();
              // resize the bit map
              //matrix.postScale(scaleWidth, scaleHeight);
              int orientation = getOrientation(MyActivity.this,Uri.parse(tempDir+"/"+photo1_path));
              switch(orientation) {
                case 3:
                    orientation = 180;
                    break;
                case 6:
                    orientation = 90;
                   break;
                case 8:
                    orientation = 270;
                    break;
              }
              int rotate = 0;
              switch(orientation) {
                case 90:
                    rotate=90;
                    break;
                case 180:
                    rotate=180;
                    break;
                case 270:
                    rotate=270;
                    break;

              }
              // rotate the Bitmap
              matrix.postRotate(rotate);

              src =Bitmap.createScaledBitmap(src , newWidth, newHeight, false);
              // recreate the new Bitmap
              Bitmap new_bit = Bitmap.createBitmap(src, 0, 0,
                                src.getWidth(), src.getHeight(), matrix, true);
                      new_bit.compress(Bitmap.CompressFormat.PNG, 100, out);

有什么建议?

编辑 :如果我只旋转或只缩放图像,它不会失去质量。 当我两者都做时,图像会失去质量。 此外,如果我在调整图像大小并将其缩放后将其放入ImageView中,它就不会失去质量,只是当我将其保存到丢失质量的文件时。

解决了! 我使用BitmapFactory inSampleSize选项调整图像大小,图像根本不会丢失质量。 码:

BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();
bmpFactoryOptions.inJustDecodeBounds = true;
Bitmap bm = BitmapFactory.decodeFile(tempDir+"/"+photo1_path , bmpFactoryOptions);


int heightRatio = (int)Math.ceil(bmpFactoryOptions.outHeight/(float)600);
int widthRatio = (int)Math.ceil(bmpFactoryOptions.outWidth/(float)800);

if (heightRatio > 1 || widthRatio > 1)
{
    if (heightRatio > widthRatio){
        bmpFactoryOptions.inSampleSize = heightRatio;
    } else {
        bmpFactoryOptions.inSampleSize = widthRatio; 
    } 
}

bmpFactoryOptions.inJustDecodeBounds = false;
bm = BitmapFactory.decodeFile(tempDir+"/"+photo1_path, bmpFactoryOptions);
//bm.compress(Bitmap.CompressFormat.PNG, 100, out);
/*Bitmap new_bit = Bitmap.createScaledBitmap(src , newWidth, newHeight, true);
            new_bit.compress(Bitmap.CompressFormat.PNG, 100, out);*/


// recreate the new Bitmap
src = Bitmap.createBitmap(bm, 0, 0,bm.getWidth(), bm.getHeight(), matrix, true);


//Bitmap dest = Bitmap.createScaledBitmap(new_bit , newWidth, newHeight, true);
src.compress(Bitmap.CompressFormat.PNG, 100, out);

使用此方法旋转位图...

private Bitmap checkifImageRotated() {
    ExifInterface exif;
    try {
        exif = new ExifInterface(file.getAbsolutePath());
        int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
        int rotate = 0;
        switch (orientation) {
            case ExifInterface.ORIENTATION_ROTATE_270 :
                rotate = -90;
                break;
            case ExifInterface.ORIENTATION_ROTATE_180 :
                rotate = 180;
                break;
            case ExifInterface.ORIENTATION_ROTATE_90 :
                rotate = 90;
                break;
        }
        if (rotate != 0) {
            Bitmap bitmap = BitmapFactory.decodeFile(getTempFile().getPath());
            Matrix matrix = new Matrix();
            matrix.setRotate(rotate);
            Bitmap bmpRotated = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, false);
            recycle(bitmap);
            return bmpRotated;
        }
    }
    catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return null;
}

不要使新位图只是覆盖

int angle = 0; int valueangle = 0; 位图位图;

        @Override
        public void onClick(View v) {

            System.out.println("valueeeeeee  " + angle);
            if (bitmap != null) {

                angle = valueangle + 90;



                Matrix matrix = new Matrix();
                matrix.postRotate(angle);

                bitmap = Bitmap.createBitmap(
                        bitmap , 0, 0,
                        bitmap .getWidth(),
                        bitmap .getHeight(), matrix, true);



                main_img.setImageBitmap(bitmap );

            } else {

                System.out.println(" bitmap is null");
            }

        }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM