Skip to content

Commit f43b8b0

Browse files
committed
new apk
1 parent ac7f359 commit f43b8b0

File tree

3 files changed

+132
-82
lines changed

3 files changed

+132
-82
lines changed

app/build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ android {
1111
applicationId "ru.tech.imageresizershrinker"
1212
minSdk 21
1313
targetSdk 33
14-
versionCode 5
15-
versionName "1.1"
14+
versionCode 6
15+
versionName "1.1.1"
1616
}
1717

1818
buildTypes {

app/src/main/java/ru/tech/imageresizershrinker/MainActivity.kt

Lines changed: 64 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,17 @@ import androidx.activity.result.PickVisualMediaRequest
1515
import androidx.activity.result.contract.ActivityResultContracts
1616
import androidx.activity.viewModels
1717
import androidx.compose.animation.*
18-
import androidx.compose.foundation.ExperimentalFoundationApi
19-
import androidx.compose.foundation.Image
20-
import androidx.compose.foundation.background
18+
import androidx.compose.animation.core.tween
19+
import androidx.compose.foundation.*
2120
import androidx.compose.foundation.gestures.detectTapGestures
2221
import androidx.compose.foundation.layout.*
2322
import androidx.compose.foundation.lazy.LazyColumn
23+
import androidx.compose.foundation.lazy.rememberLazyListState
2424
import androidx.compose.foundation.shape.RoundedCornerShape
2525
import androidx.compose.foundation.text.KeyboardOptions
2626
import androidx.compose.material.icons.Icons
2727
import androidx.compose.material.icons.filled.Flip
28+
import androidx.compose.material.icons.filled.History
2829
import androidx.compose.material.icons.filled.RotateLeft
2930
import androidx.compose.material.icons.filled.RotateRight
3031
import androidx.compose.material.icons.outlined.DoorBack
@@ -78,6 +79,8 @@ class MainActivity : ComponentActivity() {
7879
val scope = rememberCoroutineScope()
7980
var showDialog by remember { mutableStateOf(false) }
8081
var showSaveLoading by remember { mutableStateOf(false) }
82+
var showOriginal by remember { mutableStateOf(false) }
83+
val state = rememberLazyListState()
8184

8285
val bitmapInfo = viewModel.bitmapInfo
8386

@@ -123,9 +126,6 @@ class MainActivity : ComponentActivity() {
123126
.fillMaxSize()
124127
.pointerInput(Unit) {
125128
detectTapGestures(
126-
onLongPress = {
127-
128-
},
129129
onTap = {
130130
focus.clearFocus()
131131
}
@@ -185,6 +185,7 @@ class MainActivity : ComponentActivity() {
185185
}
186186
)
187187
LazyColumn(
188+
state = state,
188189
reverseLayout = true,
189190
contentPadding = PaddingValues(
190191
top = WindowInsets.statusBars.asPaddingValues()
@@ -209,14 +210,33 @@ class MainActivity : ComponentActivity() {
209210
val bmp = pair.first
210211
val loading = pair.second
211212
Box {
212-
bmp?.asImageBitmap()?.let {
213-
Image(
214-
bitmap = it,
215-
contentDescription = null,
216-
modifier = Modifier.clip(
217-
RoundedCornerShape(4.dp)
218-
)
219-
)
213+
AnimatedContent(
214+
targetState = showOriginal,
215+
transitionSpec = {
216+
fadeIn(tween(0)) with fadeOut(tween(0))
217+
}
218+
) { showOrig ->
219+
if (showOrig) {
220+
viewModel.bitmap?.asImageBitmap()?.let {
221+
Image(
222+
bitmap = it,
223+
contentDescription = null,
224+
modifier = Modifier.clip(
225+
RoundedCornerShape(4.dp)
226+
)
227+
)
228+
}
229+
} else {
230+
bmp?.asImageBitmap()?.let {
231+
Image(
232+
bitmap = it,
233+
contentDescription = null,
234+
modifier = Modifier.clip(
235+
RoundedCornerShape(4.dp)
236+
)
237+
)
238+
}
239+
}
220240
}
221241
if (loading) {
222242
Box(
@@ -263,6 +283,36 @@ class MainActivity : ComponentActivity() {
263283
) {
264284
Icon(Icons.Default.RotateRight, null)
265285
}
286+
287+
Spacer(Modifier.weight(1f))
288+
289+
Box(
290+
modifier = Modifier
291+
.clip(RoundedCornerShape(12.dp))
292+
.background(MaterialTheme.colorScheme.surfaceVariant)
293+
.pointerInput(Unit) {
294+
detectTapGestures(
295+
onPress = {
296+
state.animateScrollToItem(
297+
0,
298+
10000
299+
)
300+
showOriginal = true
301+
tryAwaitRelease()
302+
showOriginal = false
303+
}
304+
)
305+
}
306+
) {
307+
Icon(
308+
Icons.Default.History,
309+
null,
310+
tint = MaterialTheme.colorScheme.onSurfaceVariant,
311+
modifier = Modifier
312+
.align(Alignment.Center)
313+
.padding(8.dp)
314+
)
315+
}
266316
}
267317
} else if (!viewModel.isLoading) {
268318
Spacer(Modifier.height(60.dp))

app/src/main/java/ru/tech/imageresizershrinker/MainViewModel.kt

Lines changed: 66 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -61,76 +61,76 @@ class MainViewModel : ViewModel() {
6161
bitmapInfo.apply {
6262
if (!isExternalStorageWritable) {
6363
onSuccess(false)
64-
cancel()
65-
}
66-
67-
val ext = if (mime == 1) "webp" else if (mime == 0) "png" else "jpg"
68-
val explicit = resizeType == 0
69-
70-
val tWidth = width.toIntOrNull() ?: bitmap.width
71-
val tHeight = height.toIntOrNull() ?: bitmap.height
72-
73-
val timeStamp: String =
74-
SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(Date())
75-
val name = "ResizedImage$timeStamp.$ext"
76-
val localBitmap = if (explicit) {
77-
Bitmap.createScaledBitmap(
78-
bitmap,
79-
tWidth,
80-
tHeight,
81-
false
82-
)
8364
} else {
84-
bitmap.resizeBitmap(max(tWidth, tHeight))
85-
}.rotate(rotation).flip(isFlipped)
86-
87-
val fos: OutputStream? = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
88-
val resolver: ContentResolver = contentResolver
89-
val contentValues = ContentValues().apply {
90-
put(MediaStore.MediaColumns.DISPLAY_NAME, name)
91-
put(MediaStore.MediaColumns.MIME_TYPE, "image/$ext")
92-
put(MediaStore.MediaColumns.RELATIVE_PATH, "DCIM/ResizedImages")
93-
}
94-
val imageUri =
95-
resolver.insert(
96-
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
97-
contentValues
65+
val ext = if (mime == 1) "webp" else if (mime == 0) "png" else "jpg"
66+
val explicit = resizeType == 0
67+
68+
val tWidth = width.toIntOrNull() ?: bitmap.width
69+
val tHeight = height.toIntOrNull() ?: bitmap.height
70+
71+
val timeStamp: String =
72+
SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(Date())
73+
val name = "ResizedImage$timeStamp.$ext"
74+
val localBitmap = if (explicit) {
75+
Bitmap.createScaledBitmap(
76+
bitmap,
77+
tWidth,
78+
tHeight,
79+
false
9880
)
99-
resolver.openOutputStream(imageUri!!)
100-
} else {
101-
val imagesDir =
102-
"${Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM)}${File.separator}ResizedImages"
103-
val file = File(imagesDir)
104-
if (!file.exists()) {
105-
file.mkdir()
106-
}
107-
val image = File(imagesDir, "$name.$ext")
108-
FileOutputStream(image)
81+
} else {
82+
bitmap.resizeBitmap(max(tWidth, tHeight))
83+
}.rotate(rotation).flip(isFlipped)
84+
85+
val fos: OutputStream? =
86+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
87+
val resolver: ContentResolver = contentResolver
88+
val contentValues = ContentValues().apply {
89+
put(MediaStore.MediaColumns.DISPLAY_NAME, name)
90+
put(MediaStore.MediaColumns.MIME_TYPE, "image/$ext")
91+
put(MediaStore.MediaColumns.RELATIVE_PATH, "DCIM/ResizedImages")
92+
}
93+
val imageUri =
94+
resolver.insert(
95+
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
96+
contentValues
97+
)
98+
resolver.openOutputStream(imageUri!!)
99+
} else {
100+
val imagesDir =
101+
"${Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM)}${File.separator}ResizedImages"
102+
val file = File(imagesDir)
103+
if (!file.exists()) {
104+
file.mkdir()
105+
}
106+
val image = File(imagesDir, "$name.$ext")
107+
FileOutputStream(image)
108+
}
109+
localBitmap.compress(
110+
if (mime == 1) Bitmap.CompressFormat.WEBP else if (mime == 0) Bitmap.CompressFormat.PNG else Bitmap.CompressFormat.JPEG,
111+
quality.toInt(),
112+
fos
113+
)
114+
val out = ByteArrayOutputStream()
115+
localBitmap.compress(
116+
if (mime == 1) Bitmap.CompressFormat.WEBP else if (mime == 0) Bitmap.CompressFormat.PNG else Bitmap.CompressFormat.JPEG,
117+
quality.toInt(), out
118+
)
119+
val decoded =
120+
BitmapFactory.decodeStream(ByteArrayInputStream(out.toByteArray()))
121+
out.flush()
122+
out.close()
123+
fos!!.flush()
124+
fos.close()
125+
126+
_bitmap.value = decoded
127+
_bitmapInfo.value = _bitmapInfo.value.copy(
128+
isFlipped = false,
129+
rotation = 0f
130+
)
131+
onSuccess(true)
109132
}
110-
localBitmap.compress(
111-
if (mime == 1) Bitmap.CompressFormat.WEBP else if (mime == 0) Bitmap.CompressFormat.PNG else Bitmap.CompressFormat.JPEG,
112-
quality.toInt(),
113-
fos
114-
)
115-
val out = ByteArrayOutputStream()
116-
localBitmap.compress(
117-
if (mime == 1) Bitmap.CompressFormat.WEBP else if (mime == 0) Bitmap.CompressFormat.PNG else Bitmap.CompressFormat.JPEG,
118-
quality.toInt(), out
119-
)
120-
val decoded =
121-
BitmapFactory.decodeStream(ByteArrayInputStream(out.toByteArray()))
122-
out.flush()
123-
out.close()
124-
fos!!.flush()
125-
fos.close()
126-
127-
_bitmap.value = decoded
128-
_bitmapInfo.value = _bitmapInfo.value.copy(
129-
isFlipped = false,
130-
rotation = 0f
131-
)
132133
}
133-
onSuccess(true)
134134
}
135135
}
136136
}

0 commit comments

Comments
 (0)