Working EXIF lossless on Internal & SD

Tested and works on both Internal Storage and External SD cards
This commit is contained in:
Guillaume 2017-11-03 17:01:13 +01:00 committed by GitHub
parent d0e4fd1df7
commit 63d39b589a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -46,8 +46,9 @@ import com.simplemobiletools.gallery.models.Medium
import kotlinx.android.synthetic.main.activity_medium.*
import java.io.File
import java.io.FileInputStream
import java.io.FileNotFoundException
import java.io.FileOutputStream
import java.io.InputStream
import java.io.OutputStream
import java.util.*
class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, ViewPagerFragment.FragmentListener {
@ -454,52 +455,60 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
SaveAsDialog(this, currPath, false) {
Thread({
toast(R.string.saving)
if (it.isJpg() && !isPathOnSD(it)) {
if (it == currPath) {
rotateFileByExif(it)
runOnUiThread {
(getCurrentFragment() as? PhotoFragment)?.refreshBitmap()
val selectedFile = File(it)
val tmpFile = File(filesDir, ".tmp_${it.getFilenameFromPath()}")
try {
val bitmap = BitmapFactory.decodeFile(currPath)
getFileOutputStream(tmpFile) {
if (it == null) {
toast(R.string.unknown_error_occurred)
deleteFile(tmpFile) {}
return@getFileOutputStream
}
} else {
copyFile(currPath, it)
rotateFileByExif(it)
if (currPath.isJpg()) {
saveRotation(getCurrentFile(), tmpFile)
} else {
saveFile(tmpFile, bitmap, it as FileOutputStream)
}
if (tmpFile.length() > 0 && selectedFile.exists()) {
deleteFile(selectedFile) {}
}
copyFile(tmpFile, selectedFile)
scanPath(selectedFile.absolutePath) {}
deleteFile(tmpFile) {} // Not necessary?
toast(R.string.file_saved)
it.flush()
it.close()
mRotationDegrees = 0f
invalidateOptionsMenu()
}
} else {
rotateFileByDegrees(currPath, it)
} catch (e: OutOfMemoryError) {
toast(R.string.out_of_memory_error)
deleteFile(tmpFile) {}
} catch (e: Exception) {
showErrorToast(e)
deleteFile(tmpFile) {}
}
}).start()
}
}
private fun rotateFileByDegrees(sourcePath: String, destinationPath: String) {
val tmpFile = File(File(destinationPath).parent, ".tmp_${destinationPath.getFilenameFromPath()}")
private fun copyFile(source: File, destination: File) {
var inputStream: InputStream? = null
var out: OutputStream? = null
try {
getFileOutputStream(tmpFile) {
if (it == null) {
toast(R.string.unknown_error_occurred)
return@getFileOutputStream
}
val bitmap = BitmapFactory.decodeFile(sourcePath)
saveFile(tmpFile, bitmap, it as FileOutputStream)
it.flush()
it.close()
val destination = File(destinationPath)
deleteFile(destination) {
renameFile(tmpFile, destination) {}
}
toast(R.string.file_saved)
mRotationDegrees = 0f
invalidateOptionsMenu()
if (needsStupidWritePermissions(destination.absolutePath)) {
getFileDocument(destination.parent)
}
} catch (e: OutOfMemoryError) {
toast(R.string.out_of_memory_error)
deleteFile(tmpFile) {}
} catch (e: Exception) {
showErrorToast(e)
deleteFile(tmpFile) {}
out = getFileOutputStreamSync(destination.absolutePath, source.getMimeType(), getFileDocument(destination.parent))
inputStream = FileInputStream(source)
inputStream.copyTo(out!!)
} finally {
inputStream?.close()
out?.close()
}
}
@ -510,34 +519,13 @@ class ViewPagerActivity : SimpleActivity(), ViewPager.OnPageChangeListener, View
bmp.compress(file.getCompressionFormat(), 90, out)
}
private fun copyFile(sourcePath: String, destinationPath: String) {
var inputStream: FileInputStream? = null
var outputStream: FileOutputStream? = null
try {
inputStream = FileInputStream(sourcePath)
outputStream = FileOutputStream(destinationPath)
inputStream.copyTo(outputStream)
scanPath(destinationPath) {}
} catch (ignored: FileNotFoundException) {
} finally {
inputStream?.close()
outputStream?.close()
}
}
private fun rotateFileByExif(path: String) {
val exif = ExifInterface(path)
val orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL)
val orientationDegrees = (degreesForRotation(orientation) + mRotationDegrees) % 360
private fun saveRotation(input: File, output: File) {
copyFile(input, output)
val exif = ExifInterface(output.absolutePath)
var orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL)
var orientationDegrees = (degreesForRotation(orientation) + mRotationDegrees) % 360
exif.setAttribute(ExifInterface.TAG_ORIENTATION, rotationFromDegrees(orientationDegrees))
exif.saveAttributes()
if (!config.keepLastModified) {
File(getCurrentPath()).setLastModified(System.currentTimeMillis())
}
mRotationDegrees = 0f
invalidateOptionsMenu()
toast(R.string.file_saved)
}
private fun degreesForRotation(orientation: Int) = when (orientation) {