RedApparat / Fotoapparat

Making Camera for Android more friendly. 📸
Apache License 2.0
3.82k stars 407 forks source link

How to select middle resolution? #377

Open akakist opened 5 years ago

akakist commented 5 years ago

I need to select "middle" resolution - 3Mpix or the nearest.

shedeed1 commented 5 years ago

I modified the resolution selector class to add functionality to select a mid resolution. Hope it helps..

Just add a new Kotlin class and name it CustomResolutionSelector.

import android.util.Log
import io.fotoapparat.parameter.Resolution
import android.R.attr.data

/**
 * @return Selector function which provides a mid resolution
 */
fun getMidRes(): Iterable<Resolution>.() -> Resolution? {

    return { this.mid(Resolution::area) }
}

public inline fun <T, R : Comparable<R>> Iterable<T>.mid(selector: (T) -> R): T? {
    val iterator = iterator()
    val list = iterator.asSequence().toList()
    return list.get(list.size/2 + list.size % 2)
}
Bakalala commented 5 years ago

This worked perfectly ! Thank you @shedeed1 for your amazing contributions

tperraut commented 5 years ago

Another proposition to get the nearest available Resolution of the given one :

val configuration = CameraConfiguration(
    pictureResolution = { nearestBy(Resolution(1280, 720), Resolution::area) }
)

inline fun <T> Iterable<T>.nearestBy(ofValue: T, selector: (T) -> Int): T? {
    val iterator = iterator()
    if (!iterator.hasNext()) return null
    val valueToCompare = selector(ofValue)
    var nearestElem = iterator.next()
    var nearestRange = Math.abs(selector(nearestElem) - valueToCompare)
    var currentRange: Int
    while (iterator.hasNext()) {
        val e = iterator.next()
        val v = selector(e)
        currentRange = Math.abs(v - valueToCompare)
        if (currentRange < nearestRange) {
            nearestElem = e
            nearestRange = currentRange
        }
    }
    return nearestElem
}