-
Notifications
You must be signed in to change notification settings - Fork 21
Customization
You can easily implement your own shapes and coloring for QR Code in 2 ways: using math formulas or by drawing on canvas. Second way is usually slower and uses a lot of memory but provides more freedom.
For example:
- Using math formulas:
![]() |
object Circle : QrPixelShape {
override fun invoke(
i: Int, j: Int, elementSize: Int, neighbors: Neighbors
): Boolean {
val center = elementSize/2.0
return sqrt((center-i).pow(2) + (center-j).pow(2)) < center
}
}
val options = createQrOptions(1024, .3f) {
shapes {
darkPixel = Circle
}
} |
![]() |
//It is not scannable. Don't create such colorful QR codes
object Pride : QrColor {
override fun invoke(
i: Int, j: Int, width : Int, height : Int
): Int {
return when(6f * j/height){
in 0f..1f -> Color.RED
in 1f..2f-> Color(0xffffa500)
in 2f..3f-> Color.YELLOW
in 3f..4f-> Color(0xff00A300)
in 4f..5f-> Color.BLUE
else -> Color(0xff800080)
}
}
}
val options = createQrOptions(1024) {
colors {
ball = Pride
}
} |
- By drawing on canvas:
![]() |
val options : QrOptions = createQrOptions(1024) {
shapes {
darkPixel = drawShape { canvas, drawPaint, erasePaint ->
val cx = canvas.width/2f
val cy = canvas.height/2f
val radius = minOf(cx,cy)
canvas.drawCircle(cx, cy, radius, drawPaint)
canvas.drawCircle(cx, cy, radius*2/2.5f, erasePaint)
canvas.drawCircle(cx, cy, radius/1.75f, drawPaint)
}
}
} |
drawShape
is a generic function that can be used only inside a shapes
or logo
scope
and only to create properties of QrElementsShapes
or QrLogoShape
.
Usage with other type-parameters will cause an exception.
QrOptions
with larger size!
This can cause shape quality issues.
You can also implement QrCanvasShape
and cast it so necessary shape:
object Ring : QrCanvasShape {
override fun draw(
canvas: Canvas, drawPaint: Paint, erasePaint: Paint
) {
// ...
}
}
val ring : QrPixelShape = Ring
.toShapeModifier(elementSize = 48)
.asPixelShape()
// or automatically determine size with DSL
val ringPixelOptions : QrOptions = createQrOptions(1024){
shapes {
darkPixel = drawShape(Ring::draw)
}
}
![]() |
object CanvasColor : QrCanvasColor {
override fun draw(canvas: Canvas) = with(canvas) {
withRotation(135f, width/2f, height/2f) {
drawRect(-width / 2f, -height / 2f,
1.5f * width, height / 2f,
Paint().apply { color = Color.BLACK }
)
drawRect(-width / 2f, height / 2f,
1.5f * width.toFloat(), 1.5f * height.toFloat(),
Paint().apply { color = Color.DKGRAY }
)
}
}
}
|
Using draw
function inside colors
scope you can colorize your code elements as you want.
It will be converted to a QrColor
.
This is QrOptions
of the code above:
val options = createQrOptions(1024, .2f) {
colors {
dark = QrColor.RadialGradient(
startColor = Color.GRAY,
endColor = Color.BLACK
)
ball = draw(CanvasColor::draw)
frame = draw {
withRotation(
180f, width / 2f,
height / 2f, CanvasColor::draw
)
}
symmetry = true
}
shapes {
darkPixel = QrPixelShape.RoundCorners()
frame = QrFrameShape.RoundCorners(
.25f, outer = false, inner = false
)
}
}