use the previous way of image rotating at sd card files and non jpgs

This commit is contained in:
tibbi 2017-06-28 22:58:52 +02:00
parent d3d64865af
commit 7b8640a77a
5 changed files with 137 additions and 27 deletions

View file

@ -5,7 +5,10 @@ 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
@ -24,6 +27,7 @@ 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
@ -31,6 +35,7 @@ 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 {
@ -41,6 +46,7 @@ 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
@ -182,15 +188,15 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
override fun onCreateOptionsMenu(menu: Menu): Boolean { override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.menu_viewpager, menu) menuInflater.inflate(R.menu.menu_viewpager, menu)
if (getCurrentMedium() == null) val currentMedium = getCurrentMedium() ?: return true
return true
menu.apply { menu.apply {
findItem(R.id.menu_set_as).isVisible = getCurrentMedium()!!.isImage() == true findItem(R.id.menu_set_as).isVisible = currentMedium.isImage()
findItem(R.id.menu_edit).isVisible = getCurrentMedium()!!.isImage() == true findItem(R.id.menu_edit).isVisible = currentMedium.isImage()
findItem(R.id.menu_rotate).isVisible = getCurrentMedium()!!.isImage() == true findItem(R.id.menu_rotate).isVisible = currentMedium.isImage()
findItem(R.id.menu_hide).isVisible = !getCurrentMedium()!!.name.startsWith('.') findItem(R.id.menu_save_as).isVisible = mRotationDegrees != 0f
findItem(R.id.menu_unhide).isVisible = getCurrentMedium()!!.name.startsWith('.') findItem(R.id.menu_hide).isVisible = !currentMedium.name.startsWith('.')
findItem(R.id.menu_unhide).isVisible = currentMedium.name.startsWith('.')
} }
return true return true
@ -214,6 +220,7 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
R.id.menu_properties -> showProperties() R.id.menu_properties -> showProperties()
R.id.show_on_map -> showOnMap() R.id.show_on_map -> showOnMap()
R.id.menu_rotate -> rotateImage() R.id.menu_rotate -> rotateImage()
R.id.menu_save_as -> saveImageAs()
R.id.settings -> launchSettings() R.id.settings -> launchSettings()
else -> return super.onOptionsItemSelected(item) else -> return super.onOptionsItemSelected(item)
} }
@ -256,6 +263,15 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
} }
private fun rotateImage() { private fun rotateImage() {
val currentMedium = getCurrentMedium() ?: return
if (currentMedium.isJpg() && !isPathOnSD(currentMedium.path)) {
rotateByExif()
} else {
rotateByDegrees()
}
}
private fun rotateByExif() {
val exif = ExifInterface(getCurrentPath()) val exif = ExifInterface(getCurrentPath())
val rotation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL) val rotation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL)
val newRotation = getNewRotation(rotation) val newRotation = getNewRotation(rotation)
@ -274,6 +290,54 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
}.toString() }.toString()
} }
private fun rotateByDegrees() {
mRotationDegrees = (mRotationDegrees + 90) % 360
getCurrentFragment()?.let {
(it as? PhotoFragment)?.rotateImageViewBy(mRotationDegrees)
}
supportInvalidateOptionsMenu()
}
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 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 getCurrentFragment() = (view_pager.adapter as MyPagerAdapter).getCurrentFragment(view_pager.currentItem) private fun getCurrentFragment() = (view_pager.adapter as MyPagerAdapter).getCurrentFragment(view_pager.currentItem)
private fun showProperties() { private fun showProperties() {
@ -493,6 +557,7 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
} }
mPos = position mPos = position
updateActionbarTitle() updateActionbarTitle()
mRotationDegrees = 0f
supportInvalidateOptionsMenu() supportInvalidateOptionsMenu()
} }

View file

@ -28,6 +28,7 @@ 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
@ -154,28 +155,38 @@ class PhotoFragment : ViewPagerFragment() {
} }
} }
private fun loadBitmap() { private fun loadBitmap(degrees: Float = 0f) {
val targetWidth = if (ViewPagerActivity.screenWidth == 0) Target.SIZE_ORIGINAL else ViewPagerActivity.screenWidth if (degrees == 0f) {
val targetHeight = if (ViewPagerActivity.screenHeight == 0) Target.SIZE_ORIGINAL else ViewPagerActivity.screenHeight 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) Glide.with(this)
.load(medium.path) .load(medium.path)
.asBitmap() .asBitmap()
.signature(activity.getFileSignature(medium.path)) .signature(activity.getFileSignature(medium.path))
.format(if (medium.isPng()) DecodeFormat.PREFER_ARGB_8888 else DecodeFormat.PREFER_RGB_565) .format(if (medium.isPng()) DecodeFormat.PREFER_ARGB_8888 else DecodeFormat.PREFER_RGB_565)
.diskCacheStrategy(DiskCacheStrategy.NONE) .diskCacheStrategy(DiskCacheStrategy.NONE)
.override(targetWidth, targetHeight) .override(targetWidth, targetHeight)
.listener(object : RequestListener<String, Bitmap> { .listener(object : RequestListener<String, Bitmap> {
override fun onException(e: Exception?, model: String?, target: Target<Bitmap>?, isFirstResource: Boolean): Boolean { override fun onException(e: Exception?, model: String?, target: Target<Bitmap>?, isFirstResource: Boolean): Boolean {
return false return false
} }
override fun onResourceReady(resource: Bitmap, model: String?, target: Target<Bitmap>?, isFromMemoryCache: Boolean, isFirstResource: Boolean): Boolean { override fun onResourceReady(resource: Bitmap, model: String?, target: Target<Bitmap>?, isFromMemoryCache: Boolean, isFirstResource: Boolean): Boolean {
if (isFragmentVisible) if (isFragmentVisible)
addZoomableView() addZoomableView()
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() {
@ -239,6 +250,11 @@ class PhotoFragment : ViewPagerFragment() {
loadBitmap() loadBitmap()
} }
fun rotateImageViewBy(degrees: Float) {
view.subsampling_view.beGone()
loadBitmap(degrees)
}
override fun onDestroyView() { override fun onDestroyView() {
super.onDestroyView() super.onDestroyView()
Glide.clear(view.photo_view) Glide.clear(view.photo_view)

View file

@ -0,0 +1,21 @@
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

@ -20,6 +20,8 @@ data class Medium(var name: String, var path: String, val video: Boolean, val mo
fun isGif() = path.isGif() fun isGif() = path.isGif()
fun isJpg() = path.endsWith(".jpg", true) || path.endsWith(".jpeg", true)
fun isImage() = !isGif() && !video fun isImage() = !isGif() && !video
fun getMimeType() = File(path).getMimeType() fun getMimeType() = File(path).getMimeType()

View file

@ -6,6 +6,12 @@
android:icon="@drawable/ic_rotate_right" android:icon="@drawable/ic_rotate_right"
android:title="@string/rotate" android:title="@string/rotate"
app:showAsAction="ifRoom"/> app:showAsAction="ifRoom"/>
<item
android:id="@+id/menu_save_as"
android:icon="@drawable/ic_check"
android:title="@string/save_as"
android:visible="false"
app:showAsAction="ifRoom"/>
<item <item
android:id="@+id/menu_delete" android:id="@+id/menu_delete"
android:icon="@drawable/ic_delete" android:icon="@drawable/ic_delete"