如何将QR码中的3个方块替换为使用paint android使用zxing自定义QR码?

how to replace 3 squares to circle in QR Code to using paint android to customize QR code using zxing?

我用它作为参考来定制(从正方形到圆形的QR码使用zxing生成它在java所以我试图将它转换为在android[=14=中使用]

我在这里发布从 java 转换为 android

的代码

/*    width = 300,
      height =300,
      quiet zone= 4;
*/
    private Bitmap createQRCode2(String text, int width, int height, int quietZone) throws WriterException, IOException {
        final Map<EncodeHintType, Object> encodingHints = new HashMap<>();
        encodingHints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
        QRCode code = Encoder.encode(text, ErrorCorrectionLevel.H, encodingHints);
        ByteMatrix input = code.getMatrix();
        if (input == null) {
            throw new IllegalStateException();
        }
        int inputWidth = input.getWidth();
        int inputHeight = input.getHeight();
        int qrWidth = inputWidth + (quietZone * 2);
        int qrHeight = inputHeight + (quietZone * 2);
        int outputWidth = Math.max(width, qrWidth);
        int outputHeight = Math.max(height, qrHeight);
        int multiple = Math.min(outputWidth / qrWidth, outputHeight / qrHeight);
        int leftPadding = (outputWidth - (inputWidth * multiple)) / 2;
        int topPadding = (outputHeight - (inputHeight * multiple)) / 2;
        final int FINDER_PATTERN_SIZE = 7;
        final float CIRCLE_SCALE_DOWN_FACTOR = 21f / 30f;
        int circleSize = (int) (multiple * CIRCLE_SCALE_DOWN_FACTOR);

        Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        Paint paint = new Paint();
        paint.setStyle(Paint.Style.FILL);
        paint.setColor(Color.WHITE);
        paint.setAntiAlias(true);
        canvas.drawRect(0, 0, width, height, paint);
        paint.setColor(BLUE);

        for (int inputY = 0, outputY = topPadding; inputY < inputHeight; inputY++, outputY += multiple) {
            for (int inputX = 0, outputX = leftPadding; inputX < inputWidth; inputX++, outputX += multiple) {
                if (input.get(inputX, inputY) == 1) {
                    if (!(inputX <= FINDER_PATTERN_SIZE && inputY <= FINDER_PATTERN_SIZE ||
                            inputX >= inputWidth - FINDER_PATTERN_SIZE && inputY <= FINDER_PATTERN_SIZE ||
                            inputX <= FINDER_PATTERN_SIZE && inputY >= inputHeight - FINDER_PATTERN_SIZE)) {
//                        graphics.fillOval(outputX, outputY, circleSize, circleSize);
                        canvas.drawCircle(outputX, outputY, circleSize, paint);
                    }
                }
            }
        }
        int circleDiameter = (multiple * FINDER_PATTERN_SIZE);
        drawFinderPatternCircleStyle1(canvas, leftPadding, topPadding, circleDiameter, paint);
        drawFinderPatternCircleStyle1(canvas, leftPadding + (inputWidth - FINDER_PATTERN_SIZE) * multiple, topPadding, circleDiameter, paint);
        drawFinderPatternCircleStyle1(canvas, leftPadding, topPadding + (inputHeight - FINDER_PATTERN_SIZE) * multiple, circleDiameter, paint);
        return bitmap;
    }
 private static void drawFinderPatternCircleStyle1(Canvas canvas, int x, int y, int circleDiameter, Paint paint) {
        final int WHITE_CIRCLE_DIAMETER = circleDiameter * 5 / 7;
        final int WHITE_CIRCLE_OFFSET = circleDiameter / 7;
        final int MIDDLE_DOT_DIAMETER = circleDiameter * 3 / 7;
        final int MIDDLE_DOT_OFFSET = circleDiameter * 2 / 7;
/*
       below is  java code  which uses graphics to draw oval in andorid graphics2D and awt is not
       available so I have drawn circle using canvas and paint
*/

//        graphics.setColor(Color.black);
//        graphics.fillOval(x, y, circleDiameter, circleDiameter);
//        graphics.setColor(Color.white);
//        graphics.fillOval(x + WHITE_CIRCLE_OFFSET, y + WHITE_CIRCLE_OFFSET, WHITE_CIRCLE_DIAMETER, WHITE_CIRCLE_DIAMETER);
//        graphics.setColor(Color.black);
//        graphics.fillOval(x + MIDDLE_DOT_OFFSET, y + MIDDLE_DOT_OFFSET, MIDDLE_DOT_DIAMETER, MIDDLE_DOT_DIAMETER);

 /*
       code that i have chnanged from above to covert from java to android
*/
        paint.setColor(Color.BLACK);
        canvas.drawCircle(x, y, circleDiameter, paint);
        paint.setColor(WHITE);
        canvas.drawCircle(x + WHITE_CIRCLE_OFFSET, y + WHITE_CIRCLE_OFFSET, WHITE_CIRCLE_DIAMETER, paint);
        paint.setColor(BLUE);
        canvas.drawCircle(x + MIDDLE_DOT_OFFSET, y + MIDDLE_DOT_OFFSET, MIDDLE_DOT_DIAMETER, paint);
    }

如果我使用 canvas.drawOval() 它需要左上、下、右,我只有 2 个值,所以我有 用过的圈子 内部圆圈是完美绘制的,但三个圆圈显示不正确 link 在这里发布图片 og 结果我得到

删除 WHITE_CIRCLE_OFFSETMIDDLE_DOT_OFFSET

    paint.setColor(Color.BLACK);
    canvas.drawCircle(x + circleDiameter / 1.5f, y + circleDiameter / 1.5f, circleDiameter, paint);
    paint.setColor(WHITE);
    canvas.drawCircle(x + circleDiameter / 1.5f, y + circleDiameter / 1.5f, WHITE_CIRCLE_DIAMETER, paint);
    paint.setColor(BLUE);
    canvas.drawCircle(x + circleDiameter / 1.5f, y + circleDiameter / 1.5f, MIDDLE_DOT_DIAMETER, paint);

这是kotlin

中的完整代码
@Throws(WriterException::class, IOException::class)
private fun roundedQRGenerator() {

    CoroutineScope(IO).launch {

        val hints = hashMapOf<EncodeHintType, Int>().also { it[EncodeHintType.MARGIN] = 1 } // Make the QR code buffer border narrower
        val code = Encoder.encode(data, ErrorCorrectionLevel.H, hints)
        val input = code.matrix ?: throw java.lang.IllegalStateException()

        val width = 900
        val height = 900
        val quietZone = 2

        val inputWidth = input.width
        val inputHeight = input.height
        val qrWidth = inputWidth + quietZone * 2
        val qrHeight = inputHeight + quietZone * 2
        val outputWidth = width.coerceAtLeast(qrWidth)
        val outputHeight = height.coerceAtLeast(qrHeight)
        val multiple = (outputWidth / qrWidth).coerceAtMost(outputHeight / qrHeight)
        val leftPadding = (outputWidth - inputWidth * multiple) / 2
        val topPadding = (outputHeight - inputHeight * multiple) / 2
        val FINDER_PATTERN_SIZE = 7
        val CIRCLE_SCALE_DOWN_FACTOR = 21f / 30f
        val circleSize = (multiple * CIRCLE_SCALE_DOWN_FACTOR).toInt()

        val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
        val canvas = Canvas(bitmap)
        val paint = Paint()
        paint.style = Paint.Style.FILL
        paint.color = WHITE
        paint.isAntiAlias = true
        canvas.drawRect(0f, 0f, width.toFloat(), height.toFloat(), paint)
        var color = BLACK
        val background: Drawable = binding.roundedBgSetter.background
        if (background is ColorDrawable) {
            color = background.color
        }
        paint.color = color

        var inputY = 0
        var outputY = topPadding
        while (inputY < inputHeight) {
            var inputX = 0
            var outputX = leftPadding
            while (inputX < inputWidth) {
                if (input[inputX, inputY].toInt() == 1) {
                    if (!(inputX <= FINDER_PATTERN_SIZE && inputY <= FINDER_PATTERN_SIZE || inputX >= inputWidth - FINDER_PATTERN_SIZE && inputY <= FINDER_PATTERN_SIZE || inputX <= FINDER_PATTERN_SIZE && inputY >= inputHeight - FINDER_PATTERN_SIZE)) {
                        canvas.drawCircle(
                            outputX.toFloat(),
                            outputY.toFloat(),
                            circleSize * 0.6f,
                            paint
                        )
                    }
                }
                inputX++
                outputX += multiple
            }
            inputY++
            outputY += multiple
        }

        val circleDiameter = multiple * FINDER_PATTERN_SIZE / 1.8f
        drawFinderPatternCircleStyle1(canvas, leftPadding, topPadding, circleDiameter, paint)
        drawFinderPatternCircleStyle1(
            canvas,
            leftPadding + circleSize + (inputWidth - FINDER_PATTERN_SIZE) * multiple,
            topPadding,
            circleDiameter,
            paint
        )
        //        drawFinderPatternCircleStyle1(canvas, leftPadding*2-4, ((topPadding*2) + (inputHeight - FINDER_PATTERN_SIZE) * multiple)-8, circleDiameter, paint);
        drawFinderPatternCircleStyle1(
            canvas,
            leftPadding,
            topPadding + circleSize + (inputHeight - FINDER_PATTERN_SIZE) * multiple,
            circleDiameter,
            paint
        )

        withContext(Main){
            binding.qr.setImageBitmap(bitmap)
        }

    }


}

private fun drawFinderPatternCircleStyle1(
    canvas: Canvas,
    x: Int,
    y: Int,
    circleDiameter: Float,
    paint: Paint
) {
    val WHITE_CIRCLE_DIAMETER = circleDiameter * 5 / 7
    val MIDDLE_DOT_DIAMETER = circleDiameter * 3 / 7

    var color = BLACK
    val background: Drawable = binding.roundedBgSetter.background
    if (background is ColorDrawable) {
        color = background.color
    }
    paint.color = color
    canvas.drawCircle(
        x + circleDiameter / 1.5f,
        y + circleDiameter / 1.5f,
        circleDiameter,
        paint
    )
    paint.color = WHITE
    canvas.drawCircle(
        x + circleDiameter / 1.5f,
        y + circleDiameter / 1.5f,
        WHITE_CIRCLE_DIAMETER,
        paint
    )
    paint.color = color
    canvas.drawCircle(
        x + circleDiameter / 1.5f,
        y + circleDiameter / 1.5f,
        MIDDLE_DOT_DIAMETER,
        paint
    )

}