2017-07-15 9 views
0

私は、Androidのアプリで作業していますが、ユーザーはデバイスから画像を選択してリストの特定の項目に関連付けることができます。それをアプリで使用します。私の意図は、画像自体を内部メモリに格納し、SQLiteデータベース内の画像へのパスをアイテムの残りの格納された情報とともに格納することでした。
私はユーザーに画像の選択とアップロードを依頼することができましたが、写真の撮影方法によっては画像が回転することがあります。私はExifデータを見てみましたが、向きは常にゼロです。私はMediaStore.Images.Media.DATA情報のためのカーソルを使用しようとしましたが、役に立たない。関連するコードの現在の状態は以下の通りである:ここAndroidのユーザーがアップロードした画像を、Exifデータが偽のImageViewで回転した

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_details); 

    mDbHelper = new EntryDbHelper(this); 

    Intent intent = getIntent(); 
    pId = intent.getIntExtra(PhrasesActivity.T_KEY, -1); 

    mImageView = (ImageView) findViewById(R.id.details_img); 
    mImageView.setOnLongClickListener(new View.OnLongClickListener() { 
     @Override 
     public boolean onLongClick(View v) { 
      //Making an intent to Pick an image, looking for an Internal URI 
      Intent pickImageIntent = new Intent(Intent.ACTION_GET_CONTENT); 
      //Setting the content to images 
      pickImageIntent.setType("image/*"); 
      if(pickImageIntent.resolveActivity(getPackageManager()) != null) { 
       startActivityForResult(pickImageIntent, REQUEST_IMAGE_GET); 
      } 

      return true; 
     } 
    }); 

    setText(); 
    setImage(); 
} 

@Override 
protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
    if(requestCode == REQUEST_IMAGE_GET && resultCode == RESULT_OK) { 
     Bitmap image = null; 
     Uri imageUri = data.getData(); 

     try { 
      image = MediaStore.Images.Media.getBitmap(getContentResolver(), imageUri); 
     } catch(FileNotFoundException e) { 
      e.printStackTrace(); 
     } catch(IOException e) { 
      e.printStackTrace(); 
     } 

     mImageView.setImageBitmap(image); 

     String path = storeImage(image); 

     SQLiteDatabase db = mDbHelper.getWritableDatabase(); 
     ContentValues values = new ContentValues(); 
     values.put(PhraseEntry.COLUMN_URI, path.toString()); 

     String selection = PhraseEntry._ID + " = ?"; 
     String[] selectionArgs = {Integer.toString(pId)}; 

     int count = db.update(PhraseEntry.TABLE_NAME, values, selection, selectionArgs); 

     if(count == 1) { 
      Toast.makeText(this, "Image Updated Successfully", Toast.LENGTH_SHORT).show(); 
     } else { 
      Toast.makeText(this, "Image Updated UNSUCCESSFULLY", Toast.LENGTH_SHORT).show(); 
     } 
    } 
} 

private void setImage() { 
    SQLiteDatabase db = mDbHelper.getReadableDatabase(); 

    String[] projection = { 
      PhraseEntry.COLUMN_URI 
    }; 

    String selection = PhraseEntry._ID + " = ?"; 
    String[] selectionArgs = {Integer.toString(pId)}; 

    Cursor cursor = db.query(PhraseEntry.TABLE_NAME, projection, selection, selectionArgs, 
      null, null, null); 

    String imagePath = ""; 

    while(cursor.moveToNext()) { 
     imagePath = cursor.getString(
       cursor.getColumnIndexOrThrow(PhraseEntry.COLUMN_URI) 
     ); 
    } 

    if(!imagePath.isEmpty()) { 

     try { 
      File f = new File(imagePath, "phrase_" + Integer.toString(pId)); 
      Bitmap b = BitmapFactory.decodeStream(new FileInputStream(f)); 
      mImageView.setImageBitmap(b); 
     } catch (FileNotFoundException e) { 
      e.printStackTrace(); 
     } 

    } 
    else { 
     mImageView.setImageResource(R.drawable.sample); 
    } 
    cursor.close(); 
} 

が関連レイアウトファイルである:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical" 
    tools:context="com.bladefrisch.discoveringtalk.DetailsActivity"> 

    <ImageView 
     android:id="@+id/details_img" 
     style="@style/DetailImage" 
     android:contentDescription="Sample" 
     android:src="@drawable/sample" /> 

    <TextView 
     android:id="@+id/details_text" 
     style="@style/DetailText" 
     tools:text="Hello, how are you?" /> 

</LinearLayout> 

これは、ユーザが画像を選択することができ、(時には回転画像ビューにアップロード)、画像を保存し、アプリをシャットダウンした後に画像を取得します。ローテーションは唯一の大きな問題で、私が試した修正はここに反映されていません。 Exifタグをチェックし、行列を使ってビットマップを回転させ、カーソルを使って画像情報を取得して回転させ、Glideを使用するという3つのカテゴリに分類されます。 3人とも失敗し、私は次に何をすべきか迷っている。助言がありますか?

完全コードはhereです。

UPDATE
要求されたとして、私はadded無駄にExifのチェックコードをしました。前述のように、向きは常にゼロであるため、リンクのコードに基づいてヌルビットマップを取得します。

+0

"何か提案がありますか?" - 「あなたが試した修正」のいずれかを表示し、それに助けを求め、動作していないことの具体的な詳細を提示する質問をしてください。私たちが見ることのできないコードを手助けすることはできません。画像を回転するのに何もしないので、ここにあるコードは間違いなく機能しません。 FWIW、[このサンプルアプリケーション](https://github.com/commonsguy/cw-omnibus/tree/v8.6/Camera/EXIFRotater)では、「Exifタグをチェックし、ビットマップを行列で回転させる」ソリューションと、 'ImageView'を回転させます。 – CommonsWare

+0

[link](https://stackoverflow.com/questions/14066038/why-does-an-image-captured-using-camera-intent-gets-rotated-on-some-devices-on-a) – santalu

+0

@ CommonsWare私は前に試したコードを追加しましたが、santaluからのリンクに基づいていくつかの小さな変更が加えられました。私は結果に私の質問を更新しました。 – BFrisch

答えて

0

saveImage()は何をするのですか? Bitmapが入り、「パス」を返すとすれば、ファイルにBitmapを保存していると仮定します。その場合は、BitmapにはEXIFデータがないため、確かに動作しません。

the support library's edition of ExifInterfaceを使用してEXIFタグをオリジナルコンテンツから読み取ります。 getContentResolver().openInputStream(imageUri)を使用してInputStreamを取得し、それをExifInterfaceコンストラクタに渡します。

+0

これは私のデバイスSDK 24+でうまくいきました。なぜなら、それは 'InputStream'を取る' ExifInterface'コンストラクタが追加されたからです。 'saveImage()'は実際には内部ストレージに画像を書き込み、データベースのパスを返すカスタム関数です。私の主な問題は、24よりも低いデバイスのためのExifInterfaceの元のコンテンツにアクセスしているようです。別のAPIとURIでそれを行うことはできますか?最下位レベルのコンストラクタはファイル名を 'String'とみなしますが、URIとどのように違うのか少し混乱していると思います。 – BFrisch

+0

@BFrisch: "これは、デバイス24+のためにうまくいきました。なぜなら、それはInputStreamを取るExifInterfaceコンストラクタが追加されたからです。 - それはサポートライブラリからのものでもあります。これは私がリンクしているものです。 – CommonsWare

+0

私は今理解しています。私はGradleファイル内のサポートライブラリにリンクしなければならないことに気づいていませんでした。 [This](https://android-developers.googleblog.com/2016/12/introducing-the-exifinterface-support-library.html?m=1)のブログ投稿は、サポートライブラリが別のものであると理解した後に役立ちました。ありがとうございました。 – BFrisch

関連する問題