Created
January 25, 2022 10:07
-
-
Save orllewin/0f931e02b9e63a32cf78c530099a2439 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /** | |
| * Calculates 256 values from a curve to drive a Toolkit LookupTable which uses a byte array with length 256 | |
| * eg. for a red channel the zeroth index in the array has value 0 (black), index 255 has value 255 (pure red) | |
| * but... the values returned here are just the ui input mapped to 0 to 255 | |
| * @param curveId - the name of the curve, "RED", "GREEN", "BLUE", "LUMI" | |
| * @return FloatArray with values mapped from the ui in range 0 to 255 | |
| */ | |
| fun getData(curveId: String): FloatArray{ | |
| //The view can have n curves, find the one with the id we want | |
| val curve = curves.find { curve -> | |
| curve.id == curveId | |
| } ?: throw Exception("No curve found with id: $curveId") | |
| val pathMeasure = PathMeasure(curve.path, false) | |
| val sampleCount = 512 | |
| val pathSampleLength = pathMeasure.length/sampleCount | |
| val hyp = sqrt((width.toFloat() * width) + (height * height)) | |
| val outValues = FloatArray(256) | |
| val screenXSampleLength = width/256f | |
| val coords = floatArrayOf(0f, 0f) | |
| repeat(sampleCount){ index -> | |
| pathMeasure.getPosTan(index * pathSampleLength, coords, null) | |
| //For a point on the curve | |
| val pathX = coords[0] | |
| val pathY = coords[1] | |
| //Find nearest concrete (non-fractional) x value for our target values (width/256) | |
| val screenX = pathX - (pathX % (screenXSampleLength.toInt())) | |
| //Figure out which index in our out array that x value is | |
| val screenValuesIndex = max(0f, (screenX/screenXSampleLength)).toInt() | |
| //Raw screen value (bottom of the screen is low value) | |
| val rawValue = height - pathY | |
| //Adjust raw y value as we're not forcing a square view | |
| val mappedRawValue = map(rawValue, 0f, height.toFloat(), 0f, width.toFloat()) | |
| //Output - Input = change the user wants to see | |
| val difference = mappedRawValue - screenX | |
| //LUT range is 0 to 255, max difference possible in the view is half the hypotenuse | |
| val finalValue = map(difference, 0f, hyp/2, 0f, 255.toFloat()) | |
| outValues[min(255, screenValuesIndex)] = finalValue | |
| } | |
| return outValues | |
| } | |
| private fun map(value: Float, aStart: Float, aEnd: Float, bStart: Float, bEnd: Float): Float { | |
| return bStart + (bEnd - bStart) * ((value - aStart) / (aEnd - aStart)) | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment