質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.32%

  • Java

    14448questions

    Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

  • Android

    6745questions

    Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

  • Android Studio

    3911questions

    Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

Bitmapを経由せずに画像ファイルを回転したい

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 264

kyunMina

score 1

 前提・実現したいこと

Androidにてアプリ内で撮影した写真をimageViewに表示するシステムを制作しています。
setImageURIを用いて写真を表示すると、テスト端末では画像が90度回転して表示されます。
そのため、BitmapにしてExif情報を読み取ることで対応しましたが、今度は画質(画像サイズ)が著しく低下してしまいました。
BitmapにすることなくExif情報を参照する方法、または画質(画像サイズ)を保ったまま、表示する上のみで90度回転し表示することは可能でしょうか。

imageView自体を回転させたくないため、setRotationは利用したくないと考えています。

下記プログラムでは、変換される前のファイルの解像度は3492*4656、変換後の解像度は317*423になります。

当方初心者につき、必要な情報が不足しておりましたら大変申し訳ありません。その際は迅速に追記いたしますので、何卒お力添えをいただきたいと存じております。よろしくお願いいたします。

 カメラ周辺

private void cameraIntent(){

        // 保存先のフォルダーを作成
        File cameraFolder = new File(
                Environment.getExternalStoragePublicDirectory(
                        Environment.DIRECTORY_PICTURES),"IMG");
        cameraFolder.mkdirs();

        // 保存ファイル名
        String fileName = new SimpleDateFormat(
                "ddHHmmss", Locale.US).format(new Date());
        filePath = String.format("%s/%s.jpg", cameraFolder.getPath(),fileName);

        // capture画像のファイルパス
        File cameraFile = new File(filePath);
        cameraUri = FileProvider.getUriForFile(
                MainActivity.this,
                getApplicationContext().getPackageName() + ".fileprovider",
                cameraFile);

        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, cameraUri);
        startActivityForResult(intent, RESULT_CAMERA);

 onActivityResult

@Override
    protected void onActivityResult(int requestCode,
                                    int resultCode, Intent intent) {
        if (requestCode == RESULT_CAMERA) {

            if(cameraUri != null){

                rotateImage(filePath);
                imageView.setImageURI(cameraUri);
                registerDatabase(filePath);

            }
            else{
                Log.d("debug","cameraUri == null");
            }
        }
    }

 画像回転

public int rotateImage(String filePath){

        int degree = getRotateDegree(filePath);
        Log.d("debug","degree:"+degree);

        if (degree > 0){
            OutputStream out = null;
            Bitmap bitmap = null;
            Bitmap rotatedImage = null;
            try{
                Matrix mat = new Matrix();
                mat.postRotate(degree);
                BitmapFactory.Options opts = new BitmapFactory.Options();
                opts.inJustDecodeBounds = true;
                BitmapFactory.decodeFile(filePath, opts);
                int width = 480;
                int scale = 1;
                if (opts.outWidth > width) {
                    scale = opts.outWidth / width + 2;
                }
                opts.inJustDecodeBounds = false;
                opts.inSampleSize = scale;
                bitmap = BitmapFactory.decodeFile(filePath, opts);
                rotatedImage = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), mat, true);
                out = new FileOutputStream(filePath);
                rotatedImage.compress(Bitmap.CompressFormat.JPEG, 100, out);
            } catch (Exception ex) {
                ex.printStackTrace();
            } finally {
                if (out != null) try { out.close(); } catch (IOException e) {}
                if (bitmap != null) bitmap.recycle();
                if (rotatedImage != null) rotatedImage.recycle();
            }

        }

        return degree;
    }
private int getRotateDegree(String filePath){

        int degree = 0;
        try{
            ExifInterface exifInterface = new ExifInterface(filePath);
            int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION,
                    ExifInterface.ORIENTATION_UNDEFINED);

            if (orientation == ExifInterface.ORIENTATION_ROTATE_90){
                degree = 90;
            }
            else if (orientation == ExifInterface.ORIENTATION_ROTATE_180){
                degree =180;
            }
            else if (orientation == ExifInterface.ORIENTATION_ROTATE_270){
                degree = 270;
            }
            if (degree != 0){
                exifInterface.setAttribute(ExifInterface.TAG_ORIENTATION, "0");
                exifInterface.saveAttributes();
            }
        } catch (IOException e){
            degree = -1;
            e.printStackTrace();
        }

        return degree;
    }

 試したこと

Uri形式の画像ファイルを回転させる方法を調べましたが、どれもBitmap形式にしてExif情報から...というものしか見つけ出せず、かつ画質の劣化しない方法を見つけ出すに至ることができませんでした。

 補足情報

・開発環境
Android Studio 3.1.3
Build #AI-173.4819257, built on June 5, 2018
JRE: 1.8.0_152-release-1024-b02 amd64
JVM: OpenJDK 64-Bit Server VM by JetBrains s.r.o
Windows 7 6.1

・テスト端末
LG V20(LGE-H990)
Android6.0

・アプリ対応Sdk23↑

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

if (opts.outWidth > width) {
                    scale = opts.outWidth / width + 2;
                }
                opts.inJustDecodeBounds = false;
                opts.inSampleSize = scale;

ここでスケールしているからでは?

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/07/25 16:52

    inSampleSize = scale;

    inSampleSize = 1;
    にしたら本来のサイズで表示されるようになりました!
    本当にありがとうございます!!!

    キャンセル

  • 2018/07/26 01:53

    良かったですね。私、java は知りませんし組んだこともありません。

    書かれたソースはどこからかコピーしたのだと思いますが、使う前に何をしているのかくらい読み解いたほうがいいですよ。

    たいして難しい英語ではないですしjava 知らない人でも数分見たらわかるレベルです。他人のコードは理解してから使いましょう。

    キャンセル

  • 2018/07/27 11:38

    返す言葉もございません。
    勉強不足を反省し地道に知識を積んでいこうと思います。

    キャンセル

  • 2018/07/27 12:28 編集

    怒って無いですよ。がんばって下さい。

    名前に意味、意図が込められています。翻訳すれば大体の意味がわかりますのでしらべると良いですよ。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.32%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • Java

    14448questions

    Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

  • Android

    6745questions

    Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

  • Android Studio

    3911questions

    Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。