modify exif metadata at rotating image from fullscreen mode + autosave it

This commit is contained in:
tibbi 2017-06-27 22:35:21 +02:00
parent 0ed110210b
commit 3c37407315
4 changed files with 41 additions and 138 deletions

View file

@ -5,10 +5,7 @@ import android.content.Intent
import android.content.pm.ActivityInfo import android.content.pm.ActivityInfo
import android.content.res.Configuration import android.content.res.Configuration
import android.database.Cursor import android.database.Cursor
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Color import android.graphics.Color
import android.graphics.Matrix
import android.graphics.drawable.ColorDrawable import android.graphics.drawable.ColorDrawable
import android.hardware.SensorManager import android.hardware.SensorManager
import android.media.ExifInterface import android.media.ExifInterface
@ -27,7 +24,6 @@ import com.simplemobiletools.gallery.R
import com.simplemobiletools.gallery.activities.MediaActivity.Companion.mMedia import com.simplemobiletools.gallery.activities.MediaActivity.Companion.mMedia
import com.simplemobiletools.gallery.adapters.MyPagerAdapter import com.simplemobiletools.gallery.adapters.MyPagerAdapter
import com.simplemobiletools.gallery.asynctasks.GetMediaAsynctask import com.simplemobiletools.gallery.asynctasks.GetMediaAsynctask
import com.simplemobiletools.gallery.dialogs.SaveAsDialog
import com.simplemobiletools.gallery.extensions.* import com.simplemobiletools.gallery.extensions.*
import com.simplemobiletools.gallery.fragments.PhotoFragment import com.simplemobiletools.gallery.fragments.PhotoFragment
import com.simplemobiletools.gallery.fragments.ViewPagerFragment import com.simplemobiletools.gallery.fragments.ViewPagerFragment
@ -35,7 +31,6 @@ import com.simplemobiletools.gallery.helpers.*
import com.simplemobiletools.gallery.models.Medium import com.simplemobiletools.gallery.models.Medium
import kotlinx.android.synthetic.main.activity_medium.* import kotlinx.android.synthetic.main.activity_medium.*
import java.io.File import java.io.File
import java.io.OutputStream
import java.util.* import java.util.*
class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, ViewPagerFragment.FragmentListener { class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, ViewPagerFragment.FragmentListener {
@ -46,7 +41,6 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
private var mIsFullScreen = false private var mIsFullScreen = false
private var mPos = -1 private var mPos = -1
private var mShowAll = false private var mShowAll = false
private var mRotationDegrees = 0f
private var mLastHandledOrientation = 0 private var mLastHandledOrientation = 0
private var mPrevHashcode = 0 private var mPrevHashcode = 0
@ -187,16 +181,8 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
findItem(R.id.menu_set_as).isVisible = getCurrentMedium()!!.isImage() == true findItem(R.id.menu_set_as).isVisible = getCurrentMedium()!!.isImage() == true
findItem(R.id.menu_edit).isVisible = getCurrentMedium()!!.isImage() == true findItem(R.id.menu_edit).isVisible = getCurrentMedium()!!.isImage() == true
findItem(R.id.menu_rotate).isVisible = getCurrentMedium()!!.isImage() == true findItem(R.id.menu_rotate).isVisible = getCurrentMedium()!!.isImage() == true
findItem(R.id.menu_save_as).isVisible = mRotationDegrees != 0f
findItem(R.id.menu_hide).isVisible = !getCurrentMedium()!!.name.startsWith('.') findItem(R.id.menu_hide).isVisible = !getCurrentMedium()!!.name.startsWith('.')
findItem(R.id.menu_unhide).isVisible = getCurrentMedium()!!.name.startsWith('.') findItem(R.id.menu_unhide).isVisible = getCurrentMedium()!!.name.startsWith('.')
findItem(R.id.menu_rotate).subMenu.apply {
clearHeader()
findItem(R.id.rotate_right).icon = resources.getColoredDrawable(R.drawable.ic_rotate_right, R.color.actionbar_menu_icon)
findItem(R.id.rotate_left).icon = resources.getColoredDrawable(R.drawable.ic_rotate_left, R.color.actionbar_menu_icon)
findItem(R.id.rotate_one_eighty).icon = resources.getColoredDrawable(R.drawable.ic_rotate_one_eighty, R.color.actionbar_menu_icon)
}
} }
return true return true
@ -218,11 +204,8 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
R.id.menu_rename -> renameFile() R.id.menu_rename -> renameFile()
R.id.menu_edit -> openFileEditor(getCurrentFile()) R.id.menu_edit -> openFileEditor(getCurrentFile())
R.id.menu_properties -> showProperties() R.id.menu_properties -> showProperties()
R.id.menu_save_as -> saveImageAs()
R.id.show_on_map -> showOnMap() R.id.show_on_map -> showOnMap()
R.id.rotate_right -> rotateImage(90f) R.id.menu_rotate -> rotateImage()
R.id.rotate_left -> rotateImage(-90f)
R.id.rotate_one_eighty -> rotateImage(180f)
R.id.settings -> launchSettings() R.id.settings -> launchSettings()
else -> return super.onOptionsItemSelected(item) else -> return super.onOptionsItemSelected(item)
} }
@ -264,52 +247,23 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
} }
} }
private fun saveImageAs() { private fun rotateImage() {
val currPath = getCurrentPath() val exif = ExifInterface(getCurrentPath())
SaveAsDialog(this, currPath) { val rotation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL)
Thread({ val newRotation = getNewRotation(rotation)
toast(R.string.saving) exif.setAttribute(ExifInterface.TAG_ORIENTATION, newRotation)
val selectedFile = File(it) exif.saveAttributes()
val tmpFile = File(selectedFile.parent, "tmp_${it.getFilenameFromPath()}") File(getCurrentPath()).setLastModified(System.currentTimeMillis())
try { (getCurrentFragment() as? PhotoFragment)?.refreshBitmap()
val bitmap = BitmapFactory.decodeFile(currPath)
getFileOutputStream(tmpFile) {
saveFile(tmpFile, bitmap, it)
if (needsStupidWritePermissions(selectedFile.absolutePath)) {
deleteFile(selectedFile) {}
} }
renameFile(tmpFile, selectedFile) { private fun getNewRotation(rotation: Int): String {
deleteFile(tmpFile) {} return when (rotation) {
} ExifInterface.ORIENTATION_ROTATE_90 -> ExifInterface.ORIENTATION_ROTATE_180
} ExifInterface.ORIENTATION_ROTATE_180 -> ExifInterface.ORIENTATION_ROTATE_270
} catch (e: OutOfMemoryError) { ExifInterface.ORIENTATION_ROTATE_270 -> ExifInterface.ORIENTATION_NORMAL
toast(R.string.out_of_memory_error) else -> ExifInterface.ORIENTATION_ROTATE_90
deleteFile(tmpFile) {} }.toString()
} catch (e: Exception) {
toast(R.string.unknown_error_occurred)
deleteFile(tmpFile) {}
}
}).start()
}
}
private fun saveFile(file: File, bitmap: Bitmap, out: OutputStream) {
val matrix = Matrix()
matrix.postRotate(mRotationDegrees)
val bmp = Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true)
bmp.compress(file.getCompressionFormat(), 90, out)
out.flush()
toast(R.string.file_saved)
out.close()
}
private fun rotateImage(degrees: Float) {
mRotationDegrees = (mRotationDegrees + degrees) % 360
getCurrentFragment()?.let {
(it as? PhotoFragment)?.rotateImageViewBy(mRotationDegrees)
}
supportInvalidateOptionsMenu()
} }
private fun getCurrentFragment() = (view_pager.adapter as MyPagerAdapter).getCurrentFragment(view_pager.currentItem) private fun getCurrentFragment() = (view_pager.adapter as MyPagerAdapter).getCurrentFragment(view_pager.currentItem)
@ -536,7 +490,6 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
} }
mPos = position mPos = position
updateActionbarTitle() updateActionbarTitle()
mRotationDegrees = 0f
supportInvalidateOptionsMenu() supportInvalidateOptionsMenu()
} }

View file

@ -28,7 +28,6 @@ import com.simplemobiletools.gallery.extensions.config
import com.simplemobiletools.gallery.extensions.getFileSignature import com.simplemobiletools.gallery.extensions.getFileSignature
import com.simplemobiletools.gallery.extensions.getRealPathFromURI import com.simplemobiletools.gallery.extensions.getRealPathFromURI
import com.simplemobiletools.gallery.extensions.portrait import com.simplemobiletools.gallery.extensions.portrait
import com.simplemobiletools.gallery.helpers.GlideRotateTransformation
import com.simplemobiletools.gallery.helpers.MEDIUM import com.simplemobiletools.gallery.helpers.MEDIUM
import com.simplemobiletools.gallery.models.Medium import com.simplemobiletools.gallery.models.Medium
import it.sephiroth.android.library.exif2.ExifInterface import it.sephiroth.android.library.exif2.ExifInterface
@ -159,8 +158,7 @@ class PhotoFragment : ViewPagerFragment() {
} }
} }
private fun loadBitmap(degrees: Float = 0f) { private fun loadBitmap() {
if (degrees == 0f) {
val targetWidth = if (ViewPagerActivity.screenWidth == 0) Target.SIZE_ORIGINAL else ViewPagerActivity.screenWidth val targetWidth = if (ViewPagerActivity.screenWidth == 0) Target.SIZE_ORIGINAL else ViewPagerActivity.screenWidth
val targetHeight = if (ViewPagerActivity.screenHeight == 0) Target.SIZE_ORIGINAL else ViewPagerActivity.screenHeight val targetHeight = if (ViewPagerActivity.screenHeight == 0) Target.SIZE_ORIGINAL else ViewPagerActivity.screenHeight
@ -182,15 +180,6 @@ class PhotoFragment : ViewPagerFragment() {
return false return false
} }
}).into(view.photo_view) }).into(view.photo_view)
} else {
Glide.with(this)
.load(medium.path)
.asBitmap()
.transform(GlideRotateTransformation(context, degrees))
.thumbnail(0.2f)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.into(view.photo_view)
}
} }
private fun addZoomableView() { private fun addZoomableView() {
@ -249,16 +238,16 @@ class PhotoFragment : ViewPagerFragment() {
} }
} }
fun refreshBitmap() {
view.subsampling_view.beGone()
loadBitmap()
}
override fun onDestroyView() { override fun onDestroyView() {
super.onDestroyView() super.onDestroyView()
Glide.clear(view.photo_view) Glide.clear(view.photo_view)
} }
fun rotateImageViewBy(degrees: Float) {
view.subsampling_view.beGone()
loadBitmap(degrees)
}
override fun onConfigurationChanged(newConfig: Configuration?) { override fun onConfigurationChanged(newConfig: Configuration?) {
super.onConfigurationChanged(newConfig) super.onConfigurationChanged(newConfig)
loadImage() loadImage()

View file

@ -1,21 +0,0 @@
package com.simplemobiletools.gallery.helpers
import android.content.Context
import android.graphics.Bitmap
import android.graphics.Matrix
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool
import com.bumptech.glide.load.resource.bitmap.BitmapTransformation
class GlideRotateTransformation(context: Context, val rotateRotationAngle: Float) : BitmapTransformation(context) {
override fun transform(pool: BitmapPool, bitmap: Bitmap, outWidth: Int, outHeight: Int): Bitmap {
if (rotateRotationAngle % 360 == 0f)
return bitmap
val matrix = Matrix()
matrix.postRotate(rotateRotationAngle)
return Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true)
}
override fun getId() = "GlideRotateTransformation $rotateRotationAngle"
}

View file

@ -5,24 +5,6 @@
android:id="@+id/menu_rotate" android:id="@+id/menu_rotate"
android:icon="@drawable/ic_rotate_right" android:icon="@drawable/ic_rotate_right"
android:title="@string/rotate" android:title="@string/rotate"
app:showAsAction="ifRoom">
<menu>
<item
android:id="@+id/rotate_right"
android:title="@string/rotate_right"/>
<item
android:id="@+id/rotate_left"
android:title="@string/rotate_left"/>
<item
android:id="@+id/rotate_one_eighty"
android:title="@string/rotate_one_eighty"/>
</menu>
</item>
<item
android:id="@+id/menu_save_as"
android:icon="@drawable/ic_check"
android:title="@string/save_as"
android:visible="false"
app:showAsAction="ifRoom"/> app:showAsAction="ifRoom"/>
<item <item
android:id="@+id/menu_delete" android:id="@+id/menu_delete"