From c81fbdbf9d6bbd566ccdd087972e626c18ef5344 Mon Sep 17 00:00:00 2001 From: tibbi Date: Sun, 13 Jan 2019 20:56:39 +0100 Subject: [PATCH] moving some file rotation related functions in activity extensions --- .../pro/activities/ViewPagerActivity.kt | 118 +----------------- .../gallery/pro/extensions/Activity.kt | 109 ++++++++++++++++ 2 files changed, 113 insertions(+), 114 deletions(-) diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/ViewPagerActivity.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/ViewPagerActivity.kt index fac43adb8..379a8733e 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/ViewPagerActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/ViewPagerActivity.kt @@ -8,10 +8,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.media.ExifInterface import android.net.Uri @@ -26,7 +23,6 @@ import android.view.WindowManager import android.view.animation.DecelerateInterpolator import android.widget.Toast import androidx.viewpager.widget.ViewPager -import com.bumptech.glide.Glide import com.simplemobiletools.commons.dialogs.PropertiesDialog import com.simplemobiletools.commons.dialogs.RenameItemDialog 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.bottom_actions.* import java.io.File -import java.io.FileOutputStream -import java.io.InputStream -import java.io.OutputStream import java.util.* class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, ViewPagerFragment.FragmentListener { @@ -595,116 +588,15 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View SaveAsDialog(this, currPath, false) { handleSAFDialog(it) { Thread { - saveImageToFile(currPath, it) + saveImageToFile(currPath, it, mRotationDegrees) { + mRotationDegrees = 0 + invalidateOptionsMenu() + } }.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 { val file = File(mPath) if (file.isHidden) { @@ -1169,8 +1061,6 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View private fun getCurrentPath() = getCurrentMedium()?.path ?: "" - private fun getCurrentFile() = File(getCurrentPath()) - override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {} override fun onPageSelected(position: Int) { diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/extensions/Activity.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/extensions/Activity.kt index c09eab78b..3a68db2c3 100644 --- a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/extensions/Activity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/extensions/Activity.kt @@ -1,13 +1,19 @@ package com.simplemobiletools.gallery.pro.extensions +import android.annotation.TargetApi import android.app.Activity import android.content.ContentProviderOperation import android.content.Intent +import android.graphics.Bitmap +import android.graphics.BitmapFactory +import android.graphics.Matrix import android.media.ExifInterface +import android.os.Build import android.provider.MediaStore import android.util.DisplayMetrics import android.view.View import androidx.appcompat.app.AppCompatActivity +import com.bumptech.glide.Glide import com.simplemobiletools.commons.activities.BaseSimpleActivity import com.simplemobiletools.commons.dialogs.ConfirmationDialog 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.interfaces.MediumDao import java.io.File +import java.io.FileOutputStream import java.io.InputStream import java.io.OutputStream import java.text.SimpleDateFormat @@ -364,3 +371,105 @@ fun Activity.fixDateTaken(paths: ArrayList, callback: (() -> Unit)? = nu 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) +}