Add eye dropper
This commit is contained in:
parent
6c3c7dd193
commit
1dd61c9ab0
|
@ -13,8 +13,8 @@ import android.view.Menu
|
|||
import android.view.MenuItem
|
||||
import android.view.WindowManager
|
||||
import android.webkit.MimeTypeMap
|
||||
import android.widget.ImageView
|
||||
import android.widget.SeekBar
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.print.PrintHelper
|
||||
import com.simplemobiletools.commons.dialogs.ColorPickerDialog
|
||||
import com.simplemobiletools.commons.dialogs.ConfirmationAdvancedDialog
|
||||
|
@ -30,6 +30,7 @@ import com.simplemobiletools.draw.pro.BuildConfig
|
|||
import com.simplemobiletools.draw.pro.R
|
||||
import com.simplemobiletools.draw.pro.dialogs.SaveImageDialog
|
||||
import com.simplemobiletools.draw.pro.extensions.config
|
||||
import com.simplemobiletools.draw.pro.helpers.EyeDropper
|
||||
import com.simplemobiletools.draw.pro.helpers.JPG
|
||||
import com.simplemobiletools.draw.pro.helpers.PNG
|
||||
import com.simplemobiletools.draw.pro.helpers.SVG
|
||||
|
@ -60,10 +61,17 @@ class MainActivity : SimpleActivity(), CanvasListener {
|
|||
private var savedPathsHash = 0L
|
||||
private var lastSavePromptTS = 0L
|
||||
private var isEraserOn = false
|
||||
private var isEyeDropperOn = false
|
||||
private var isImageCaptureIntent = false
|
||||
private var isEditIntent = false
|
||||
private var lastBitmapPath = ""
|
||||
|
||||
private val eyeDropper by lazy {
|
||||
EyeDropper(my_canvas) { selectedColor ->
|
||||
setColor(selectedColor)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_main)
|
||||
|
@ -88,6 +96,7 @@ class MainActivity : SimpleActivity(), CanvasListener {
|
|||
true
|
||||
}
|
||||
redo.setOnClickListener { my_canvas.redo() }
|
||||
eye_dropper.setOnClickListener { eyeDropperClicked() }
|
||||
|
||||
checkIntents()
|
||||
if (!isImageCaptureIntent) {
|
||||
|
@ -184,7 +193,8 @@ class MainActivity : SimpleActivity(), CanvasListener {
|
|||
val faqItems = arrayListOf(
|
||||
FAQItem(R.string.faq_2_title_commons, R.string.faq_2_text_commons),
|
||||
FAQItem(R.string.faq_6_title_commons, R.string.faq_6_text_commons),
|
||||
FAQItem(R.string.faq_7_title_commons, R.string.faq_7_text_commons))
|
||||
FAQItem(R.string.faq_7_title_commons, R.string.faq_7_text_commons)
|
||||
)
|
||||
|
||||
startAboutActivity(R.string.app_name, licenses, BuildConfig.VERSION_NAME, faqItems, false)
|
||||
}
|
||||
|
@ -317,7 +327,7 @@ class MainActivity : SimpleActivity(), CanvasListener {
|
|||
}
|
||||
|
||||
private fun updateEraserState() {
|
||||
eraser.setImageDrawable(resources.getDrawable(if (isEraserOn) R.drawable.ic_eraser_on else R.drawable.ic_eraser_off))
|
||||
eraser.setImageDrawable(ContextCompat.getDrawable(this, if (isEraserOn) R.drawable.ic_eraser_on else R.drawable.ic_eraser_off))
|
||||
my_canvas.toggleEraser(isEraserOn)
|
||||
}
|
||||
|
||||
|
@ -335,6 +345,16 @@ class MainActivity : SimpleActivity(), CanvasListener {
|
|||
}
|
||||
}
|
||||
|
||||
private fun eyeDropperClicked() {
|
||||
isEyeDropperOn = !isEyeDropperOn
|
||||
if (isEyeDropperOn) {
|
||||
eyeDropper.start()
|
||||
} else {
|
||||
eyeDropper.stop()
|
||||
}
|
||||
eye_dropper.setImageDrawable(ContextCompat.getDrawable(this, if (isEyeDropperOn) R.drawable.ic_colorise_off_vector else R.drawable.ic_colorize_vector))
|
||||
}
|
||||
|
||||
private fun confirmImage() {
|
||||
when {
|
||||
isEditIntent -> {
|
||||
|
@ -496,6 +516,7 @@ class MainActivity : SimpleActivity(), CanvasListener {
|
|||
undo.applyColorFilter(contrastColor)
|
||||
eraser.applyColorFilter(contrastColor)
|
||||
redo.applyColorFilter(contrastColor)
|
||||
eye_dropper.applyColorFilter(contrastColor)
|
||||
if (isBlackAndWhiteTheme()) {
|
||||
stroke_width_bar.setColors(0, contrastColor, 0)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
package com.simplemobiletools.draw.pro.helpers
|
||||
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.Color
|
||||
import android.graphics.Matrix
|
||||
import android.graphics.drawable.BitmapDrawable
|
||||
import android.view.View
|
||||
import android.view.View.DRAWING_CACHE_QUALITY_LOW
|
||||
import android.widget.ImageView
|
||||
|
||||
|
||||
// forked from https://github.com/Madrapps/EyeDropper
|
||||
class EyeDropper(private val view: View, private val onColorSelected: ((Int) -> Unit)) {
|
||||
companion object {
|
||||
private const val NO_COLOR = Color.TRANSPARENT
|
||||
private val INVERT_MATRIX = Matrix()
|
||||
}
|
||||
|
||||
private var viewTouchListener = View.OnTouchListener { _, event ->
|
||||
notifyColorSelection(event.x.toInt(), event.y.toInt())
|
||||
true
|
||||
}
|
||||
|
||||
fun start() {
|
||||
enableDrawingCache()
|
||||
view.setOnTouchListener(viewTouchListener)
|
||||
}
|
||||
|
||||
fun stop() {
|
||||
disableDrawingCache()
|
||||
view.setOnTouchListener(null)
|
||||
}
|
||||
|
||||
private fun enableDrawingCache() {
|
||||
if (view.shouldDrawingCacheBeEnabled()) {
|
||||
view.isDrawingCacheEnabled = true
|
||||
view.drawingCacheQuality = DRAWING_CACHE_QUALITY_LOW
|
||||
}
|
||||
}
|
||||
|
||||
private fun disableDrawingCache() {
|
||||
if (view.shouldDrawingCacheBeEnabled()) {
|
||||
view.isDrawingCacheEnabled = false
|
||||
}
|
||||
}
|
||||
|
||||
private fun notifyColorSelection(x: Int, y: Int) {
|
||||
val colorAtPoint = getColorAtPoint(x, y)
|
||||
onColorSelected.invoke(colorAtPoint)
|
||||
}
|
||||
|
||||
private fun getColorAtPoint(x: Int, y: Int): Int {
|
||||
return when (view) {
|
||||
is ImageView -> handleIfImageView(view, x, y)
|
||||
else -> getPixelAtPoint(view.drawingCache, x, y)
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleIfImageView(view: ImageView, x: Int, y: Int): Int {
|
||||
return when (val drawable = view.drawable) {
|
||||
is BitmapDrawable -> {
|
||||
view.imageMatrix.invert(INVERT_MATRIX)
|
||||
val mappedPoints = floatArrayOf(x.toFloat(), y.toFloat())
|
||||
INVERT_MATRIX.mapPoints(mappedPoints)
|
||||
getPixelAtPoint(drawable.bitmap, mappedPoints[0].toInt(), mappedPoints[1].toInt())
|
||||
}
|
||||
else -> {
|
||||
NO_COLOR
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getPixelAtPoint(bitmap: Bitmap, x: Int, y: Int): Int {
|
||||
if (bitmap.isValidCoordinate(x, y)) {
|
||||
return bitmap.getPixel(x, y)
|
||||
}
|
||||
return NO_COLOR
|
||||
}
|
||||
|
||||
private fun Bitmap.isValidCoordinate(x: Int, y: Int): Boolean {
|
||||
return x in 1 until width && y in 1 until height
|
||||
}
|
||||
|
||||
private fun View.shouldDrawingCacheBeEnabled(): Boolean = (this !is ImageView) && !isDrawingCacheEnabled
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M12.126,8.125l1.937,-1.937 3.747,3.747 -1.937,1.938zM20.71,5.63l-2.34,-2.34a1,1 0,0 0,-1.41 0l-1.83,1.83 3.75,3.75L20.71,7a1,1 0,0 0,0 -1.37zM2,5l6.63,6.63L3,17.25V21h3.75l5.63,-5.62L18,21l2,-2L4,3 2,5z"/>
|
||||
</vector>
|
|
@ -0,0 +1,10 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M20.71,5.63l-2.34,-2.34c-0.39,-0.39 -1.02,-0.39 -1.41,0l-3.12,3.12 -1.93,-1.91 -1.41,1.41 1.42,1.42L3,16.25V21h4.75l8.92,-8.92 1.42,1.42 1.41,-1.41 -1.92,-1.92 3.12,-3.12c0.4,-0.4 0.4,-1.03 0.01,-1.42zM6.92,19L5,17.08l8.06,-8.06 1.92,1.92L6.92,19z"/>
|
||||
</vector>
|
|
@ -23,10 +23,19 @@
|
|||
android:id="@+id/eraser"
|
||||
android:layout_width="@dimen/normal_icon_size"
|
||||
android:layout_height="@dimen/normal_icon_size"
|
||||
android:layout_toStartOf="@+id/color_picker"
|
||||
android:layout_toStartOf="@+id/eye_dropper"
|
||||
android:padding="@dimen/normal_margin"
|
||||
android:src="@drawable/ic_eraser_off" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/eye_dropper"
|
||||
android:layout_width="@dimen/normal_icon_size"
|
||||
android:layout_height="@dimen/normal_icon_size"
|
||||
android:layout_toStartOf="@+id/color_picker"
|
||||
android:padding="@dimen/medium_margin"
|
||||
android:src="@drawable/ic_colorize_vector"
|
||||
android:visibility="visible" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/color_picker"
|
||||
android:layout_width="@dimen/normal_icon_size"
|
||||
|
|
Loading…
Reference in New Issue