0
0
mirror of https://github.com/markusfisch/BinaryEye.git synced 2024-09-20 03:52:16 +02:00

Improved RenderScript processing

This commit is contained in:
Markus Fisch 2018-05-29 20:58:14 +02:00
parent f6a582e4f7
commit 17f11ea2de
3 changed files with 129 additions and 108 deletions

View File

@ -46,15 +46,15 @@ class CameraActivity : AppCompatActivity() {
private lateinit var vibrator: Vibrator
private lateinit var cameraView: CameraView
private lateinit var zoomBar: SeekBar
private lateinit var preprocessor: Preprocessor
private var decoding = false
private var decodingThread: Thread? = null
private var preprocessor: Preprocessor? = null
private var frameData: ByteArray? = null
private var frameWidth: Int = 0
private var frameHeight: Int = 0
private var frameOrientation: Int = 0
private var odd = false
private var invert = false
private var flash = false
override fun onRequestPermissionsResult(
@ -84,7 +84,6 @@ class CameraActivity : AppCompatActivity() {
preferences = PreferenceManager.getDefaultSharedPreferences(this)
vibrator = getSystemService(Context.VIBRATOR_SERVICE) as Vibrator
preprocessor = Preprocessor(this)
cameraView = findViewById(R.id.camera_view) as CameraView
zoomBar = findViewById(R.id.zoom) as SeekBar
@ -98,7 +97,7 @@ class CameraActivity : AppCompatActivity() {
override fun onDestroy() {
super.onDestroy()
preprocessor.destroy()
preprocessor?.destroy()
saveZoom()
}
@ -364,18 +363,25 @@ class CameraActivity : AppCompatActivity() {
}
private fun decodeFrame(): Result? {
val yuvData = frameData
yuvData ?: return null
preprocessor.process(
yuvData,
frameWidth,
frameHeight,
frameOrientation
)
var fd = frameData
fd ?: return null
if (preprocessor == null) {
preprocessor = Preprocessor(
this,
frameWidth,
frameHeight,
frameOrientation
)
}
var pp = preprocessor
pp ?: return null
pp.process(fd)
invert = invert xor true
return zxing.decode(
yuvData,
frameWidth,
frameHeight
fd,
pp.outWidth,
pp.outHeight,
invert
)
}
@ -385,8 +391,9 @@ class CameraActivity : AppCompatActivity() {
startActivity(
MainActivity.getDecodeIntent(
this, result.text,
result.getBarcodeFormat()
this,
result.text,
result.barcodeFormat
)
)
}

View File

@ -9,7 +9,15 @@ import android.support.v8.renderscript.RenderScript
import android.support.v8.renderscript.ScriptIntrinsicResize
import android.support.v8.renderscript.Type
class Preprocessor(context: Context) {
class Preprocessor(
context: Context,
width: Int,
height: Int,
val orientation: Int
) {
var outWidth = 0
var outHeight = 0
private val rs = RenderScript.create(context)
private val resizeScript = ScriptIntrinsicResize.create(rs)
private val rotatorScript = ScriptC_rotator(rs)
@ -21,6 +29,58 @@ class Preprocessor(context: Context) {
private var rotatedType: Type? = null
private var rotatedAlloc: Allocation? = null
init {
yuvType = Type.createXY(
rs,
Element.U8(rs),
width,
height // use only grayscale part
)
yuvAlloc = Allocation.createTyped(
rs,
yuvType,
Allocation.USAGE_SCRIPT
)
var w = width / 2
var h = height / 2
resizedType = Type.createXY(
rs,
Element.U8(rs),
w,
h
)
resizedAlloc = Allocation.createTyped(
rs,
resizedType,
Allocation.USAGE_SCRIPT
)
if (orientation == 90 || orientation == 270) {
val tmp = w
w = h
h = tmp
}
outWidth = w
outHeight = h
if (orientation != 0) {
rotatedType = Type.createXY(
rs,
Element.U8(rs),
w,
h
)
rotatedAlloc = Allocation.createTyped(
rs,
rotatedType,
Allocation.USAGE_SCRIPT
)
}
}
fun destroy() {
yuvType?.destroy()
yuvType = null
@ -39,79 +99,34 @@ class Preprocessor(context: Context) {
rs.destroy()
}
fun process(
frame: ByteArray,
width: Int,
height: Int,
orientation: Int
) {
if (yuvAlloc == null) {
yuvType = Type.createXY(
rs,
Element.U8(rs),
width,
height * 3 / 2
)
yuvAlloc = Allocation.createTyped(
rs,
yuvType,
Allocation.USAGE_SCRIPT
)
var w = width / 2
var h = height / 2
resizedType = Type.createXY(
rs,
Element.U8(rs),
w,
h
)
resizedAlloc = Allocation.createTyped(
rs,
resizedType,
Allocation.USAGE_SCRIPT
)
if (orientation == 90 || orientation == 270) {
val tmp = w
w = h
h = tmp
}
rotatedType = Type.createXY(
rs,
Element.U8(rs),
w,
h
)
rotatedAlloc = Allocation.createTyped(
rs,
rotatedType,
Allocation.USAGE_SCRIPT
)
}
fun process(frame: ByteArray) {
yuvAlloc?.copyFrom(frame)
resizeScript.setInput(yuvAlloc)
resizeScript.forEach_bicubic(resizedAlloc)
if (orientation == 0) {
val t = resizedType
if (t == null || orientation == 0) {
resizedAlloc?.copyTo(frame)
return
} else {
rotatorScript._inImage = resizedAlloc
rotatorScript._inWidth = t.x
rotatorScript._inHeight = t.y
when (orientation) {
90 -> rotatorScript.forEach_rotate90(
rotatedAlloc,
rotatedAlloc
)
180 -> rotatorScript.forEach_rotate180(
rotatedAlloc,
rotatedAlloc
)
270 -> rotatorScript.forEach_rotate270(
rotatedAlloc,
rotatedAlloc
)
}
rotatedAlloc?.copyTo(frame)
}
rotatorScript._inImage = resizedAlloc
rotatorScript._inWidth = width
rotatorScript._inHeight = height
when (orientation) {
90 -> rotatorScript.forEach_rotate90(rotatedAlloc, rotatedAlloc)
180 -> rotatorScript.forEach_rotate180(rotatedAlloc, rotatedAlloc)
270 -> rotatorScript.forEach_rotate270(rotatedAlloc, rotatedAlloc)
}
rotatedAlloc?.copyTo(frame)
}
}

View File

@ -20,8 +20,6 @@ import java.util.EnumSet
class Zxing {
private val multiFormatReader: MultiFormatReader = MultiFormatReader()
private var odd = false
init {
val decodeFormats = EnumSet.noneOf<BarcodeFormat>(
BarcodeFormat::class.java
@ -56,32 +54,33 @@ class Zxing {
multiFormatReader.setHints(hints)
}
fun decode(yuvData: ByteArray, width: Int, height: Int): Result? {
fun decode(
yuvData: ByteArray,
width: Int,
height: Int,
invert: Boolean = false
): Result? {
val source = PlanarYUVLuminanceSource(
yuvData,
width,
height,
0,
0,
width,
height,
false
)
return decodeLuminanceSource(
PlanarYUVLuminanceSource(
yuvData,
width,
height,
0,
0,
width,
height,
false
)
if (invert) {
source.invert()
} else {
source
}
)
}
private fun decodeLuminanceSource(source: LuminanceSource): Result? {
val bitmap = BinaryBitmap(
HybridBinarizer(
if (odd) {
source
} else {
source.invert()
}
)
)
odd = odd xor true
val bitmap = BinaryBitmap(HybridBinarizer(source))
return try {
multiFormatReader.decodeWithState(bitmap)
} catch (e: ReaderException) {