Skip to content

Commit

Permalink
Add a custom view to display recognised cards
Browse files Browse the repository at this point in the history
  • Loading branch information
tomekdz committed Sep 17, 2018
1 parent e52865a commit 988a6f8
Show file tree
Hide file tree
Showing 13 changed files with 480 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.tooploox.pokerml.app.view

import android.support.v7.widget.RecyclerView
import android.view.View
import android.view.ViewGroup
import com.tooploox.pokerml.domain.entity.Detection

class DetectionsAdapter() : RecyclerView.Adapter<DetectionsAdapter.ViewHolder>() {

var detections: List<Detection>? = null

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
return ViewHolder(PlayingCardView(parent.context))
}

override fun getItemCount(): Int = detections?.size ?: 0

override fun onBindViewHolder(holder: ViewHolder, position: Int) {
(holder.view as PlayingCardView).displayDetection(detections!![position])
}

class ViewHolder(val view: View) : RecyclerView.ViewHolder(view)

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package com.tooploox.pokerml.app.view

import android.content.Context
import android.graphics.drawable.LayerDrawable
import android.support.constraint.ConstraintLayout
import android.support.v4.content.ContextCompat
import android.util.AttributeSet
import android.view.View
import com.tooploox.pokerml.R
import com.tooploox.pokerml.data.tensorflowprocessing.TensorflowImageProcessor
import com.tooploox.pokerml.domain.entity.Card
import com.tooploox.pokerml.domain.entity.Detection
import com.tooploox.pokerml.domain.entity.Rank
import com.tooploox.pokerml.domain.entity.Suit
import kotlinx.android.synthetic.main.view_playing_card.view.*
import kotlin.math.round

class PlayingCardView(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : ConstraintLayout(context, attrs, defStyleAttr) {
init {
View.inflate(context, R.layout.view_playing_card, this)
}

fun displayDetection(detection: Detection) {
val accuracyApprox: Int = round(detection.probability * 100).toInt()
ivCard.setBackgroundResource(AssetMap.cardToDrawable.getValue(detection.card))
pbAccuracy.progress = accuracyApprox
tvAccuracy.text = context.getString(R.string.recognition_accuracy, accuracyApprox)

val oneThirdOfRange = (1 - TensorflowImageProcessor.DETECTION_THRESHOLD) / 3.0

(pbAccuracy.progressDrawable as LayerDrawable).findDrawableByLayerId(android.R.id.progress)
.setTint(ContextCompat.getColor(context, when (detection.probability) {
in (1 - oneThirdOfRange)..1.0 -> R.color.recognition_good
in (1 - (2 * oneThirdOfRange))..(1 - oneThirdOfRange) -> R.color.recognition_satisfactory
else -> R.color.recognition_borderline
}))
}
}

object AssetMap {
val cardToDrawable = mapOf(
Card(Rank.TEN, Suit.CLUBS) to R.drawable.ten_of_clubs,
Card(Rank.TEN, Suit.DIAMONDS) to R.drawable.ten_of_diamonds,
Card(Rank.TEN, Suit.HEARTS) to R.drawable.ten_of_hearts,
Card(Rank.TEN, Suit.SPADES) to R.drawable.ten_of_spades,
Card(Rank.TWO, Suit.CLUBS) to R.drawable.two_of_clubs,
Card(Rank.TWO, Suit.DIAMONDS) to R.drawable.two_of_diamonds,
Card(Rank.TWO, Suit.HEARTS) to R.drawable.two_of_hearts,
Card(Rank.TWO, Suit.SPADES) to R.drawable.two_of_spades,
Card(Rank.THREE, Suit.CLUBS) to R.drawable.three_of_clubs,
Card(Rank.THREE, Suit.DIAMONDS) to R.drawable.three_of_diamonds,
Card(Rank.THREE, Suit.HEARTS) to R.drawable.three_of_hearts,
Card(Rank.THREE, Suit.SPADES) to R.drawable.three_of_spades,
Card(Rank.FOUR, Suit.CLUBS) to R.drawable.four_of_clubs,
Card(Rank.FOUR, Suit.DIAMONDS) to R.drawable.four_of_diamonds,
Card(Rank.FOUR, Suit.HEARTS) to R.drawable.four_of_hearts,
Card(Rank.FOUR, Suit.SPADES) to R.drawable.four_of_spades,
Card(Rank.FIVE, Suit.CLUBS) to R.drawable.five_of_clubs,
Card(Rank.FIVE, Suit.DIAMONDS) to R.drawable.five_of_diamonds,
Card(Rank.FIVE, Suit.HEARTS) to R.drawable.five_of_hearts,
Card(Rank.FIVE, Suit.SPADES) to R.drawable.five_of_spades,
Card(Rank.SIX, Suit.CLUBS) to R.drawable.six_of_clubs,
Card(Rank.SIX, Suit.DIAMONDS) to R.drawable.six_of_diamonds,
Card(Rank.SIX, Suit.HEARTS) to R.drawable.six_of_hearts,
Card(Rank.SIX, Suit.SPADES) to R.drawable.six_of_spades,
Card(Rank.SEVEN, Suit.CLUBS) to R.drawable.seven_of_clubs,
Card(Rank.SEVEN, Suit.DIAMONDS) to R.drawable.seven_of_diamonds,
Card(Rank.SEVEN, Suit.HEARTS) to R.drawable.seven_of_hearts,
Card(Rank.SEVEN, Suit.SPADES) to R.drawable.seven_of_spades,
Card(Rank.EIGHT, Suit.CLUBS) to R.drawable.eight_of_clubs,
Card(Rank.EIGHT, Suit.DIAMONDS) to R.drawable.eight_of_diamonds,
Card(Rank.EIGHT, Suit.HEARTS) to R.drawable.eight_of_hearts,
Card(Rank.EIGHT, Suit.SPADES) to R.drawable.eight_of_spades,
Card(Rank.NINE, Suit.CLUBS) to R.drawable.nine_of_clubs,
Card(Rank.NINE, Suit.DIAMONDS) to R.drawable.nine_of_diamonds,
Card(Rank.NINE, Suit.HEARTS) to R.drawable.nine_of_hearts,
Card(Rank.NINE, Suit.SPADES) to R.drawable.nine_of_spades,
Card(Rank.ACE, Suit.CLUBS) to R.drawable.ace_of_clubs,
Card(Rank.ACE, Suit.DIAMONDS) to R.drawable.ace_of_diamonds,
Card(Rank.ACE, Suit.HEARTS) to R.drawable.ace_of_hearts,
Card(Rank.ACE, Suit.SPADES) to R.drawable.ace_of_spades,
Card(Rank.JACK, Suit.CLUBS) to R.drawable.jack_of_clubs,
Card(Rank.JACK, Suit.DIAMONDS) to R.drawable.jack_of_diamonds,
Card(Rank.JACK, Suit.HEARTS) to R.drawable.jack_of_hearts,
Card(Rank.JACK, Suit.SPADES) to R.drawable.jack_of_spades,
Card(Rank.KING, Suit.CLUBS) to R.drawable.king_of_clubs,
Card(Rank.KING, Suit.DIAMONDS) to R.drawable.king_of_diamonds,
Card(Rank.KING, Suit.HEARTS) to R.drawable.king_of_hearts,
Card(Rank.KING, Suit.SPADES) to R.drawable.king_of_spades,
Card(Rank.QUEEN, Suit.CLUBS) to R.drawable.queen_of_clubs,
Card(Rank.QUEEN, Suit.DIAMONDS) to R.drawable.queen_of_diamonds,
Card(Rank.QUEEN, Suit.HEARTS) to R.drawable.queen_of_hearts,
Card(Rank.QUEEN, Suit.SPADES) to R.drawable.queen_of_spades
)
}
11 changes: 11 additions & 0 deletions android/app/src/main/res/drawable/bottom_bar_background.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">

<solid android:color="@color/white" />

<corners
android:topLeftRadius="10dp"
android:topRightRadius="10dp" />

</shape>
6 changes: 6 additions & 0 deletions android/app/src/main/res/drawable/card_background.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@color/white" />
<corners android:radius="5dp" />
</shape>
24 changes: 24 additions & 0 deletions android/app/src/main/res/drawable/progress_background.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@android:id/background">
<shape>
<corners android:radius="3dp" />
<solid android:color="@color/white" />
</shape>
</item>

<item
android:id="@android:id/progress"
android:bottom="1dp"
android:left="1dp"
android:right="1dp"
android:top="1dp">

<scale android:scaleWidth="100%">
<shape>
<corners android:radius="2dp" />
<solid android:color="@color/white" />
</shape>
</scale>
</item>
</layer-list>
14 changes: 14 additions & 0 deletions android/app/src/main/res/drawable/recognized_background.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">

<gradient
android:angle="0"
android:endColor="@color/genoa"
android:startColor="@color/eucalyptus" />

<corners
android:topLeftRadius="7dp"
android:topRightRadius="7dp" />

</shape>
115 changes: 115 additions & 0 deletions android/app/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".app.photo.MainActivity"
>

<io.fotoapparat.view.CameraView
android:id="@+id/cvPreview"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>

<ImageView
android:id="@+id/ivWatermark"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="@drawable/ic_watermark"
tools:ignore="ContentDescription"
/>

<android.support.constraint.ConstraintLayout
android:id="@+id/bottomBar"
android:layout_width="match_parent"
android:layout_height="110dp"
android:layout_gravity="bottom"
android:background="@drawable/bottom_bar_background"
>

<TextView
android:id="@+id/tvPrompt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/touch_screen_to_take_a_photo"
android:textColor="@color/primary_text"
android:textSize="14sp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
/>

<android.support.constraint.Group
android:id="@+id/gRecognizingProgress"
android:layout_width="0dp"
android:layout_height="0dp"
android:visibility="gone"
app:constraint_referenced_ids="pbRecognizing,tvRecognizing"
/>

<ProgressBar
android:id="@+id/pbRecognizing"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminateTint="@color/yellow_sea"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/tvRecognizing"
app:layout_constraintHorizontal_chainStyle="packed"
/>

<TextView
android:id="@+id/tvRecognizing"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:text="@string/recognizing_image"
android:textColor="@color/primary_text"
android:textSize="14sp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@id/pbRecognizing"
app:layout_constraintEnd_toEndOf="parent"
/>

<android.support.constraint.Group
android:id="@+id/gRecognizingFailed"
android:layout_width="0dp"
android:layout_height="0dp"
android:visibility="gone"
app:constraint_referenced_ids="tvRecognizingFailed,btnTryAgain"
/>

<TextView
android:id="@+id/tvRecognizingFailed"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="@string/sorry_not_able_to_recognize_the_cards"
android:textColor="@color/text_highlight"
android:textSize="14sp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
/>

<Button
android:id="@+id/btnTryAgain"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:backgroundTint="@color/yellow_sea"
android:text="@string/try_again"
android:textColor="@android:color/white"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvRecognizingFailed"
/>

</android.support.constraint.ConstraintLayout>
</FrameLayout>
75 changes: 75 additions & 0 deletions android/app/src/main/res/layout/activity_result.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
>

<ImageView
android:id="@+id/ivSourceImage"
android:layout_width="0dp"
android:layout_height="260dp"
android:scaleType="centerCrop"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
/>


<View
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@drawable/recognized_background"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="190dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
/>

<TextView
android:id="@+id/tvRecognizedTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="21dp"
android:layout_marginTop="17dp"
android:fontFamily="sans-serif"
android:letterSpacing="0.05"
android:text="Recognized cards"
android:textColor="#ffffff"
android:textSize="18sp"
android:textStyle="normal"
app:layout_constraintTop_toBottomOf="@id/ivSourceImage"
app:layout_constraintStart_toStartOf="parent"
/>

<TextView
android:id="@+id/tvRecognizedSubtitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="21dp"
android:layout_marginTop="21dp"
android:fontFamily="sans-serif"
android:letterSpacing="0.05"
android:text="Accuracy level"
android:textAllCaps="true"
android:textColor="#ffffff"
android:textSize="12sp"
app:layout_constraintTop_toBottomOf="@id/tvRecognizedTitle"
app:layout_constraintStart_toStartOf="parent"
/>

<android.support.v7.widget.RecyclerView
android:id="@+id/rvCards"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginLeft="21dp"
android:layout_marginRight="21dp"
android:layout_marginTop="7dp"
app:layout_constraintTop_toBottomOf="@id/tvRecognizedSubtitle"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
/>

</android.support.constraint.ConstraintLayout>
Loading

0 comments on commit 988a6f8

Please sign in to comment.