当前位置: 首页 > 知识库问答 >
问题:

Android-缩放、旋转位图并将其保存到SD卡,而不会丢失质量

刘兴朝
2023-03-14

我正在做一个应用程序,用相机拍照,然后旋转和缩放。我需要旋转图像,因为相机返回错误的旋转图像,我需要缩放它以减小其大小。我首先将相机返回的原始图像保存在临时目录中,然后读取并进行修改,将新图像保存到新文件中。我尝试使用矩阵来旋转和缩放图片,但它失去了质量。然后我试着先用位图来缩放它。创建缩放位图,然后使用矩阵旋转,但结果比仅使用矩阵的结果更糟糕。然后我尝试先旋转它,然后使用“始终位图”调整大小。创建缩放位图。图像不会丢失质量,但在旋转后,当我缩放图像时,图像会被拉伸,宽度和高度会反转。还尝试根据所做的旋转反转高度和宽度,但再次失去质量。这是我写的最后一段代码:

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中,它不会丢失质量,只是当我将其保存到文件时会丢失质量。

共有3个答案

艾星河
2023-03-14

不要让新位图只是覆盖

int角=0; int值角=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");
            }

        }
缪嘉志
2023-03-14

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

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;
}
鲜于浩淼
2023-03-14

解决了的!我使用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);
 类似资料:
  • 现在我有一个打开手机摄像头应用程序的意图,允许用户拍照,然后带着新图像回到我的应用程序。有了这个,它返回一个位图。为了获得图片的Uri,以便我可以将ImageView设置为它,我相信我必须先将其保存到存储。唯一的问题是当我的应用程序打开它时,图像质量非常差。在我必须压缩的部分,我保持了100的质量,所以我不确定我做错了什么。 以下是我如何启动照相机的意图: 以下是我如何处理它: 对于switchT

  • 目前,我的(使用的是Stackoverflow,我自己没有完整地编写)代码如下所示: 我得到错误:“打开失败;EACCES(权限被拒绝)”。 我的舱单是这样的:

  • 当我运行progressdialog出现在屏幕上时,它突然停止运行,并发出通知“应用程序停止了,再试一次”,然后我在android manitor上重复了这个错误,当然我首先要做的是:

  • 问题内容: 我尝试使用此代码下载图像并将其保存在以下行中: 我在emulator.my应用程序上尝试了此操作,但出现异常,没有权限保存到此路径: 我也添加了这一行: 这是代码: 问题答案:

  • 我一直在寻找保存音频到SdCard。 我还试图保存以下内容: 在这两种情况下,它都起作用,但会保存到内部存储中。从不使用SD卡 我使用getExternalFilesDirs()来创建。但如果用户卸载应用程序,则会丢失文件。 我不想那样。 如何将音频保存在SD卡公用文件夹中或创建新文件夹。 任何时候它都会创建到内部存储中。 有什么解决办法吗??? 我尝试了这个,我可以在SD卡中创建一个文档。还有一

  • 我在Android上工作。我需要保存一个没有质量损失的位图。 我使用位图的方法进行了尝试,将质量设置为100。这对我不起作用,位图失去了太多的质量。我已经测试了JPEG和PNG格式。 我已经测试过将位图复制到,然后提取,并使用保存它。在这种情况下,我无法显示用这种方式保存的图像,我只看到一个空白页。 我的问题是,有没有办法在不压缩的情况下将位图保存在SD卡中? 编辑:这里我的代码的一部分 我检测到