Working EXIF lossless on Internal & SD
Tested and works on both Internal Storage and External SD cards
This commit is contained in:
parent
d0e4fd1df7
commit
63d39b589a
1 changed files with 52 additions and 64 deletions
|
@ -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) {
|
||||
|
|
Loading…
Reference in a new issue