三星设备中的相机方向问题

5

我已经成功地点击了图片并将其保存在卡片中。在所有设备上都运行得非常完美,但问题是当我在三星设备上测试时,如果我在竖屏模式下点击图像,则默认情况下将图像保存在横屏模式下。但我没有编写任何旋转代码。请帮帮我。我该如何解决这个问题?

private void takePicture() {

    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

    try {
        Uri mImageCaptureUri = null;
        String state = Environment.getExternalStorageState();
        if (Environment.MEDIA_MOUNTED.equals(state)) {
            mImageCaptureUri = Uri.fromFile(mFileTemp);
        } else {
            mImageCaptureUri = InternalStorageContentProvider.CONTENT_URI;
        }
        intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT,
                mImageCaptureUri);
        intent.putExtra("return-data", true);
        startActivityForResult(intent, REQUEST_CODE_TAKE_PICTURE);
    } catch (ActivityNotFoundException e) {

        Log.d("", "cannot take picture", e);
    }
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {

    if (resultCode != RESULT_OK) {

        return;
    }

    Bitmap bitmap;

    switch (requestCode) {

    case REQUEST_CODE_TAKE_PICTURE:

        startCropImage();
        break;
    case REQUEST_CODE_CROP_IMAGE:

        String path = data.getStringExtra(CropImage.IMAGE_PATH);
        if (path == null) {

            return;
        }

        bitmap = BitmapFactory.decodeFile(mFileTemp.getPath());
        resizedBitmap = ScalingUtilities.createScaledBitmap(bitmap, 320,
                320, ScalingLogic.CROP);
        imgPreview.setImageBitmap(resizedBitmap);
        break;
    }
    super.onActivityResult(requestCode, resultCode, data);
}


private void startCropImage() {

    Intent intent = new Intent(this, CropImage.class);
    intent.putExtra(CropImage.IMAGE_PATH, mFileTemp.getPath());
    intent.putExtra(CropImage.SCALE, true);

    intent.putExtra(CropImage.ASPECT_X, 2);
    intent.putExtra(CropImage.ASPECT_Y, 2);

    startActivityForResult(intent, REQUEST_CODE_CROP_IMAGE);
}

我在清单文件中添加了以下权限。
   <uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.hardware.camera.autofocus" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

1
请查看我的答案,链接如下:https://dev59.com/uoDba4cB1Zd3GeqPEnq1#24219714 或者 https://dev59.com/3WYq5IYBdhLWcg3w8VG8#23730776 - Haresh Chhelana
请问为什么在Android上使用相机意图捕获的图像会在某些设备上旋转? - Shirish Herwade
2个回答

5

我解决了我的 bug,其实我使用了一个技巧。我以编程方式获取了制造商名称,就像这样:

 String device_name = Build.MANUFACTURER;

之后,我将其保存在sharedpreferences对象中。

 deviceIdPreferences = getSharedPreferences("USER_INFO", Context.MODE_PRIVATE);
    SharedPreferences.Editor   editor = deviceIdPreferences.edit();
    editor.putString("Device_id",deviceId);
    editor.putString("device_name",device_name);
    editor.commit();

接下来,在目标Java文件中,我从SharedPreference中提取了值。

preferences = this.getSharedPreferences(
            "USER_INFO", Context.MODE_PRIVATE);
    device_name = preferences.getString("device_name", "Empty");

然后

    mBitmap = getBitmap(mImagePath);
    if(device_name.equals("samsung")){

            switch (Integer.parseInt(gotOrientation)) {

                case ExifInterface.ORIENTATION_ROTATE_90:
                    mBitmap = Util.rotateImage(mBitmap, 90);
                    break;
                case ExifInterface.ORIENTATION_ROTATE_180:
                    mBitmap = Util.rotateImage(mBitmap, 90);
                    break;
                case ExifInterface.ORIENTATION_ROTATE_270:
                    mBitmap = Util.rotateImage(mBitmap, 90);
                    break;
                default:
                    mBitmap = Util.rotateImage(mBitmap, 90);
                    break;
            }

        }




 private Bitmap getBitmap(String path) {

    Uri uri = getImageUri(path);
    InputStream in = null;
    try {
        in = mContentResolver.openInputStream(uri);

        //Decode image size
        BitmapFactory.Options o = new BitmapFactory.Options();
        o.inJustDecodeBounds = true;

        BitmapFactory.decodeStream(in, null, o);
        in.close();

        int scale = 1;
        if (o.outHeight > IMAGE_MAX_SIZE || o.outWidth > IMAGE_MAX_SIZE) {
            scale = (int) Math.pow(2, (int) Math.round(Math.log(IMAGE_MAX_SIZE / (double) Math.max(o.outHeight, o.outWidth)) / Math.log(0.5)));
        }

        BitmapFactory.Options o2 = new BitmapFactory.Options();
        o2.inSampleSize = scale;
        in = mContentResolver.openInputStream(uri);
        Bitmap b = BitmapFactory.decodeStream(in, null, o2);
        in.close();

        return b;
    } catch (FileNotFoundException e) {
        Log.e(TAG, "file " + path + " not found");
    } catch (IOException e) {
        Log.e(TAG, "file " + path + " not found");
    }
    return null;
}

3
许多设备,但不是全部,无法保存竖屏图像。它们会保存带有EXIF标头的横屏图像,告诉图像查看器将图像旋转为竖屏。并非所有图像查看器都处理此类情况。
这是我编写CWAC-Camera库的部分原因,以提供来自不同设备的统一相机输出。 我使用的代码类似于Haresh在他的评论中指出的内容,但有一些值得注意的区别:
  1. Haresh的代码似乎假设相机处于竖屏模式;我的代码旨在处理任何情况。

  2. Haresh的代码在主应用程序线程上显式执行所有繁重的工作,包括磁盘I/O,这是一个非常糟糕的想法。我的代码在后台线程上运行。

  3. 他的代码对图像进行降采样。我猜这是为了帮助防止内存不足错误,这在这里绝对是个挑战。在我的情况下,我让使用我的库的开发人员有选择地指定大堆,以帮助确保我可以执行位图旋转。最终,我将把这段代码移到NDK中,在那里内存分配不计入Dalvik堆限制。

  4. 我的代码还负责其他设备特定问题,例如根据需要翻转FFC图像或者如果开发人员请求则镜像FFC图像。

但是,我的代码专门设计用于我的库,因此需要大量工作才能将逻辑拆分成可独立使用的东西。

请注意,我的代码链接是特定于库的v0.6.9版本。如果您在几个月后阅读此答案,则可能存在该类的更新版本。相反,该类可能已不再存在于master仓库中,因为我已将代码移入NDK。

在使用了太多与相机相关的库并自己实现了一些之后,我可以诚实地说,对于我来说,cwac2是顶尖的相机库。关于您提供的链接和方向问题,据我理解,问题的根源是三星和其他一些制造商将所有图像旋转90度。您的解决方案是否通用而不基于当前制造商? - Nativ
@Nativ:如果我没记错的话,我的实现只使用了EXIF头,没有使用任何制造商特定的技巧。 - CommonsWare
谢谢。我打算自己实现这个层,想知道你是否知道有没有一个来源可能包含一个制造商列表,该列表将方向与其他制造商不同对待。 - Nativ

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接