https://kotlinlang.org logo
Join the conversationJoin Slack
Channels
100daysofcode
100daysofkotlin
100daysofkotlin-2021
advent-of-code
aem
ai
alexa
algeria
algolialibraries
amsterdam
android
android-architecture
android-databinding
android-studio
androidgithubprojects
androidthings
androidx
androidx-xprocessing
anime
anko
announcements
apollo-kotlin
appintro
arabic
argentina
arkenv
arksemdevteam
armenia
arrow
arrow-contributors
arrow-meta
ass
atlanta
atm17
atrium
austin
australia
austria
awesome-kotlin
ballast
bangladesh
barcelona
bayarea
bazel
beepiz-libraries
belgium
berlin
big-data
books
boston
brazil
brikk
budapest
build
build-tools
bulgaria
bydgoszcz
cambodia
canada
carrat
carrat-dev
carrat-feed
chicago
chile
china
chucker
cincinnati-user-group
cli
clikt
cloudfoundry
cn
cobalt
code-coverage
codeforces
codemash-precompiler
codereview
codingame
codingconventions
coimbatore
collaborations
colombia
colorado
communities
competitive-programming
competitivecoding
compiler
compose
compose-android
compose-desktop
compose-hiring
compose-ios
compose-mp
compose-ui-showcase
compose-wear
compose-web
connect-audit-events
corda
cork
coroutines
couchbase
coursera
croatia
cryptography
cscenter-course-2016
cucumber-bdd
cyprus
czech
dagger
data2viz
databinding
datascience
dckotlin
debugging
decompose
decouple
denmark
deprecated
detekt
detekt-hint
dev-core
dfw
docs-revamped
dokka
domain-driven-design
doodle
dsl
dublin
dutch
eap
eclipse
ecuador
edinburgh
education
effective-kotlin
effectivekotlin
emacs
embedded-kotlin
estatik
event21-community-content
events
exposed
failgood
fb-internal-demo
feed
firebase
flow
fluid-libraries
forkhandles
forum
fosdem
fp-in-kotlin
framework-elide
freenode
french
fritz2
fuchsia
functional
funktionale
gamedev
ge-kotlin
general-advice
georgia
geospatial
german-lang
getting-started
github-workflows-kt
glance
godot-kotlin
google-io
gradle
graphic
graphkool
graphql
graphql-kotlin
graviton-browser
greece
grpc
gsoc
gui
hackathons
hacktoberfest
hamburg
hamkrest
helios
helsinki
hexagon
hibernate
hikari-cp
hire-me
hiring
hongkong
hoplite
http4k
hungary
hyderabad
image-processing
india
indonesia
inkremental
intellij
intellij-plugins
intellij-tricks
internships
introduce-yourself
io
ios
iran
israel
istanbulcoders
italian
jackson-kotlin
jadx
japanese
jasync-sql
java-to-kotlin-refactoring
javadevelopers
javafx
javalin
javascript
jdbi
jhipster-kotlin
jobsworldwide
jpa
jshdq
juul-libraries
jvm-ir-backend-feedback
jxadapter
k2-early-adopters
kaal
kafka
kakao
kalasim
kapt
karachi
karg
karlsruhe
kash_shell
kaskade
kbuild
kdbc
kgen-doc-tools
kgraphql
kinta
klaxon
klock
kloudformation
kmdc
kmm-español
kmongo
knbt
knote
koalaql
koans
kobalt
kobweb
kodein
kodex
kohesive
koin
koin-dev
komapper
kondor-json
kong
kontent
kontributors
korau
korean
korge
korim
korio
korlibs
korte
kotest
kotest-contributors
kotless
kotlick
kotlin-asia
kotlin-beam
kotlin-by-example
kotlin-csv
kotlin-data-storage
kotlin-foundation
kotlin-fuel
kotlin-in-action
kotlin-inject
kotlin-latam
kotlin-logging
kotlin-multiplatform-contest
kotlin-mumbai
kotlin-native
kotlin-pakistan
kotlin-plugin
kotlin-pune
kotlin-roadmap
kotlin-samples
kotlin-sap
kotlin-serbia
kotlin-spark
kotlin-szeged
kotlin-website
kotlinacademy
kotlinbot
kotlinconf
kotlindl
kotlinforbeginners
kotlingforbeginners
kotlinlondon
kotlinmad
kotlinprogrammers
kotlinsu
kotlintest
kotlintest-devs
kotlintlv
kotlinultimatechallenge
kotlinx-datetime
kotlinx-files
kotlinx-html
kotrix
kotson
kovenant
kprompt
kraph
krawler
kroto-plus
ksp
ktcc
ktfmt
ktlint
ktor
ktp
kubed
kug-leads
kug-torino
kvision
kweb
lambdaworld_cadiz
lanark
language-evolution
language-proposals
latvia
leakcanary
leedskotlinusergroup
lets-have-fun
libgdx
libkgd
library-development
linkeddata
lithuania
london
losangeles
lottie
love
lychee
macedonia
machinelearningbawas
madrid
malaysia
mathematics
meetkotlin
memes
meta
metro-detroit
mexico
miami
micronaut
minnesota
minutest
mirror
mockk
moko
moldova
monsterpuzzle
montreal
moonbean
morocco
motionlayout
mpapt
mu
multiplatform
mumbai
munich
mvikotlin
mvrx
myndocs-oauth2-server
naming
navigation-architecture-component
nepal
new-mexico
new-zealand
newname
nigeria
nodejs
norway
npm-publish
nyc
oceania
ohio-kotlin-users
oldenburg
oolong
opensource
orbit-mvi
osgi
otpisani
package-search
pakistan
panamá
pattern-matching
pbandk
pdx
peru
philippines
phoenix
pinoy
pocketgitclient
polish
popkorn
portugal
practical-functional-programming
proguard
prozis-android-backup
pyhsikal
python
python-contributors
quasar
random
re
react
reaktive
realm
realworldkotlin
reductor
reduks
redux
redux-kotlin
refactoring-to-kotlin
reflect
refreshversions
reports
result
rethink
revolver
rhein-main
rocksdb
romania
room
rpi-pico
rsocket
russian
russian_feed
russian-kotlinasfirst
rx
rxjava
san-diego
science
scotland
scrcast
scrimage
script
scripting
seattle
serialization
server
sg-user-group
singapore
skia-wasm-interop-temp
skrape-it
slovak
snake
sofl-user-group
southafrica
spacemacs
spain
spanish
speaking
spek
spin
splitties
spotify-mobius
spring
spring-security
squarelibraries
stackoverflow
stacks
stayhungrystayfoolish
stdlib
stlouis
strife-discord-lib
strikt
students
stuttgart
sudan
swagger-gradle-codegen
swarm
sweden
swing
swiss-user-group
switzerland
talking-kotlin
tallinn
tampa
teamcity
tegal
tempe
tensorflow
terminal
test
testing
testtestest
texas
tgbotapi
thailand
tornadofx
touchlab-tools
training
tricity-kotlin-user-group
trójmiasto
truth
tunisia
turkey
turkiye
twitter-feed
uae
udacityindia
uk
ukrainian
uniflow
unkonf
uruguay
utah
uuid
vancouver
vankotlin
vertx
videos
vienna
vietnam
vim
vkug
vuejs
web-mpp
webassembly
webrtc
wimix_sentry
wwdc
zircon
Powered by Linen
android
  • s

    Slackbot

    09/15/2020, 7:42 AM
    This message was deleted.
    s
    s
    +3
    • 6
    • 10
  • s

    Slackbot

    09/15/2020, 2:16 PM
    This message was deleted.
    d
    • 2
    • 1
  • l

    L.C

    09/15/2020, 3:22 PM
    Hi everyone, I am a Kotlin Flow learner. I am wondering if there is a way to get a ViewModel instance observing the state change in a Flow instance, for instance a new value is added in and ready to be collected? I am felling I might misunderstand the concept of the Flow or miss some key information. Could anyone help me? Thanks in advance!
    d
    z
    • 3
    • 6
  • k

    Ken Maffei

    09/16/2020, 6:07 AM
    I've got the following ViewModel:
    class FundamentalsViewModel: ViewModel() {
    
        var fundamentalsLiveData = MutableLiveData<WrappedResult<PriceDataResponse>>()
        private val repository = FundamentalsRespository()
        private var job: Job? = null
    
        fun getData(symbol: String) {
            if(job == null || job?.isActive == false) {
                fundamentalsLiveData.value = WrappedResult.Loading
                job = viewModelScope.launch(<http://Dispatchers.IO|Dispatchers.IO>) {
                    try {
                        val response = repository.getData(symbol)
                        withContext(Dispatchers.Main) {
                            fundamentalsLiveData.value = WrappedResult.Success(response)
                        }
                    } catch(e: Exception) {
                        withContext(Dispatchers.Main) {
      						fundamentalsLiveData.value = WrappedResult.Failure(e)
                        }
                    }
                }
            }
        }
    }
    And out in the field I'm getting a crash that says this:
    Fatal Exception: java.lang.NullPointerException
    Parameter specified as non-null is null: method kotlin.j0.d.u.p, parameter symbol
    On the line that is:
    fundamentalsLiveData.value = WrappedResult.Loading
    How is it possible that there is ANY NPE here? It makes no sense to me. The WrappedResult is a typical Kotlin sealed class that looks like this:
    sealed class WrappedResult<out T> {
        data class Success<out T: Any>(val data:T) : WrappedResult<T>()
        data class Failure(val error: Throwable) : WrappedResult<Nothing>()
        data class CallFailure(val error: String) : WrappedResult<Nothing>()
        object Loading : WrappedResult<Nothing>()
    }
    Any ideas would be appreciated!
    👍 1
    r
    d
    • 3
    • 4
  • m

    Mahdi Javaheri

    09/16/2020, 7:37 AM
    After migrating to
    Kotlin 1.4.0
    in my Android project (AGP 4.0.1) when i want to build a release apk there are errors in console:
    Warning: class [META-INF/versions/9/module-info.class] unexpectedly contains class [module-info]
    Note: duplicate definition of program class [module-info]
    Note: there were 20 duplicate class definitions.
          (<http://proguard.sourceforge.net/manual/troubleshooting.html#duplicateclass>)
    Warning: there were 21 classes in incorrectly named files.
             You should make sure all file names correspond to their class names.
             The directory hierarchies must correspond to the package hierarchies.
    Anyone has idea to resolve this issue?
    g
    a
    • 3
    • 5
  • d

    Don Phillips

    09/16/2020, 4:47 PM
    So, maybe this is an Android Studio thing, but after upgrading to Kotlin 1.4.0, AS keeps reporting all of the new language features of 1.4 as red squiggly errors, though it compiles just fine. To get around this, we had to explicitly add the following to our build.gradle files
    kotlinOptions {
        languageVersion = "1.4"
    }
    Did those of you using 1.4 have to do this? We're using AS 4.0.1, and we've got the Kotlin 1.4.10-release-Studio4.0-1 plugin installed in AS.
    ✔️ 1
    l
    p
    • 3
    • 59
  • w

    Will Nixon

    09/16/2020, 6:40 PM
    Hi all, wondering whether you all tend to include or exclude tax when you decide on pricing your apps in the app store?
    d
    • 2
    • 1
  • g

    Grant Park

    09/17/2020, 2:49 AM
    For anyone who uses RxJava with Room, do you always error handle your subscriptions?
    g
    k
    • 3
    • 16
  • m

    msfjarvis

    09/17/2020, 12:55 PM
    Hey @Ian Lake, what would be the solution to avoid this happening? https://issuetracker.google.com/issues/168779518 We have an app that creates fragments upon item selection in a RV and AFAIK, calling
    popBackstackImmediate()
    to go back invalidates the fragment and queues it for GC. We're calling
    registerForActivityResult
    in those fragments which eventually causes this overflow if the user stays in the app for long enough because our
    registerForActivityResult
    calls keep incrementing the counter.
    i
    j
    • 3
    • 13
  • m

    Mark

    09/18/2020, 4:09 AM
    Looking for an idiomatic way to perform some long running background Job in the viewmodel such that the work will be paused when the user navigates forward, resumed when the user navigates back to the fragment, and cancelled when the user navigates back from that fragment. I know the viewLifecycleOwner is probably useful for that and that the viewmodel can implement
    LifecycleObserver
    to observe the fragment lifecycle, but what I’m struggling with is a mechanism of how best to use these callbacks to control the work.
    i
    k
    • 3
    • 10
  • o

    OG

    09/18/2020, 6:39 AM
    Hello everyone 👋 I've got a question regarding playing a video full screen portrait. The videos are typically 16:9 or 4:3 aspect ratio, and the videos are recorded in portrait orientation only (this is enforced while recording). Is there a way to play these videos in full screen portrait? That is, I want them to scale and keep aspect ratio intact to match the width/height of the parent container. Something similar to ImageView.ScaleType.CENTER_CROP. Essentially I want the video to fill the entire screen just like how popular apps like instagram and snapchat play video in full screen portrait. I'm using PlayerView from ExoPlayer UI lib and setting height/width to match_parent. PlayerView supports passing a
    resize_mode
    and I believe the default is
    fit
    which translates to
    ImageView.ScaleType.CENTER_INSIDE
    There's also a
    fill
    and
    zoom
    but these don't seem to keep the aspect ratio intact and stretch the video. Anyone have any idea if there is some straightforward combination of settings that I may be missing in order to achieve "center_crop" scaling and get the video to show full screen? The easy alternative is to set a black background for letter boxing and playing the video in it's actual aspect ratio, but the fullscreen is definitely preferred.
    :stackoverflow: 1
    • 1
    • 1
  • j

    Joost Klitsie

    09/18/2020, 9:26 AM
    Hi all! I have a navigation component and I am wondering about transitions while I am changing graphs. The case: I have a graph, which shows a start screen, a login flow and a logged in graph:
    <MainNavGraph>
        <StartFragment>
        <LoginFlowGraph>
             <UsernameFragment>
             <PasswordFragment>
        </LoginFlowGraph>
        <LoggedInGraph>
             <HomeFragment>
        </LoggedInGraph>
    </MainNavGraph>
    My problem is this: when I am logged in, I want to go to the LoggedInGraph and pop everything what is on the backstack:
    if (!navController.currentDestination.isPartOfGraph(R.id.loggedInNavGraph)) {
    	navController.popBackStack(R.id.mainNavGraph, false)
    	navController.navigate(R.id.loggedInNavGraph)
    }
    This works fine. The graph is basically emptied to the root and then the loggedInNavGraph starts. I want to use material transitions during this, On the login flow I use Material shared transition on the X axis
    enterTransition = MaterialSharedAxis(MaterialSharedAxis.X, true)
    returnTransition = MaterialSharedAxis(MaterialSharedAxis.X, false)
    On the HomeFragment I use transitions on the Z axis:
    enterTransition = MaterialSharedAxis(MaterialSharedAxis.Z, true)
    returnTransition = MaterialSharedAxis(MaterialSharedAxis.Z, false)
    However, popping the backstack after the login flow, shows the fragments in the backstack also with the wrong animation... Is it possible to clear the backstack without the fragments from within the backstack to show themselves during the transition?
    i
    • 2
    • 16
  • k

    Ken Maffei

    09/18/2020, 10:20 PM
    Is it necessary to call removeObserver for LiveData in a retained fragment? If so, where and when should this be done?
    a
    • 2
    • 2
  • d

    David Ng

    09/19/2020, 10:55 AM
    Hi all, I'm using GoogleSignInClient for logging the user into my app and I have a backend api to verify the TokenId (Jwt). For subsequent request to my backend api, I uses the same TokenId (Jwt) for authentication. But the token only valid for an hour, what's the recommended way to refresh the token? Do I do a .silentSignIn() to get a new token or should the backend api retrieve a new token and passes it back to the android app?
    r
    • 2
    • 2
  • e

    Eric Ampire [MOD]

    09/19/2020, 3:17 PM
    Hi @zsmb do you have any tips for using the BottomSheetDialogFragment with RainbowCake ?
    👍 1
    z
    • 2
    • 3
  • a

    Andarb

    09/20/2020, 8:11 PM
    Hey. I'm looking to build a Kotlin android app from scratch, something I could use on my portfolio for jobseeking. But with hundreds of thousands of apps already live, how does one choose what kind of app to build? (I've done Udacity's android developer nanodegree (java), so have a few projects on github. I also just finished Antonio Leiva's Kotlin for android online course, hence my current situation)
    a
    s
    t
    • 4
    • 4
  • a

    Ariel Bogdziewicz

    09/21/2020, 10:37 AM
    Hi there! Is there really no way to iterate in Kotlin/Java over graphenes/runes like “👨‍👩‍👧‍👧”?
    A: count = 1, utf16 = 1, unicode scalars = 1 -> ['A']
    €: count = 1, utf16 = 1, unicode scalars = 1 -> ['€']
    ➜: count = 1, utf16 = 1, unicode scalars = 1 -> ['➜']
    ⛳: count = 1, utf16 = 1, unicode scalars = 1 -> ['⛳']
    💩: count = 1, utf16 = 2, unicode scalars = 1 -> ['💩']
    ❤️: count = 1, utf16 = 2, unicode scalars = 2 -> ['❤', '️']
    👨‍👩‍👧‍👦: count = 1, utf16 = 11, unicode scalars = 7 -> ['👨', '‍', '👩', '‍', '👧', '‍', '👦']
    👩‍❤️‍💋‍👩: count = 1, utf16 = 11, unicode scalars = 8 -> ['👩', '‍', '❤', '️', '‍', '💋', '‍', '👩']
    In swift it’s just
    text.count
    and it returns number of characters like “👨‍👩‍👧‍👧”. I tried
    @Test
        public void printBreak() {
            BreakIterator iterator = BreakIterator.getCharacterInstance();
            String[] tests = {
                    "\uD83D\uDC68\u200D\uD83D\uDC69\u200D\uD83D\uDC67\u200D\uD83D\uDC67", // family icon 👨‍👩‍👧‍👧
                    "💩",
                    "€"
            };
            for (String test: tests) {
                iterator.setText(test);
                int index = iterator.first();
                System.out.println("!!!! Start " + test);
                while (index != BreakIterator.DONE) {
                    System.out.println(index);
                    index = iterator.next();
                }
                System.out.println("!!!! End " + test);
            }
        }
    as article https://engineering.linecorp.com/en/blog/the-7-ways-of-counting-characters/ suggested but it also iterates over unicode scalars like
    !!!! Start 👨‍👩‍👧‍👧
    0
    2
    3
    5
    6
    8
    9
    11
    !!!! End 👨‍👩‍👧‍👧
    Is it really so rocket science to iterate over multiple-characters in Android?
    g
    m
    • 3
    • 25
  • k

    Kevin Velasco

    09/21/2020, 5:28 PM
    I wrote a library that allows you to generate a dagger module with a single binding. The idea being that you can use this with Dagger-Hilt and its new
    @UninstallModules
    annotation to replace a single binding in your tests rather than having to manually write those dagger modules yourself https://github.com/JuulLabs/pommel
    👍 2
    r
    • 2
    • 2
  • z

    zoha131

    09/22/2020, 8:27 AM
    How can I get current location? I have tried
    FusedLocationProviderClient
    but unfortunately,
    lastLocation
    does not provide the correct location.
    :stackoverflow: 5
    👍 1
    d
    • 2
    • 2
  • m

    myanmarking

    09/22/2020, 11:27 AM
    hello. Has any1 had problem animating a view with MaterialContainerTransform inside a MotionLayout. For some reason, the animation glitches for me
    :stackoverflow: 1
    :google: 2
    d
    r
    • 3
    • 3
  • k

    KayCee

    09/23/2020, 4:34 AM
    Is this normal to set a nullable properties in Entity and Model class? Should we use non null "val" instead?
    data class DataInputEntity(
        @PrimaryKey(autoGenerate = true)
        @ColumnInfo(name = "id") val id: Int,
        @ColumnInfo(name = "weight") var weight: Float? = null,
        @ColumnInfo(name = "body_fat") val bodyFat: Float? = null,
        @ColumnInfo(name = "stamp") val stamp: String,
        @ColumnInfo(name = "note") val note: String,
        @ColumnInfo(name = "date") val date: Long,
        @ColumnInfo(name = "unit") val weightUnit: Int = TypeUnitWeight.KG.value
    )
    a
    a
    • 3
    • 3
  • a

    Alex

    09/23/2020, 6:25 AM
    For MotionLayout: does someone know how to transition to a State/ConstraintSet instantly (skipping the transition)?
    :stackoverflow: 2
    :google: 3
    d
    m
    e
    • 4
    • 12
  • s

    Spikey Sanju

    09/23/2020, 1:44 PM
    LazyColumnFor items ripple effect is laggy. Is this an issue with compose?
    j
    d
    • 3
    • 3
  • j

    Joao Birk

    09/23/2020, 2:15 PM
    Hi there, I have a question about navigation components and navigating from one bottom sheet to another bottom sheet. On Bottom Sheet A I have an option that does the following:
    dismiss()
    findNavController().navigate(
        R.id.action_bottom_sheet_b,
        bundleOf(...)
    )
    It opens the Bottom Sheet B without any problem, but if I rotate the screen I get a crash:
    java.lang.IllegalStateException
    DialogFragment NUM doesn't exist in the FragmentManager
    If I move the
    dismiss
    after the
    navigate
    , Bottom Sheet B doesnt show up. Seems they are in the same transaction and therefore bottom sheet B gets dismised as well. Here is my navigation.xml
    <dialog
        android:id="@+id/bottom_sheet_a"
        android:name="...BottomSheetA"
        tools:layout="@layout/dialog_bottom_sheet_a">
    
        <action
            android:id="@+id/action_bottom_sheet_b"
            app:destination="@id/bottom_sheet_b"/>
    
    </dialog>
    I found this on stack: https://stackoverflow.com/questions/56647476/why-dialog-does-not-have-a-navcontroller-missing And this: https://issuetracker.google.com/issues/134089818 which seems got resolved in 2.1.0-alpha06 But not sure it's the same issue. I'm using 2.3.0. If I use child
    childFragmentManager.beginTransaction().show()
    to show bottom sheet A instead of
    findNavController().navigate()
    , bottom sheet B gets displayed fine, no crash either. Any ideas of how to fix this?
    :google: 2
    i
    • 2
    • 2
  • a

    ankushg

    09/23/2020, 6:43 PM
    kotlinx.serialization
    recently added the ability to derive a serializer from external classes with properties-only primary constructors: https://github.com/Kotlin/kotlinx.serialization/blob/v1.0.0-RC2/docs/serializers.md#deriving-external-serializer-for-another-kotlin-class-experimental Are there plans to add support for this sort of feature for
    @Parcelize
    ?
    g
    • 2
    • 2
  • c

    Christian

    09/24/2020, 5:30 AM
    Hi, are you guys encounter this problem
    Dependent features configured but no package ID was set.
    I'm trying to set the project as modular as possible. Trying to access the theme from another module which is a
    Composable
    function to my main app module.
    d
    • 2
    • 3
  • r

    rkeazor

    09/24/2020, 6:59 AM
    Anyone ran into issues using kotlin REPL in android studios , WARN: error in opening zip file: /Users/robertkeazor/.gradle/caches/transforms-2/files-2.1/d12ae88f0ff0382cb6bf0028c8ac549d/constraintlayout-2.0.1/AndroidManifest.xml java.util.zip.ZipException: error in opening zip file
    o
    • 2
    • 2
  • d

    Deva Pandiyan

    09/24/2020, 9:24 AM
    I/art: Background partial concurrent mark sweep GC freed 37518(2MB) AllocSpace objects, 7(1348KB) LOS objects, 14% free, 22MB/26MB,
    D/View: [ANR Warning]onMeasure time too long, this =androidx.constraintlayout.widget.ConstraintLayout{b5b15d4 V.E...... ......ID 0,0-720,2380}time =419 ms
    how to reduce my app freezing
    :google: 3
    :stackoverflow: 3
    d
    • 2
    • 1
  • r

    Rechee Jozil

    09/24/2020, 3:42 PM
    For those using Coroutines... Do you have your own custom "global scope". If so, do you cancel it? I'm creating a global scope (includes our thread pool)... But I wonder if I need to cancel it or it's children due to some lifecycle. Only one would be application lifecycle but not sure if it marrers. Thoughts?
    s
    z
    • 3
    • 3
  • i

    Ivann Ruiz

    09/24/2020, 8:05 PM
    Hey 👋 currently need to crop an image at an angle (not sure what the actual name for this is.) Looked for a few libraries out there but they all seem to do rectangular cropping. To illustrate what I'm trying to do consider image
    1)
    below, assume you take a picture of a document at an angle. Assuming there's some kind of edge-detection mechanism, 4 corners appear on each corner of the paper page on the pic. The final result should be a cropped image that has been transformed, namely image
    2)
    . Any help/direction is appreciated 🙌
    :google: 1
    :stackoverflow: 3
    c
    b
    • 3
    • 3
Powered by Linen
Title
i

Ivann Ruiz

09/24/2020, 8:05 PM
Hey 👋 currently need to crop an image at an angle (not sure what the actual name for this is.) Looked for a few libraries out there but they all seem to do rectangular cropping. To illustrate what I'm trying to do consider image
1)
below, assume you take a picture of a document at an angle. Assuming there's some kind of edge-detection mechanism, 4 corners appear on each corner of the paper page on the pic. The final result should be a cropped image that has been transformed, namely image
2)
. Any help/direction is appreciated 🙌
:google: 1
:stackoverflow: 3
c

Casey Brooks

09/24/2020, 8:54 PM
I don’t know of any libraries for this, but what you’re looking to do is called a “perspective transformation”, which might turn up some better search results for you.
👍 1
i

Ivann Ruiz

09/24/2020, 10:01 PM
Ok cool, appreciate the heads up
b

Benjamin Vallet

09/25/2020, 1:02 AM
You need a function like opencv.warpPerspective. That does exactly what you need. You can find many tutorial online about how to use it. For reference, you can download on android the application CamScanner. It does that.
View count: 13