Mercurial > cgi-bin > hgweb.cgi > SimpleResizer
annotate app/src/main/java/com/bartsent/simpleresizer/EditImage.kt @ 6:e8059b166de1
Lanczos works, but is painfully slow.
author | David Barts <n5jrn@me.com> |
---|---|
date | Tue, 16 Feb 2021 17:29:52 -0800 |
parents | 247e03baf77c |
children | 884092efe31a 5626557ac542 |
rev | line source |
---|---|
0
13935000c2d9
Stuff Andriod Studio ignored for some reason.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
1 package com.bartsent.simpleresizer |
13935000c2d9
Stuff Andriod Studio ignored for some reason.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
2 |
2
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
3 import android.content.ContentValues |
1
f26f61a8a9ad
Make the EditImage activity stateful.
David Barts <n5jrn@me.com>
parents:
0
diff
changeset
|
4 import android.graphics.Bitmap |
0
13935000c2d9
Stuff Andriod Studio ignored for some reason.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
5 import android.graphics.BitmapFactory |
2
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
6 import android.graphics.Canvas |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
7 import android.graphics.Matrix |
0
13935000c2d9
Stuff Andriod Studio ignored for some reason.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
8 import android.net.Uri |
13935000c2d9
Stuff Andriod Studio ignored for some reason.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
9 import android.os.Bundle |
2
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
10 import android.os.Environment |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
11 import android.provider.MediaStore |
1
f26f61a8a9ad
Make the EditImage activity stateful.
David Barts <n5jrn@me.com>
parents:
0
diff
changeset
|
12 import android.provider.OpenableColumns |
2
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
13 import android.view.MenuItem |
0
13935000c2d9
Stuff Andriod Studio ignored for some reason.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
14 import android.view.View |
2
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
15 import android.widget.EditText |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
16 import androidx.appcompat.app.AlertDialog |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
17 import androidx.appcompat.app.AppCompatActivity |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
18 import androidx.appcompat.widget.PopupMenu |
0
13935000c2d9
Stuff Andriod Studio ignored for some reason.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
19 import com.bartsent.simpleresizer.databinding.ActivityEditImageBinding |
6
e8059b166de1
Lanczos works, but is painfully slow.
David Barts <n5jrn@me.com>
parents:
5
diff
changeset
|
20 import com.bartsent.simpleresizer.lib.getScaledInstance |
5 | 21 import java.io.File |
2
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
22 import java.io.IOException |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
23 import kotlin.math.roundToInt |
0
13935000c2d9
Stuff Andriod Studio ignored for some reason.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
24 |
13935000c2d9
Stuff Andriod Studio ignored for some reason.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
25 class EditImage : AppCompatActivity() { |
5 | 26 private object State { |
1
f26f61a8a9ad
Make the EditImage activity stateful.
David Barts <n5jrn@me.com>
parents:
0
diff
changeset
|
27 var uri: Uri? = null |
f26f61a8a9ad
Make the EditImage activity stateful.
David Barts <n5jrn@me.com>
parents:
0
diff
changeset
|
28 var bitmap: Bitmap? = null |
f26f61a8a9ad
Make the EditImage activity stateful.
David Barts <n5jrn@me.com>
parents:
0
diff
changeset
|
29 } |
f26f61a8a9ad
Make the EditImage activity stateful.
David Barts <n5jrn@me.com>
parents:
0
diff
changeset
|
30 |
2
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
31 private val STDDIMS = arrayOf<Int>(1600, 1280, 1024, 800, 640, 512, 400, 320).apply { |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
32 sort() |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
33 } |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
34 |
0
13935000c2d9
Stuff Andriod Studio ignored for some reason.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
35 private lateinit var binding: ActivityEditImageBinding |
13935000c2d9
Stuff Andriod Studio ignored for some reason.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
36 |
13935000c2d9
Stuff Andriod Studio ignored for some reason.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
37 override fun onCreate(savedInstanceState: Bundle?) { |
13935000c2d9
Stuff Andriod Studio ignored for some reason.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
38 super.onCreate(savedInstanceState) |
13935000c2d9
Stuff Andriod Studio ignored for some reason.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
39 binding = ActivityEditImageBinding.inflate(layoutInflater) |
13935000c2d9
Stuff Andriod Studio ignored for some reason.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
40 setContentView(binding.root) |
13935000c2d9
Stuff Andriod Studio ignored for some reason.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
41 } |
13935000c2d9
Stuff Andriod Studio ignored for some reason.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
42 |
1
f26f61a8a9ad
Make the EditImage activity stateful.
David Barts <n5jrn@me.com>
parents:
0
diff
changeset
|
43 // Cribbed from: https://stackoverflow.com/questions/5568874/how-to-extract-the-file-name-from-uri-returned-from-intent-action-get-content |
f26f61a8a9ad
Make the EditImage activity stateful.
David Barts <n5jrn@me.com>
parents:
0
diff
changeset
|
44 private fun getFileName(uri: Uri): String? { |
f26f61a8a9ad
Make the EditImage activity stateful.
David Barts <n5jrn@me.com>
parents:
0
diff
changeset
|
45 var result: String? = null |
f26f61a8a9ad
Make the EditImage activity stateful.
David Barts <n5jrn@me.com>
parents:
0
diff
changeset
|
46 if (uri.scheme == "content") { |
f26f61a8a9ad
Make the EditImage activity stateful.
David Barts <n5jrn@me.com>
parents:
0
diff
changeset
|
47 contentResolver.query(uri, null, null, null, null).use { cursor -> |
f26f61a8a9ad
Make the EditImage activity stateful.
David Barts <n5jrn@me.com>
parents:
0
diff
changeset
|
48 if (cursor != null && cursor.moveToFirst()) |
f26f61a8a9ad
Make the EditImage activity stateful.
David Barts <n5jrn@me.com>
parents:
0
diff
changeset
|
49 result = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME)) |
f26f61a8a9ad
Make the EditImage activity stateful.
David Barts <n5jrn@me.com>
parents:
0
diff
changeset
|
50 } |
f26f61a8a9ad
Make the EditImage activity stateful.
David Barts <n5jrn@me.com>
parents:
0
diff
changeset
|
51 } |
f26f61a8a9ad
Make the EditImage activity stateful.
David Barts <n5jrn@me.com>
parents:
0
diff
changeset
|
52 if (result == null) { |
f26f61a8a9ad
Make the EditImage activity stateful.
David Barts <n5jrn@me.com>
parents:
0
diff
changeset
|
53 val uriPath = uri.path |
f26f61a8a9ad
Make the EditImage activity stateful.
David Barts <n5jrn@me.com>
parents:
0
diff
changeset
|
54 result = uriPath?.substring(uriPath.lastIndexOf('/') + 1) |
f26f61a8a9ad
Make the EditImage activity stateful.
David Barts <n5jrn@me.com>
parents:
0
diff
changeset
|
55 } |
f26f61a8a9ad
Make the EditImage activity stateful.
David Barts <n5jrn@me.com>
parents:
0
diff
changeset
|
56 return result |
f26f61a8a9ad
Make the EditImage activity stateful.
David Barts <n5jrn@me.com>
parents:
0
diff
changeset
|
57 } |
f26f61a8a9ad
Make the EditImage activity stateful.
David Barts <n5jrn@me.com>
parents:
0
diff
changeset
|
58 |
2
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
59 private fun showError(message: String): Unit { |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
60 AlertDialog.Builder(this).also { |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
61 it.setMessage(message) |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
62 it.setNeutralButton(R.string.ok_text) { dialog, _ -> |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
63 dialog.dismiss() |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
64 } |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
65 it.setOnDismissListener { |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
66 finish() |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
67 } |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
68 it.create() |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
69 }.show() |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
70 } |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
71 |
0
13935000c2d9
Stuff Andriod Studio ignored for some reason.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
72 override fun onResume() { |
13935000c2d9
Stuff Andriod Studio ignored for some reason.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
73 super.onResume() |
1
f26f61a8a9ad
Make the EditImage activity stateful.
David Barts <n5jrn@me.com>
parents:
0
diff
changeset
|
74 |
f26f61a8a9ad
Make the EditImage activity stateful.
David Barts <n5jrn@me.com>
parents:
0
diff
changeset
|
75 // Read the URI, die if we can't. |
0
13935000c2d9
Stuff Andriod Studio ignored for some reason.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
76 val imageUri = intent?.data |
13935000c2d9
Stuff Andriod Studio ignored for some reason.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
77 if (imageUri == null) { |
2
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
78 showError(getString(R.string.error_no_uri)) |
1
f26f61a8a9ad
Make the EditImage activity stateful.
David Barts <n5jrn@me.com>
parents:
0
diff
changeset
|
79 return |
0
13935000c2d9
Stuff Andriod Studio ignored for some reason.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
80 } |
1
f26f61a8a9ad
Make the EditImage activity stateful.
David Barts <n5jrn@me.com>
parents:
0
diff
changeset
|
81 |
f26f61a8a9ad
Make the EditImage activity stateful.
David Barts <n5jrn@me.com>
parents:
0
diff
changeset
|
82 // Being stateful stops data loss when the phone gets rotated. |
f26f61a8a9ad
Make the EditImage activity stateful.
David Barts <n5jrn@me.com>
parents:
0
diff
changeset
|
83 if (imageUri != State.uri) { |
f26f61a8a9ad
Make the EditImage activity stateful.
David Barts <n5jrn@me.com>
parents:
0
diff
changeset
|
84 State.uri = imageUri |
f26f61a8a9ad
Make the EditImage activity stateful.
David Barts <n5jrn@me.com>
parents:
0
diff
changeset
|
85 State.bitmap = contentResolver.openInputStream(imageUri).use { |
f26f61a8a9ad
Make the EditImage activity stateful.
David Barts <n5jrn@me.com>
parents:
0
diff
changeset
|
86 BitmapFactory.decodeStream(it) |
f26f61a8a9ad
Make the EditImage activity stateful.
David Barts <n5jrn@me.com>
parents:
0
diff
changeset
|
87 } |
0
13935000c2d9
Stuff Andriod Studio ignored for some reason.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
88 } |
1
f26f61a8a9ad
Make the EditImage activity stateful.
David Barts <n5jrn@me.com>
parents:
0
diff
changeset
|
89 if (State.bitmap == null) { |
2
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
90 showError(getString(R.string.error_bad_image)) |
1
f26f61a8a9ad
Make the EditImage activity stateful.
David Barts <n5jrn@me.com>
parents:
0
diff
changeset
|
91 return |
f26f61a8a9ad
Make the EditImage activity stateful.
David Barts <n5jrn@me.com>
parents:
0
diff
changeset
|
92 } |
2
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
93 setImage(State.bitmap!!) |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
94 } |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
95 |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
96 fun setImage(image: Bitmap): Unit { |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
97 binding.imageSize.text = getString(R.string.image_size_text, image.width, image.height) |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
98 binding.image.setImageBitmap(image) |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
99 State.bitmap = image |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
100 } |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
101 |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
102 fun scaleClicked(view: View): Unit { |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
103 val maxSize = State.bitmap!!.run { maxOf(width, height) } |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
104 PopupMenu(this, view).apply { |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
105 menu.run { |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
106 STDDIMS.filter { it < maxSize }.forEach { add(it.toString()) } |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
107 add(getString(R.string.custom_text)) |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
108 add(getString(R.string.cancel_text)) |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
109 } |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
110 setOnMenuItemClickListener(::scaleMenuItemClicked) |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
111 show() |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
112 } |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
113 } |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
114 |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
115 fun scaleMenuItemClicked(item: MenuItem) : Boolean { |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
116 val itString = item.title.toString() |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
117 var itVal = itString.toIntOrNull() |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
118 if (itVal == null) { |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
119 return when (itString) { |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
120 getString(R.string.cancel_text) -> true |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
121 getString(R.string.custom_text) -> { showCustomScaleDialog(); true } |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
122 else -> false |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
123 } |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
124 } |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
125 doScale(itVal) |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
126 return true |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
127 } |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
128 |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
129 private fun copyColorSpace(old: Bitmap, new: Bitmap): Unit { |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
130 if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
131 val oldColorSpace = old.colorSpace |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
132 if (oldColorSpace != null) |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
133 new.setColorSpace(oldColorSpace) |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
134 } |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
135 } |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
136 |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
137 fun doScale(newMax: Int): Unit { |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
138 val oldBitmap = State.bitmap!! |
6
e8059b166de1
Lanczos works, but is painfully slow.
David Barts <n5jrn@me.com>
parents:
5
diff
changeset
|
139 val factor = newMax.toDouble() / maxOf(oldBitmap.width, oldBitmap.height).toDouble() |
2
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
140 if (factor >= 1.0) { |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
141 throw IllegalArgumentException("can only scale down") |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
142 } |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
143 val newBitmap = Bitmap.createBitmap((oldBitmap.width * factor).roundToInt(), (oldBitmap.height * factor).roundToInt(), oldBitmap.config) |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
144 copyColorSpace(oldBitmap, newBitmap) |
6
e8059b166de1
Lanczos works, but is painfully slow.
David Barts <n5jrn@me.com>
parents:
5
diff
changeset
|
145 setImage(oldBitmap.getScaledInstance( |
e8059b166de1
Lanczos works, but is painfully slow.
David Barts <n5jrn@me.com>
parents:
5
diff
changeset
|
146 (oldBitmap.width.toDouble() * factor + 0.5).toInt(), |
e8059b166de1
Lanczos works, but is painfully slow.
David Barts <n5jrn@me.com>
parents:
5
diff
changeset
|
147 (oldBitmap.height.toDouble() * factor + 0.5).toInt())) |
2
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
148 } |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
149 |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
150 // is there any way to remember the last scale value? |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
151 // if so: should we? |
1
f26f61a8a9ad
Make the EditImage activity stateful.
David Barts <n5jrn@me.com>
parents:
0
diff
changeset
|
152 |
2
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
153 fun showCustomScaleDialog(): Unit { |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
154 val image = State.bitmap!! |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
155 val curMaxDim = maxOf(image.width, image.height) |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
156 val dialogView = layoutInflater.inflate(R.layout.dialog_custom_scale, null) |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
157 AlertDialog.Builder(this).also { |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
158 it.setPositiveButton(R.string.ok_text) { dialog, _ -> |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
159 val maxDim = dialogView.findViewById<EditText>(R.id.custom_scale)?.text.toString().toIntOrNull() |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
160 dialog.dismiss() |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
161 if (maxDim == null || maxDim < 8 || maxDim >= curMaxDim) { |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
162 AlertDialog.Builder(this).also { |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
163 it.setMessage(R.string.bad_scale) |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
164 it.setNeutralButton(R.string.ok_text) { dialog, _ -> |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
165 dialog.dismiss() |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
166 } |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
167 it.create() |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
168 }.show() |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
169 } else { |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
170 doScale(maxDim) |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
171 } |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
172 } |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
173 it.setNegativeButton(R.string.cancel_text) { dialog, _ -> |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
174 dialog.dismiss() |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
175 } |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
176 it.setView(dialogView) |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
177 it.create() |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
178 }.show() |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
179 } |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
180 |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
181 fun rotateClicked(view: View): Unit { |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
182 PopupMenu(this, view).apply { |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
183 setOnMenuItemClickListener { |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
184 when(it.itemId) { |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
185 R.id.r_90_cw -> { |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
186 doRotate(90) |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
187 true |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
188 } |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
189 R.id.r_180 -> { |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
190 doRotate(180) |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
191 true |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
192 } |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
193 R.id.r_90_ccw -> { |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
194 doRotate(270) |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
195 true |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
196 } |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
197 R.id.r_cancel -> true |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
198 else -> false |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
199 } |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
200 } |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
201 inflate(R.menu.rotate) |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
202 show() |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
203 } |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
204 } |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
205 |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
206 fun doRotate(deg: Int): Unit { |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
207 val oldBitmap = State.bitmap!! |
5 | 208 if (deg % 90 != 0) { |
209 throw IllegalArgumentException("$deg not a multiple of 90") | |
2
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
210 } |
5 | 211 val (w, h) = if (deg % 180 == 0) Pair(oldBitmap.width, oldBitmap.height) else Pair(oldBitmap.height, oldBitmap.width) |
212 val newBitmap = Bitmap.createBitmap(w, h, oldBitmap.config) | |
2
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
213 copyColorSpace(oldBitmap, newBitmap) |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
214 val rotater = Matrix().apply { |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
215 setRotate(deg.toFloat(), oldBitmap.width.toFloat()/2.0f, oldBitmap.height.toFloat()/2.0f) |
5 | 216 postTranslate((w - oldBitmap.width).toFloat()/2.0f, (h - oldBitmap.height).toFloat()/2.0f) |
2
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
217 } |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
218 Canvas(newBitmap).run { |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
219 drawBitmap(oldBitmap, rotater, null) |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
220 } |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
221 setImage(newBitmap) |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
222 } |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
223 |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
224 fun cancelClicked(view: View): Unit { |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
225 State.uri = null |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
226 State.bitmap = null |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
227 finish() |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
228 } |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
229 |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
230 fun doneClicked(view: View): Unit { |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
231 val contentValues = ContentValues().apply { |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
232 var fileName = getFileName(State.uri!!) |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
233 if (fileName == null) { |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
234 val d = java.util.Date() |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
235 fileName = "IMG_%tY%tm%td_%tH%tM%tS.jpg".format(d, d, d, d, d, d) |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
236 } else { |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
237 val dot = fileName.lastIndexOf('.') |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
238 if (dot == -1) { |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
239 fileName = fileName + ".jpg" |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
240 } else { |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
241 val fileExt = fileName.substring(dot).toLowerCase() |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
242 if (fileExt !in setOf(".jpg", ".jpeg")) |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
243 fileName = fileName.substring(0..dot) + ".jpg" |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
244 } |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
245 } |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
246 put(MediaStore.MediaColumns.DISPLAY_NAME, fileName) |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
247 put(MediaStore.MediaColumns.MIME_TYPE, "image/jpeg") |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
248 if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q) { |
5 | 249 put(MediaStore.MediaColumns.RELATIVE_PATH, |
250 File(Environment.DIRECTORY_PICTURES, getString(R.string.app_name)).getPath()) | |
2
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
251 } |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
252 } |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
253 try { |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
254 val myUri = contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues) |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
255 if (myUri == null) { |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
256 throw IOException(getString(R.string.error_create_mediastore)) |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
257 } |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
258 val stream = contentResolver.openOutputStream(myUri) |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
259 if (stream == null) { |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
260 throw IOException(getString(R.string.error_get_output)) |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
261 } |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
262 // fixme: use quality from settings |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
263 stream.use { |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
264 if (!State.bitmap!!.compress(Bitmap.CompressFormat.JPEG, 85, it)) { |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
265 throw IOException(getString(R.string.error_save_bitmap)) |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
266 } |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
267 } |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
268 } catch (ioe: IOException) { |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
269 showError(ioe.message ?: getString(R.string.error_io)) |
06825e49f7aa
Got it scaling and rotating, needs settings, etc.
David Barts <n5jrn@me.com>
parents:
1
diff
changeset
|
270 } |
5 | 271 finish() |
0
13935000c2d9
Stuff Andriod Studio ignored for some reason.
David Barts <n5jrn@me.com>
parents:
diff
changeset
|
272 } |
1
f26f61a8a9ad
Make the EditImage activity stateful.
David Barts <n5jrn@me.com>
parents:
0
diff
changeset
|
273 } |