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 存储图像被旋转的主要内容,如果未能解决你的问题,请参考以下文章
Android:图片以 -90 度旋转上传到 Firebase
从 foreach 中删除单个图像(Firebase 存储)