Android:如何使用CameraX裁剪图像?

3pvhb19x  于 2022-12-16  发布在  Android
关注(0)|答案(4)|浏览(330)

我想拍一张照片,用Camerax从中心裁剪出一个25X25 DP的正方形。我读到过使用ImageCapture裁剪是可能的,但不幸的是,到目前为止几乎没有类似的例子。

val imageCaptureConfig = ImageCaptureConfig.Builder().apply {
    setTargetAspectRatio(Rational(1, 1))
    setCaptureMode(ImageCapture.CaptureMode.MIN_LATENCY)
}.build()

val imageCapture = ImageCapture(imageCaptureConfig)
btn_take_photo.setOnClickListener {
    imageCapture.takePicture(
        object : ImageCapture.OnImageCapturedListener() {
            override fun onCaptureSuccess(image: ImageProxy?, rotationDegrees: Int) {
                super.onCaptureSuccess(image, rotationDegrees)

                // image manipulation here?
            }
        }
    )
}
mxg2im7a

mxg2im7a1#

您可以使用此功能在捕获图像后裁剪图像:

private fun cropImage(bitmap: Bitmap, frame: View, reference: View): ByteArray {
        val heightOriginal = frame.height
        val widthOriginal = frame.width
        val heightFrame = reference.height
        val widthFrame = reference.width
        val leftFrame = reference.left
        val topFrame = reference.top
        val heightReal = bitmap.height
        val widthReal = bitmap.width
        val widthFinal = widthFrame * widthReal / widthOriginal
        val heightFinal = heightFrame * heightReal / heightOriginal
        val leftFinal = leftFrame * widthReal / widthOriginal
        val topFinal = topFrame * heightReal / heightOriginal
        val bitmapFinal = Bitmap.createBitmap(
            bitmap,
            leftFinal, topFinal, widthFinal, heightFinal
        )
        val stream = ByteArrayOutputStream()
        bitmapFinal.compress(
            Bitmap.CompressFormat.JPEG,
            100,
            stream
        ) //100 is the best quality possibe
        return stream.toByteArray()
    }

裁剪图像,将父视图作为参考帧,将子视图作为最终参考

  • param bitmap要裁剪的图像
  • param frame,其中设置了图像
  • param reference frame以作为裁剪图像的参考
  • return图像已裁剪
vnzz0bqm

vnzz0bqm2#

可以将图像转换为位图,然后进行裁剪。

Bitmap cropImage(Image image, int rotationDegree, int xOffset, int yOffset, int cropWidth, int cropHeight) {
    // 1 - Convert image to Bitmap
    ByteBuffer buffer = image.getPlanes()[0].getBuffer();
    byte[] bytes = new byte[buffer.remaining()];
    buffer.get(bytes);
    Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);

    // 2 - Rotate the Bitmap
    if(rotationDegree != 0) {
        Matrix rotationMatrix = new Matrix();
        rotationMatrix.postRotate(rotationDegree);
        bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), rotationMatrix, true);
    }

    // 3 - Crop the Bitmap
    bitmap = Bitmap.createBitmap(bitmap, xOffset, yOffset, cropWidth, cropHeight);

    return bitmap;
}
63lcw9qa

63lcw9qa3#

您可以从图像中获取平面并手动裁剪它们:

private fun cropByteArray(array : ByteArray, cropRect: Rect): ByteArray {
    val croppedArray = ByteArray(cropRect.width()*cropRect.height())
    val imageWidth = 640
    var i = 0
    array.forEachIndexed { index, byte ->
        val x = index % imageWidth
        val y = index / imageWidth

        if (cropRect.left <= x && x < cropRect.right && cropRect.top <= y && y < cropRect.bottom) {
            croppedArray[i] = byte
            i++
        }
    }
    return croppedArray
}

......

val buffer = image.planes[0].buffer
val imageByteArray = buffer.toByteArray()
val data = cropByteArray(imageByteArray, cropRect)
mqxuamgl

mqxuamgl4#

已测试。简单的裁剪中心位图功能。

fun Bitmap.toSquare(): Bitmap {
    val srcBmp = this
    if (srcBmp.width >= srcBmp.height) {
        return Bitmap.createBitmap(
            srcBmp,
            srcBmp.width / 2 - srcBmp.height / 2,
            0,
            srcBmp.height,
            srcBmp.height
        );
    } else {
        return Bitmap.createBitmap(
            srcBmp,
            0,
            srcBmp.getHeight() / 2 - srcBmp.width / 2,
            srcBmp.width,
            srcBmp.width
        );
    }
}

用法:

val squareBitmap = orgBitmap.toSquare()

相关问题