Firebase 存储图像被旋转

Posted

技术标签:

【中文标题】Firebase 存储图像被旋转【英文标题】:Firebase Storage image gets rotated 【发布时间】:2018-08-22 23:46:15 【问题描述】:

在我的应用程序中,我提示用户捕获图像。用户的相机活动从按钮单击开始,用户可以选择使用相机来捕捉图像。

此图像保存在用户手机上。然后将图像上传到 firebase 存储,一切正常。一位使用三星 Note 8 的用户的反馈是,当以纵向模式拍摄图像时,他稍后在应用程序中将其以横向模式显示。

我查看了 firebase 存储,发现图像以横向模式保存在存储中,即使用户以纵向模式捕获图像。

我想我必须将元数据传递给以纵向模式捕获图像的 jpeg 文件,以便 firebase 知道它实际上是纵向模式。

这是捕获图像的代码:

private void takePhoto() 
    Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    if (takePictureIntent.resolveActivity(getPackageManager()) != null) 
        File photoFile = null;
        try 


            photoFile = createImageFile();


         catch (IOException ex) 
            // Error occurred while creating the File

        


        if (photoFile != null) 


            imageUri = FileProvider.getUriForFile(this, "com.example.android.fileprovider", photoFile);
            takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
            startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);

        
    

这是 CreateImageFile 方法:

public File createImageFile() throws IOException 
    // Create an image file name
    String timeStamp = new SimpleDateFormat("yyyy.MM.dd_HH:mm:ss").format(new Date());

    String imageFileName = "JPEG_" + timeStamp + "_";
    File storageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
            "MAP_NAME");

    if (!storageDir.exists()) 
    if (!storageDir.mkdir()) 
        return null;
    



    File image = File.createTempFile(
            imageFileName,
            ".jpg",
            storageDir
    );


    // Save a file: path for use with ACTION_VIEW intents
    mCurrentPhotoPath = image.getAbsolutePath();
    return image;



最后是上传图片到firebase存储的代码:

private StorageTask mUploadTask;

private void uploadFile() 
    final String dateStamp = new SimpleDateFormat("dd MM").format(new Date());
    final String timeStamp = new SimpleDateFormat("HH:mm:ss").format(new Date());

    if (mImageUri != null) 
        StorageReference fileReference = mStorageRef.child(System.currentTimeMillis() + "");

        mUploadTask = fileReference.putFile(mImageUri)
                .addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() 
                    @Override
                    public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) 

                        Handler handler = new Handler();
                        handler.postDelayed(new Runnable() 
                            @Override
                            public void run() 
                                mProgressBar.setProgress(0);
                            
                        , 500);

稍后显示来自 firebase 存储的图像时,我使用 picasso 库,如下所示:

Picasso.with(mContext)
            .load(uploadCurrent.getImageUrl())
            .placeholder(R.mipmap.ic_launcher)
            .centerCrop()
            .fit()
            .into(holder.imageView);

是否可以在毕加索的帮助下检测到旋转?

【问题讨论】:

Android : How to detect the image orientation (portrait or landscape) picked from gallery while setting on an imageview?的可能重复 我稍后在我的代码中将图像从 firebase 存储检索到 recyclerview - cardview。如何检测图像在 firebase 存储中旋转时是否旋转? 在上传到 Firebase 存储之前,您需要实现 Exif Interface 并更改从相机/图库拍摄的图像的方向,请遵循此 answer 您在将图像上传到 Firebase 存储时确定并更正图像的方向。它必须以与上传时相同的方式返回。 我已经阅读过了,但是否有可能至少得到一个提示,从哪里开始在我的代码中实现 EXIF?我想补充一点,我正在尝试使用全尺寸图像,而不是位图。 【参考方案1】:

我在使用google example 拍照时遇到了同样的问题,问题是,当我通过Glide 设置 imageView 的路径时捕获后,它以正确的方向显示,但上传后它在 Firebase 存储中旋转。

所以在onActivityResult我设置imageView的路径,然后得到Bitmap 从路径,旋转它并将其保存回路径,然后将文件上传到 Firebase 存储。

private Disposable disposable;

disposable = Completable
     .fromAction(this::handleImageOrientation)
     .subscribeOn(Schedulers.io())
     .observeOn(AndroidSchedulers.mainThread())
     .subscribe(this::uploadProfilePic);

@Override
public void onDestroy() 
    super.onDestroy();
    if (disposable != null) 
        disposable.dispose();
        disposable = null;
    

如果你没有使用RxRava

new Thread() 
     @Override
     public void run() 
         super.run();
         handleImageOrientation();
         getActivity().runOnUiThread(() -> uploadProfilePic());
     
.start();

我使用的是支持库中的android.support.media.ExifInterface,因此android.media.ExifInterface 的实现在旧版本的Android 中存在一些已知的安全漏洞。

build.gradle

implementation "com.android.support:exifinterface:27.1.1"

handleImageOrientation()

private void handleImageOrientation() 
        Bitmap bitmap = BitmapFactory.decodeFile(currentPhotoPath);
        Bitmap rotatedBitmap;
        try 
            ExifInterface ei = new ExifInterface(currentPhotoPath);
            int orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED);

            switch (orientation) 
                case ExifInterface.ORIENTATION_ROTATE_90:
                    rotatedBitmap = Utils.rotateImage(bitmap, 90);
                    break;

                case ExifInterface.ORIENTATION_ROTATE_180:
                    rotatedBitmap = Utils.rotateImage(bitmap, 180);
                    break;

                case ExifInterface.ORIENTATION_ROTATE_270:
                    rotatedBitmap = Utils.rotateImage(bitmap, 270);
                    break;

                case ExifInterface.ORIENTATION_NORMAL:
                default:
                    rotatedBitmap = bitmap;
            
         if (rotatedBitmap != bitmap) 
            FileOutputStream fOut = new FileOutputStream(currentPhotoPath);
            rotatedBitmap.compress(Bitmap.CompressFormat.PNG, 100, fOut);
            fOut.flush();
            fOut.close();
        
            bitmap.recycle();
            rotatedBitmap.recycle();
         catch (IOException e) 
            e.printStackTrace();
        
    

Utils.rotateImage()

public static Bitmap rotateImage(Bitmap source, float angle) 
     Matrix matrix = new Matrix();
     matrix.postRotate(angle);
     return Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(), matrix, true);

【讨论】:

以上是关于Firebase 存储图像被旋转的主要内容,如果未能解决你的问题,请参考以下文章

如何将图像上传到 Firebase 存储?

Android:图片以 -90 度旋转上传到 Firebase

从 foreach 中删除单个图像(Firebase 存储)

如何让用户从 web 应用程序上的 firebase 存储下载图像?

如何按选择的顺序将多个文件上传到 Firebase 存储?

将图像链接从 Firebase 存储存储到 Firebase 数据库时出错