moving some file rotation related functions in activity extensions

This commit is contained in:
tibbi 2019-01-13 20:56:39 +01:00
parent 745adda5a4
commit c81fbdbf9d
2 changed files with 113 additions and 114 deletions

View File

@ -8,10 +8,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.media.ExifInterface import android.media.ExifInterface
import android.net.Uri import android.net.Uri
@ -26,7 +23,6 @@ import android.view.WindowManager
import android.view.animation.DecelerateInterpolator import android.view.animation.DecelerateInterpolator
import android.widget.Toast import android.widget.Toast
import androidx.viewpager.widget.ViewPager import androidx.viewpager.widget.ViewPager
import com.bumptech.glide.Glide
import com.simplemobiletools.commons.dialogs.PropertiesDialog import com.simplemobiletools.commons.dialogs.PropertiesDialog
import com.simplemobiletools.commons.dialogs.RenameItemDialog import com.simplemobiletools.commons.dialogs.RenameItemDialog
import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.commons.extensions.*
@ -49,9 +45,6 @@ import com.simplemobiletools.gallery.pro.models.ThumbnailItem
import kotlinx.android.synthetic.main.activity_medium.* import kotlinx.android.synthetic.main.activity_medium.*
import kotlinx.android.synthetic.main.bottom_actions.* import kotlinx.android.synthetic.main.bottom_actions.*
import java.io.File import java.io.File
import java.io.FileOutputStream
import java.io.InputStream
import java.io.OutputStream
import java.util.* import java.util.*
class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, ViewPagerFragment.FragmentListener { class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, ViewPagerFragment.FragmentListener {
@ -595,116 +588,15 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
SaveAsDialog(this, currPath, false) { SaveAsDialog(this, currPath, false) {
handleSAFDialog(it) { handleSAFDialog(it) {
Thread { Thread {
saveImageToFile(currPath, it) saveImageToFile(currPath, it, mRotationDegrees) {
mRotationDegrees = 0
invalidateOptionsMenu()
}
}.start() }.start()
} }
} }
} }
private fun saveImageToFile(oldPath: String, newPath: String) {
toast(R.string.saving)
if (oldPath == newPath && oldPath.isJpg()) {
if (tryRotateByExif(oldPath)) {
return
}
}
val tmpPath = "$recycleBinPath/.tmp_${newPath.getFilenameFromPath()}"
val tmpFileDirItem = FileDirItem(tmpPath, tmpPath.getFilenameFromPath())
try {
getFileOutputStream(tmpFileDirItem) {
if (it == null) {
toast(R.string.unknown_error_occurred)
return@getFileOutputStream
}
val oldLastModified = File(oldPath).lastModified()
if (oldPath.isJpg()) {
copyFile(oldPath, tmpPath)
saveExifRotation(ExifInterface(tmpPath), mRotationDegrees)
} else {
val inputstream = getFileInputStreamSync(oldPath)
val bitmap = BitmapFactory.decodeStream(inputstream)
saveFile(tmpPath, bitmap, it as FileOutputStream)
}
if (getDoesFilePathExist(newPath)) {
tryDeleteFileDirItem(FileDirItem(newPath, newPath.getFilenameFromPath()), false, true)
}
copyFile(tmpPath, newPath)
scanPathRecursively(newPath)
toast(R.string.file_saved)
if (config.keepLastModified) {
File(newPath).setLastModified(oldLastModified)
updateLastModified(newPath, oldLastModified)
}
it.flush()
it.close()
mRotationDegrees = 0
invalidateOptionsMenu()
// we cannot refresh a specific image in Glide Cache, so just clear it all
val glide = Glide.get(applicationContext)
glide.clearDiskCache()
runOnUiThread {
glide.clearMemory()
}
}
} catch (e: OutOfMemoryError) {
toast(R.string.out_of_memory_error)
} catch (e: Exception) {
showErrorToast(e)
} finally {
tryDeleteFileDirItem(tmpFileDirItem, false, true)
}
}
@TargetApi(Build.VERSION_CODES.N)
private fun tryRotateByExif(path: String): Boolean {
return try {
val file = File(path)
val oldLastModified = file.lastModified()
if (saveImageRotation(path, mRotationDegrees)) {
if (config.keepLastModified) {
file.setLastModified(oldLastModified)
updateLastModified(path, oldLastModified)
}
mRotationDegrees = 0
invalidateOptionsMenu()
toast(R.string.file_saved)
true
} else {
false
}
} catch (e: Exception) {
showErrorToast(e)
false
}
}
private fun copyFile(source: String, destination: String) {
var inputStream: InputStream? = null
var out: OutputStream? = null
try {
out = getFileOutputStreamSync(destination, source.getMimeType())
inputStream = getFileInputStreamSync(source)
inputStream?.copyTo(out!!)
} finally {
inputStream?.close()
out?.close()
}
}
private fun saveFile(path: String, bitmap: Bitmap, out: FileOutputStream) {
val matrix = Matrix()
matrix.postRotate(mRotationDegrees.toFloat())
val bmp = Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true)
bmp.compress(path.getCompressionFormat(), 90, out)
}
private fun isShowHiddenFlagNeeded(): Boolean { private fun isShowHiddenFlagNeeded(): Boolean {
val file = File(mPath) val file = File(mPath)
if (file.isHidden) { if (file.isHidden) {
@ -1169,8 +1061,6 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
private fun getCurrentPath() = getCurrentMedium()?.path ?: "" private fun getCurrentPath() = getCurrentMedium()?.path ?: ""
private fun getCurrentFile() = File(getCurrentPath())
override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {} override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {}
override fun onPageSelected(position: Int) { override fun onPageSelected(position: Int) {

View File

@ -1,13 +1,19 @@
package com.simplemobiletools.gallery.pro.extensions package com.simplemobiletools.gallery.pro.extensions
import android.annotation.TargetApi
import android.app.Activity import android.app.Activity
import android.content.ContentProviderOperation import android.content.ContentProviderOperation
import android.content.Intent import android.content.Intent
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Matrix
import android.media.ExifInterface import android.media.ExifInterface
import android.os.Build
import android.provider.MediaStore import android.provider.MediaStore
import android.util.DisplayMetrics import android.util.DisplayMetrics
import android.view.View import android.view.View
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import com.bumptech.glide.Glide
import com.simplemobiletools.commons.activities.BaseSimpleActivity import com.simplemobiletools.commons.activities.BaseSimpleActivity
import com.simplemobiletools.commons.dialogs.ConfirmationDialog import com.simplemobiletools.commons.dialogs.ConfirmationDialog
import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.commons.extensions.*
@ -22,6 +28,7 @@ import com.simplemobiletools.gallery.pro.helpers.NOMEDIA
import com.simplemobiletools.gallery.pro.helpers.RECYCLE_BIN import com.simplemobiletools.gallery.pro.helpers.RECYCLE_BIN
import com.simplemobiletools.gallery.pro.interfaces.MediumDao import com.simplemobiletools.gallery.pro.interfaces.MediumDao
import java.io.File import java.io.File
import java.io.FileOutputStream
import java.io.InputStream import java.io.InputStream
import java.io.OutputStream import java.io.OutputStream
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
@ -364,3 +371,105 @@ fun Activity.fixDateTaken(paths: ArrayList<String>, callback: (() -> Unit)? = nu
showErrorToast(e) showErrorToast(e)
} }
} }
fun BaseSimpleActivity.saveImageToFile(oldPath: String, newPath: String, degrees: Int, callback: () -> Unit) {
toast(R.string.saving)
if (oldPath == newPath && oldPath.isJpg()) {
if (tryRotateByExif(oldPath, degrees, callback)) {
return
}
}
val tmpPath = "$recycleBinPath/.tmp_${newPath.getFilenameFromPath()}"
val tmpFileDirItem = FileDirItem(tmpPath, tmpPath.getFilenameFromPath())
try {
getFileOutputStream(tmpFileDirItem) {
if (it == null) {
toast(R.string.unknown_error_occurred)
return@getFileOutputStream
}
val oldLastModified = File(oldPath).lastModified()
if (oldPath.isJpg()) {
copyFile(oldPath, tmpPath)
saveExifRotation(ExifInterface(tmpPath), degrees)
} else {
val inputstream = getFileInputStreamSync(oldPath)
val bitmap = BitmapFactory.decodeStream(inputstream)
saveFile(tmpPath, bitmap, it as FileOutputStream, degrees)
}
if (getDoesFilePathExist(newPath)) {
tryDeleteFileDirItem(FileDirItem(newPath, newPath.getFilenameFromPath()), false, true)
}
copyFile(tmpPath, newPath)
scanPathRecursively(newPath)
toast(R.string.file_saved)
if (config.keepLastModified) {
File(newPath).setLastModified(oldLastModified)
updateLastModified(newPath, oldLastModified)
}
it.flush()
it.close()
callback.invoke()
// we cannot refresh a specific image in Glide Cache, so just clear it all
val glide = Glide.get(applicationContext)
glide.clearDiskCache()
runOnUiThread {
glide.clearMemory()
}
}
} catch (e: OutOfMemoryError) {
toast(R.string.out_of_memory_error)
} catch (e: Exception) {
showErrorToast(e)
} finally {
tryDeleteFileDirItem(tmpFileDirItem, false, true)
}
}
@TargetApi(Build.VERSION_CODES.N)
fun Activity.tryRotateByExif(path: String, degrees: Int, callback: () -> Unit): Boolean {
return try {
val file = File(path)
val oldLastModified = file.lastModified()
if (saveImageRotation(path, degrees)) {
if (config.keepLastModified) {
file.setLastModified(oldLastModified)
updateLastModified(path, oldLastModified)
}
callback.invoke()
toast(R.string.file_saved)
true
} else {
false
}
} catch (e: Exception) {
showErrorToast(e)
false
}
}
fun BaseSimpleActivity.copyFile(source: String, destination: String) {
var inputStream: InputStream? = null
var out: OutputStream? = null
try {
out = getFileOutputStreamSync(destination, source.getMimeType())
inputStream = getFileInputStreamSync(source)
inputStream?.copyTo(out!!)
} finally {
inputStream?.close()
out?.close()
}
}
fun saveFile(path: String, bitmap: Bitmap, out: FileOutputStream, degrees: Int) {
val matrix = Matrix()
matrix.postRotate(degrees.toFloat())
val bmp = Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true)
bmp.compress(path.getCompressionFormat(), 90, out)
}