Skip to content

Commit d077daf

Browse files
author
Dan Oprea
committed
Fix #1
1 parent 9209acb commit d077daf

File tree

3 files changed

+29
-108
lines changed

3 files changed

+29
-108
lines changed

app/src/main/AndroidManifest.xml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@
1717
android:label="@string/app_name"
1818
android:roundIcon="@mipmap/ic_launcher_round"
1919
android:supportsRtl="true"
20-
android:theme="@style/Theme.SimpleRawCamera"
21-
android:largeHeap="true">
20+
android:theme="@style/Theme.SimpleRawCamera">
2221
<activity
2322
android:name=".CameraActivity"
2423
android:screenOrientation="landscape">

app/src/main/java/com/dan/simplerawcamera/CameraActivity.kt

Lines changed: 28 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,9 @@ import com.dan.simplerawcamera.databinding.ActivityMainBinding
3232
import kotlinx.coroutines.Dispatchers
3333
import kotlinx.coroutines.GlobalScope
3434
import kotlinx.coroutines.launch
35-
import java.io.ByteArrayOutputStream
35+
import java.io.OutputStream
3636
import java.text.SimpleDateFormat
3737
import java.util.*
38-
import kotlin.concurrent.schedule
3938
import kotlin.concurrent.timer
4039
import kotlin.math.abs
4140
import kotlin.math.log2
@@ -75,22 +74,10 @@ class CameraActivity : AppCompatActivity() {
7574
const val FOCUS_STATE_SEARCHING = 2
7675
const val FOCUS_STATE_LOCKED = 3
7776

78-
const val MEMORY_RETRY_TIMEOUT = 250L //ms
79-
8077
const val SELECT_CAMERA_ASYNC_DELAY = 250L //ms
8178

8279
private val FILE_NAME_DATE_FORMAT = SimpleDateFormat("yyyyMMdd_HHmmss_SSS", Locale.US)
8380

84-
fun getMemInfo(): Pair<Long, Long> {
85-
val info = Runtime.getRuntime()
86-
val usedSize = (info.totalMemory() - info.freeMemory()) / (1024L * 1024L)
87-
val maxSize = info.maxMemory() / (1024L * 1024L)
88-
val freeSize = maxSize - usedSize
89-
return Pair(freeSize, maxSize)
90-
}
91-
92-
fun getFreeMemInfo(): Long = getMemInfo().first
93-
9481
/** Get photo name */
9582
fun getPhotoBaseFileName(timestamp: Long): String = FILE_NAME_DATE_FORMAT.format(Date(timestamp))
9683

@@ -176,9 +163,6 @@ class CameraActivity : AppCompatActivity() {
176163

177164
private var mLocation: Location? = null
178165

179-
private val mSaveAsyncMQ = mutableListOf<Triple<String, String, ByteArray>>()
180-
private var mSaveAsyncBusy = false
181-
182166
private var mOrientationEventListener: OrientationEventListener? = null
183167
private var mScreenOrientation: Int = 0
184168
private var mPhotoExifOrientation: Int = 0
@@ -1125,61 +1109,27 @@ class CameraActivity : AppCompatActivity() {
11251109
}
11261110
}
11271111

1128-
private fun saveAsyncNextItem() {
1129-
mBinding.frameView.updateDebugMemInfo()
1130-
1131-
if(!mSaveAsyncBusy && mSaveAsyncMQ.isNotEmpty()) {
1132-
mSaveAsyncBusy = true
1133-
mBinding.frameView.showSavePhotosIcon(true)
1134-
val item = mSaveAsyncMQ.get(0)
1135-
mSaveAsyncMQ.removeAt(0)
1136-
1137-
GlobalScope.launch(Dispatchers.IO) {
1138-
val fileName = item.first
1139-
val mimeType = item.second
1140-
val byteArray = item.third
1141-
var failed = true
1142-
1143-
try {
1144-
mSaveFolder?.let { saveFolder ->
1145-
saveFolder.createFile(mimeType, fileName)?.let { newFile ->
1146-
contentResolver.openOutputStream(newFile.uri)?.let { outputStream ->
1147-
outputStream.write(byteArray)
1148-
outputStream.close()
1149-
failed = false
1150-
}
1151-
}
1152-
}
1153-
} catch (e: Exception) {
1154-
e.printStackTrace()
1155-
}
1156-
1157-
mSaveAsyncBusy = false
1158-
runOnUiThread {
1159-
if (failed) mBinding.frameView.showSaveError()
1160-
saveAsyncNextItem()
1112+
private fun createAndSave( fileName: String, mimeType: String, saveCallback: (outputStream: OutputStream) -> Unit ) {
1113+
mSaveFolder?.let { saveFolder ->
1114+
saveFolder.createFile(mimeType, fileName)?.let { newFile ->
1115+
contentResolver.openOutputStream(newFile.uri)?.let { outputStream ->
1116+
saveCallback.invoke( outputStream )
1117+
outputStream.close()
11611118
}
11621119
}
1163-
} else if(!mSaveAsyncBusy) {
1164-
mBinding.frameView.showSavePhotosIcon(false)
11651120
}
11661121
}
11671122

1168-
private fun saveAsync(fileName: String, mimeType: String, byteArray: ByteArray) {
1169-
mSaveAsyncMQ.add(Triple(fileName, mimeType, byteArray))
1170-
saveAsyncNextItem()
1171-
}
1172-
11731123
private fun saveDng(image: Image, captureResult: TotalCaptureResult) {
11741124
Log.i("TAKE_PHOTO", "DNG: Save starts")
11751125
try {
1176-
val outputStream = ByteArrayOutputStream()
11771126
val dngCreator = DngCreator(mCameraInfo.cameraCharacteristics, captureResult)
11781127
mLocation?.let { dngCreator.setLocation(it) }
11791128
dngCreator.setOrientation(mPhotoExifOrientation)
1180-
dngCreator.writeImage(outputStream, image)
1181-
saveAsync("$mPhotoFileNameBase.dng", "image/x-adobe-dng", outputStream.toByteArray())
1182-
} catch (e: Exception) {
1129+
createAndSave( "$mPhotoFileNameBase.dng", "image/x-adobe-dng" ) { outputStream ->
1130+
dngCreator.writeImage(outputStream, image)
1131+
}
1132+
} catch (e: Exception) {
11831133
e.printStackTrace()
11841134
}
11851135
Log.i("TAKE_PHOTO", "DNG: Save ends")
@@ -1188,12 +1138,12 @@ class CameraActivity : AppCompatActivity() {
11881138
private fun saveJpeg(image: Image) {
11891139
Log.i("TAKE_PHOTO", "JPEG: Save starts")
11901140
try {
1191-
val outputStream = ByteArrayOutputStream()
11921141
val buffer = image.planes[0].buffer
11931142
val bytes = ByteArray(buffer.remaining())
11941143
buffer.get(bytes)
1195-
outputStream.write(bytes)
1196-
saveAsync("$mPhotoFileNameBase.jpg", "image/jpeg", outputStream.toByteArray())
1144+
createAndSave( "$mPhotoFileNameBase.jpg", "image/jpeg" ) { outputStream ->
1145+
outputStream.write(bytes)
1146+
}
11971147
} catch (e: Exception) {
11981148
e.printStackTrace()
11991149
}
@@ -1219,8 +1169,6 @@ class CameraActivity : AppCompatActivity() {
12191169
/** Start taking a photo */
12201170
private fun takePhoto(newFile: Boolean = false, start: Boolean = false) {
12211171
runOnUiThread {
1222-
mBinding.frameView.updateDebugMemInfo()
1223-
12241172
if (start) {
12251173
if (!mSequenceStarted) {
12261174
mPhotoCounter = 0
@@ -1267,41 +1215,24 @@ class CameraActivity : AppCompatActivity() {
12671215
val cameraCaptureSession = mCameraCaptureSession
12681216

12691217
if (takeNewPhoto && null != captureRequestPhoto && null != cameraCaptureSession) {
1270-
var minMem =
1271-
when (settings.takePhotoModes) {
1272-
Settings.PHOTO_TYPE_DNG -> mCameraInfo.estimatedDngSize * 2
1273-
Settings.PHOTO_TYPE_JPEG -> mCameraInfo.estimatedJpegSize
1274-
else -> mCameraInfo.estimatedDngSize * 2 + mCameraInfo.estimatedJpegSize
1275-
}
1276-
minMem = 1 + minMem / (1024 * 1024) //convert to MB
1277-
1278-
if (mSaveAsyncMQ.isNotEmpty() && minMem > getFreeMemInfo()) {
1279-
Log.i("TAKE_PHOTO", "Not enough memory")
1280-
mPhotoTakeMask = PHOTO_TAKE_OUT_OF_MEMORY
1281-
Timer("Out of memory", false).schedule(MEMORY_RETRY_TIMEOUT) {
1282-
mPhotoTakeMask = 0
1283-
takePhoto(true)
1284-
}
1285-
} else {
1286-
Log.i("TAKE_PHOTO", "New photo")
1218+
Log.i("TAKE_PHOTO", "New photo")
12871219

1288-
mPhotoInProgress = true
1220+
mPhotoInProgress = true
12891221

1290-
mPhotoTakeMask = when (settings.takePhotoModes) {
1291-
Settings.PHOTO_TYPE_DNG -> PHOTO_TAKE_DNG or PHOTO_TAKE_COMPLETED
1292-
Settings.PHOTO_TYPE_JPEG -> PHOTO_TAKE_JPEG or PHOTO_TAKE_COMPLETED
1293-
else -> PHOTO_TAKE_JPEG or PHOTO_TAKE_DNG or PHOTO_TAKE_COMPLETED
1294-
}
1222+
mPhotoTakeMask = when (settings.takePhotoModes) {
1223+
Settings.PHOTO_TYPE_DNG -> PHOTO_TAKE_DNG or PHOTO_TAKE_COMPLETED
1224+
Settings.PHOTO_TYPE_JPEG -> PHOTO_TAKE_JPEG or PHOTO_TAKE_COMPLETED
1225+
else -> PHOTO_TAKE_JPEG or PHOTO_TAKE_DNG or PHOTO_TAKE_COMPLETED
1226+
}
12951227

1296-
mPhotoTimestamp = System.currentTimeMillis()
1297-
mPhotoFileNameBase = getPhotoBaseFileName(mPhotoTimestamp)
1228+
mPhotoTimestamp = System.currentTimeMillis()
1229+
mPhotoFileNameBase = getPhotoBaseFileName(mPhotoTimestamp)
12981230

1299-
cameraCaptureSession.capture(
1300-
captureRequestPhoto,
1301-
mCameraCaptureSessionPhotoCaptureCallback,
1302-
getWorkerHandler()
1303-
)
1304-
}
1231+
cameraCaptureSession.capture(
1232+
captureRequestPhoto,
1233+
mCameraCaptureSessionPhotoCaptureCallback,
1234+
getWorkerHandler()
1235+
)
13051236
} else {
13061237
mPhotoInProgress = false
13071238
setupCapturePreviewRequest()

app/src/main/java/com/dan/simplerawcamera/FrameView.kt

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -131,10 +131,6 @@ class FrameView : View {
131131
mSavePhotoErrorIcon.bounds = Rect(PHOTO_ICON_X + PHOTO_ICON_WIDTH, PHOTO_ICON_X, PHOTO_ICON_X + 2 * PHOTO_ICON_WIDTH, PHOTO_ICON_Y + PHOTO_ICON_HEIGHT)
132132

133133
DrawableCompat.setTint(mSavePhotoErrorIcon, Color.RED)
134-
135-
timer(null, false, 1000, 1000) {
136-
updateDebugMemInfo()
137-
}
138134
}
139135

140136
/** Sequence: show the delay until the next sequence photo */
@@ -259,11 +255,6 @@ class FrameView : View {
259255
}
260256
}
261257

262-
fun updateDebugMemInfo() {
263-
val memInfo = CameraActivity.getMemInfo()
264-
setDebugInfo(DEBUG_INFO_MEM, "Mem: ${memInfo.first} MB / ${memInfo.second} MB")
265-
}
266-
267258
@SuppressLint("DrawAllocation", "UseCompatLoadingForDrawables")
268259
override fun onDraw(canvas: Canvas?) {
269260
super.onDraw(canvas)

0 commit comments

Comments
 (0)