Son aktivite 1751943995

MainActivity.kt Ham Playground
1package com.ogletree.composecameraexample
2
3import android.content.ContentResolver
4import android.content.ContentValues
5import android.graphics.Bitmap
6import android.graphics.BitmapFactory
7import android.graphics.Matrix
8import android.net.Uri
9import android.os.Bundle
10import android.provider.MediaStore
11import androidx.activity.ComponentActivity
12import androidx.activity.compose.setContent
13import androidx.activity.result.ActivityResultLauncher
14import androidx.activity.result.contract.ActivityResultContracts
15import androidx.compose.foundation.Image
16import androidx.compose.foundation.background
17import androidx.compose.foundation.clickable
18import androidx.compose.foundation.layout.*
19import androidx.compose.material.MaterialTheme
20import androidx.compose.material.OutlinedButton
21import androidx.compose.material.Surface
22import androidx.compose.material.Text
23import androidx.compose.runtime.*
24import androidx.compose.ui.Alignment
25import androidx.compose.ui.Modifier
26import androidx.compose.ui.graphics.ImageBitmap
27import androidx.compose.ui.graphics.asImageBitmap
28import androidx.compose.ui.text.font.FontWeight
29import androidx.compose.ui.tooling.preview.Preview
30import androidx.compose.ui.unit.dp
31import com.ogletree.composecameraexample.ui.theme.ComposeCameraExampleTheme
32import java.text.SimpleDateFormat
33import java.util.*
34import kotlin.math.min
35
36
37class MainActivity : ComponentActivity() {
38 enum class CameraPermissionStatus { NoPermission, PermissionGranted, PermissionDenied }
39
40 override fun onCreate(savedInstanceState: Bundle?) {
41 super.onCreate(savedInstanceState)
42
43 val cameraPermissionStatusState = mutableStateOf(CameraPermissionStatus.NoPermission)
44 val photoUriState: MutableState<Uri?> = mutableStateOf(null)
45 val hasPhotoState = mutableStateOf(value = false)
46 val resolver = applicationContext.contentResolver
47
48 val requestPermissionLauncher =
49 registerForActivityResult(ActivityResultContracts.RequestPermission()){ isGranted: Boolean ->
50 if (isGranted) {
51 cameraPermissionStatusState.value = CameraPermissionStatus.PermissionGranted
52 } else {
53 cameraPermissionStatusState.value = CameraPermissionStatus.PermissionDenied
54 }
55 }
56
57 val takePhotoLauncher =
58 registerForActivityResult(ActivityResultContracts.TakePicture()) { isSaved ->
59 hasPhotoState.value = isSaved
60 }
61
62 val takePhoto: () -> Unit = {
63 hasPhotoState.value = false
64
65 val values = ContentValues().apply {
66 val title = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(Date())
67 put(MediaStore.Images.Media.TITLE, "Compose Camera Example Image - $title")
68 put(MediaStore.Images.Media.DISPLAY_NAME, title)
69 put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg")
70 put(MediaStore.Images.Media.DATE_TAKEN, System.currentTimeMillis())
71 }
72
73 val uri = resolver.insert(
74 MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
75 values
76 )
77 takePhotoLauncher.launch(uri)
78 photoUriState.value = uri
79
80 }
81
82 // Ideally these would be cached instead of reloaded
83 val getThumbnail: (Uri?) -> ImageBitmap? = { uri ->
84 val targetSize = 256f
85 println("URI is $uri")
86 uri?.let {
87 println("Opening Input Stream")
88 resolver.openInputStream(it)
89 }?.let {
90 BitmapFactory.decodeStream(it)
91 }?.let {
92 val height = it.height.toFloat()
93 val width = it.width.toFloat()
94 val scaleFactor = min(targetSize / height, targetSize / width)
95 Bitmap.createScaledBitmap(it, (scaleFactor * width).toInt() , (scaleFactor * height).toInt(), true)
96 }?.let {
97 val rotation = getImageRotation(resolver, uri)
98 Bitmap.createBitmap(it, 0, 0, it.width, it.height, Matrix().apply { postRotate(rotation.toFloat()) }, true)
99 }?.asImageBitmap()
100
101 }
102
103 val getFullImage: (Uri?) -> ImageBitmap? = { uri ->
104 uri?.let {
105 resolver.openInputStream(it)
106 }?.let {
107 BitmapFactory.decodeStream(it)
108 }?.let {
109 val rotation = getImageRotation(resolver, uri)
110 Bitmap.createBitmap(it, 0, 0, it.width, it.height, Matrix().apply { postRotate(rotation.toFloat()) }, true)
111 }?.asImageBitmap()
112
113 }
114
115 setContent {
116 val cameraPermissionStatus by remember { cameraPermissionStatusState }
117 val hasPhoto by remember { hasPhotoState }
118 var shouldShowFullImage by remember { mutableStateOf(false) }
119 ComposeCameraExampleTheme {
120 Box(modifier = Modifier.fillMaxSize()) {
121 Column(
122 modifier = Modifier.fillMaxSize(),
123 verticalArrangement = Arrangement.Center,
124 horizontalAlignment = Alignment.CenterHorizontally
125 ) {
126 TakePhotoButton(
127 cameraPermissionStatus = cameraPermissionStatus,
128 requestPermissionLauncher = requestPermissionLauncher,
129 takePhoto = takePhoto
130 )
131 if (hasPhoto) {
132 val bitmap = getThumbnail(photoUriState.value)
133 println("Is bitmap null: $bitmap")
134 if (bitmap != null) {
135 Image(
136 bitmap = bitmap,
137 contentDescription = "Thumbnail of Save Photo",
138 modifier = Modifier.clickable {
139 shouldShowFullImage = true
140 }
141 )
142 }
143 }
144 }
145
146 if (shouldShowFullImage && hasPhoto) {
147 val bitmap =getFullImage(photoUriState.value)
148 if (bitmap != null){
149 Box(modifier = Modifier.fillMaxSize().clickable {
150 shouldShowFullImage = false
151 }){
152 Image(
153 bitmap = bitmap,
154 contentDescription = "Full image of Save Photo",
155 modifier = Modifier.align(Alignment.Center)
156 )
157 Surface(
158 modifier = Modifier
159 .background(MaterialTheme.colors.background)
160 .align(Alignment.Center)
161 .padding(8.dp)
162 ) {
163 Text(
164 text = "Click to Close",
165 style = MaterialTheme.typography.h4.copy(
166 fontWeight = FontWeight.ExtraBold
167 )
168 )
169 }
170 }
171
172
173 } else {
174 shouldShowFullImage = false
175 }
176
177 }
178 }
179 }
180 }
181 }
182
183 private fun getImageRotation(resolver: ContentResolver, uri: Uri): Int {
184 val cursor = resolver.query(uri, arrayOf(MediaStore.Images.Media.ORIENTATION), null, null, null)
185 var result = 0
186
187 cursor?.apply {
188 moveToFirst()
189 val index = getColumnIndex(MediaStore.Images.Media.ORIENTATION)
190 result = getInt(index)
191 close()
192 }
193 println("Rotation = $result")
194 return result
195 }
196
197}
198
199@Composable
200fun TakePhotoButton(
201 cameraPermissionStatus: MainActivity.CameraPermissionStatus,
202 requestPermissionLauncher: ActivityResultLauncher<String>,
203 takePhoto: () -> Unit
204) {
205 OutlinedButton(
206 onClick = {
207 when (cameraPermissionStatus) {
208 MainActivity.CameraPermissionStatus.NoPermission ->
209 requestPermissionLauncher.launch(android.Manifest.permission.CAMERA)
210
211 MainActivity.CameraPermissionStatus.PermissionGranted ->
212 takePhoto()
213
214
215 MainActivity.CameraPermissionStatus.PermissionDenied -> {}
216
217 }
218 }
219 ) {
220 when (cameraPermissionStatus) {
221 MainActivity.CameraPermissionStatus.NoPermission ->
222 Text(text = "Request Camera Permissions")
223
224 MainActivity.CameraPermissionStatus.PermissionDenied ->
225 Text(text = "Camera Permissions Have Been Denied")
226
227 MainActivity.CameraPermissionStatus.PermissionGranted ->
228 Text(text = "Take Photo")
229 }
230 }
231}
232
233
234@Composable
235fun Greeting(name: String) {
236 Text(text = "Hello $name!")
237}
238
239@Preview(showBackground = true)
240@Composable
241fun DefaultPreview() {
242 ComposeCameraExampleTheme {
243 Greeting("Android")
244 }
245}