alexzhirkevich / custom-qr-generator

Android library for creating QR codes with logo, custom shapes, colors, background image. Powered by ZXing
MIT License
173 stars 18 forks source link

How to custom gradient color and select background, logo from devices #42

Closed duyltph25901 closed 1 year ago

duyltph25901 commented 1 year ago
  1. select logo and background from devices
  2. custom color gradient qr
alexzhirkevich commented 1 year ago
  1. Logo is a default Android android.graphics.drawable.Drawable. You just need to resolve it from the file system like anywhere alse

val uri = // your uri resolved from file picker val drawable = if (Build.VERSION.SDK_INT < 28) MediaStore.Images.Media .getBitmap(context.contentResolver, uri.toUri()) .copy(Bitmap.Config.ARGB_8888, false) .toDrawable(context.resources) else ImageDecoder .decodeBitmap(ImageDecoder.createSource(context.contentResolver, uri.toUri())) .copy(Bitmap.Config.ARGB_8888, false) .toDrawable(context.resources)



2. I don't get what do you mean
duyltph25901 commented 1 year ago
  1. I want to like this pic. Can you guide me? image
alexzhirkevich commented 1 year ago

Unfortunately this one was created using deprecated raster method (you can check this color). I dont actualy know if it possible to do that with the new vector method. Probably using a custom shader. You can check how android implements default gradient shaders and try to implement a custom one.

duyltph25901 commented 1 year ago

I found this in your source code:

data class LinearGradient( val colors: List<Pair<Float, Int>>, val orientation: Orientation ) : QrVectorColor {

    enum class Orientation(
        val start: (Float, Float) -> Pair<Float, Float>,
        val end: (Float, Float) -> Pair<Float, Float>
    ) {
        Vertical({ w, _ -> w / 2 to 0f }, { w, h -> w / 2 to h }),
        Horizontal({ _, h -> 0f to h / 2 }, { w, h -> w to h / 2 }),
        LeftDiagonal({ _, _ -> 0f to 0f }, { w, h -> w to h }),
        RightDiagonal({ _, h -> 0f to h }, { w, _ -> w to 0f })
    }

    override fun createPaint(width: Float, height: Float): Paint {
        val (x0, y0) = orientation.start(width, height)
        val (x1, y1) = orientation.end(width, height)
        return Paint().apply {
            shader = android.graphics.LinearGradient(
                x0, y0, x1, y1,
                colors.map { it.second }.toIntArray(),
                colors.map { it.first }.toFloatArray(),
                Shader.TileMode.CLAMP
            )
        }
    }
}

data class RadialGradient( val colors: List<Pair<Float, Int>>, @FloatRange(from = 0.0) val radius: Float = sqrt(2f), ) : QrVectorColor { override fun createPaint(width: Float, height: Float): Paint = Paint().apply { shader = android.graphics.RadialGradient( width / 2, height / 2, maxOf(width, height) / 2 * radius.coerceAtLeast(0f), colors.map { it.second }.toIntArray(), colors.map { it.first }.toFloatArray(), Shader.TileMode.CLAMP ) } }

data class SweepGradient( val colors: List<Pair<Float, Int>> ) : QrVectorColor {

    override fun createPaint(width: Float, height: Float): Paint = Paint().apply {
        shader = android.graphics.SweepGradient(
            width / 2, height / 2,
            colors.map { it.second }.toIntArray(),
            colors.map { it.first }.toFloatArray()
        )
    }
}

but I don't know how to use them, can you give me specific examples in each item

alexzhirkevich commented 1 year ago
QrVectorColor.LinearGradient(
    colors = listOf(
        0f to Color.RED,
        1f to Color.BLUE, 
    ),
    orientation = QrVectorColor.LinearGradient.Orientation.LeftDiagonal
)

Sweep gradient works the same but without orientation parameter

duyltph25901 commented 1 year ago

I did it, thank you so much