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.res.Configuration
import android.database.Cursor
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Color
import android.graphics.Matrix
import android.graphics.drawable.ColorDrawable
import android.hardware.SensorManager
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.adapters.MyPagerAdapter
import com.simplemobiletools.gallery.asynctasks.GetMediaAsynctask
import com.simplemobiletools.gallery.dialogs.SaveAsDialog
import com.simplemobiletools.gallery.extensions.*
import com.simplemobiletools.gallery.fragments.PhotoFragment
import com.simplemobiletools.gallery.fragments.ViewPagerFragment
@ -35,7 +31,6 @@ import com.simplemobiletools.gallery.helpers.*
import com.simplemobiletools.gallery.models.Medium
import kotlinx.android.synthetic.main.activity_medium.*
import java.io.File
import java.io.OutputStream
import java.util.*
class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, ViewPagerFragment.FragmentListener {
@ -46,7 +41,6 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
private var mIsFullScreen = false
private var mPos = -1
private var mShowAll = false
private var mRotationDegrees = 0f
private var mLastHandledOrientation = 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_edit).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_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
@ -218,11 +204,8 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
R.id.menu_rename -> renameFile()
R.id.menu_edit -> openFileEditor(getCurrentFile())
R.id.menu_properties -> showProperties()
R.id.menu_save_as -> saveImageAs()
R.id.show_on_map -> showOnMap()
R.id.rotate_right -> rotateImage(90f)
R.id.rotate_left -> rotateImage(-90f)
R.id.rotate_one_eighty -> rotateImage(180f)
R.id.menu_rotate -> rotateImage()
R.id.settings -> launchSettings()
else -> return super.onOptionsItemSelected(item)
}
@ -264,52 +247,23 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
}
}
private fun saveImageAs() {
val currPath = getCurrentPath()
SaveAsDialog(this, currPath) {
Thread({
toast(R.string.saving)
val selectedFile = File(it)
val tmpFile = File(selectedFile.parent, "tmp_${it.getFilenameFromPath()}")
try {
val bitmap = BitmapFactory.decodeFile(currPath)
getFileOutputStream(tmpFile) {
saveFile(tmpFile, bitmap, it)
if (needsStupidWritePermissions(selectedFile.absolutePath)) {
deleteFile(selectedFile) {}
}
renameFile(tmpFile, selectedFile) {
deleteFile(tmpFile) {}
}
}
} catch (e: OutOfMemoryError) {
toast(R.string.out_of_memory_error)
deleteFile(tmpFile) {}
} catch (e: Exception) {
toast(R.string.unknown_error_occurred)
deleteFile(tmpFile) {}
}
}).start()
}
private fun rotateImage() {
val exif = ExifInterface(getCurrentPath())
val rotation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL)
val newRotation = getNewRotation(rotation)
exif.setAttribute(ExifInterface.TAG_ORIENTATION, newRotation)
exif.saveAttributes()
File(getCurrentPath()).setLastModified(System.currentTimeMillis())
(getCurrentFragment() as? PhotoFragment)?.refreshBitmap()
}
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 getNewRotation(rotation: Int): String {
return when (rotation) {
ExifInterface.ORIENTATION_ROTATE_90 -> ExifInterface.ORIENTATION_ROTATE_180
ExifInterface.ORIENTATION_ROTATE_180 -> ExifInterface.ORIENTATION_ROTATE_270
ExifInterface.ORIENTATION_ROTATE_270 -> ExifInterface.ORIENTATION_NORMAL
else -> ExifInterface.ORIENTATION_ROTATE_90
}.toString()
}
private fun getCurrentFragment() = (view_pager.adapter as MyPagerAdapter).getCurrentFragment(view_pager.currentItem)
@ -536,7 +490,6 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
}
mPos = position
updateActionbarTitle()
mRotationDegrees = 0f
supportInvalidateOptionsMenu()
}

View file

@ -28,7 +28,6 @@ import com.simplemobiletools.gallery.extensions.config
import com.simplemobiletools.gallery.extensions.getFileSignature
import com.simplemobiletools.gallery.extensions.getRealPathFromURI
import com.simplemobiletools.gallery.extensions.portrait
import com.simplemobiletools.gallery.helpers.GlideRotateTransformation
import com.simplemobiletools.gallery.helpers.MEDIUM
import com.simplemobiletools.gallery.models.Medium
import it.sephiroth.android.library.exif2.ExifInterface
@ -159,38 +158,28 @@ class PhotoFragment : ViewPagerFragment() {
}
}
private fun loadBitmap(degrees: Float = 0f) {
if (degrees == 0f) {
val targetWidth = if (ViewPagerActivity.screenWidth == 0) Target.SIZE_ORIGINAL else ViewPagerActivity.screenWidth
val targetHeight = if (ViewPagerActivity.screenHeight == 0) Target.SIZE_ORIGINAL else ViewPagerActivity.screenHeight
private fun loadBitmap() {
val targetWidth = if (ViewPagerActivity.screenWidth == 0) Target.SIZE_ORIGINAL else ViewPagerActivity.screenWidth
val targetHeight = if (ViewPagerActivity.screenHeight == 0) Target.SIZE_ORIGINAL else ViewPagerActivity.screenHeight
Glide.with(this)
.load(medium.path)
.asBitmap()
.signature(activity.getFileSignature(medium.path))
.format(if (medium.isPng()) DecodeFormat.PREFER_ARGB_8888 else DecodeFormat.PREFER_RGB_565)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.override(targetWidth, targetHeight)
.listener(object : RequestListener<String, Bitmap> {
override fun onException(e: Exception?, model: String?, target: Target<Bitmap>?, isFirstResource: Boolean): Boolean {
return false
}
Glide.with(this)
.load(medium.path)
.asBitmap()
.signature(activity.getFileSignature(medium.path))
.format(if (medium.isPng()) DecodeFormat.PREFER_ARGB_8888 else DecodeFormat.PREFER_RGB_565)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.override(targetWidth, targetHeight)
.listener(object : RequestListener<String, Bitmap> {
override fun onException(e: Exception?, model: String?, target: Target<Bitmap>?, isFirstResource: Boolean): Boolean {
return false
}
override fun onResourceReady(resource: Bitmap, model: String?, target: Target<Bitmap>?, isFromMemoryCache: Boolean, isFirstResource: Boolean): Boolean {
if (isFragmentVisible)
addZoomableView()
return false
}
}).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)
}
override fun onResourceReady(resource: Bitmap, model: String?, target: Target<Bitmap>?, isFromMemoryCache: Boolean, isFirstResource: Boolean): Boolean {
if (isFragmentVisible)
addZoomableView()
return false
}
}).into(view.photo_view)
}
private fun addZoomableView() {
@ -249,16 +238,16 @@ class PhotoFragment : ViewPagerFragment() {
}
}
fun refreshBitmap() {
view.subsampling_view.beGone()
loadBitmap()
}
override fun onDestroyView() {
super.onDestroyView()
Glide.clear(view.photo_view)
}
fun rotateImageViewBy(degrees: Float) {
view.subsampling_view.beGone()
loadBitmap(degrees)
}
override fun onConfigurationChanged(newConfig: Configuration?) {
super.onConfigurationChanged(newConfig)
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:icon="@drawable/ic_rotate_right"
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"/>
<item
android:id="@+id/menu_delete"