Implemented scaling QR code

This commit is contained in:
dankito 2022-03-13 23:43:57 +01:00
parent f3292e38ae
commit d2dd5389ea
5 changed files with 38 additions and 25 deletions

View File

@ -4,10 +4,33 @@ import com.soywiz.korim.bitmap.Bitmap32
open class EpcQrCode( open class EpcQrCode(
open val bitmap: Bitmap32 bitmap: Bitmap32,
heightAndWidth: Int = DefaultHeightAndWidth
) { ) {
companion object {
const val DefaultHeightAndWidth = 500
}
open var bitmap: Bitmap32 = bitmap // declare before init() method, otherwise application will crash
protected set
open val bytes: ByteArray open val bytes: ByteArray
get() = bitmap.extractBytes() get() = bitmap.extractBytes()
constructor(bitmap: Bitmap32) : this(bitmap, DefaultHeightAndWidth) // convenience constructor for languages that don't support default parameters
init {
scale(heightAndWidth)
}
open fun scale(heightAndWidth: Int) {
this.bitmap = bitmap.scaled(heightAndWidth, heightAndWidth, true)
}
} }

View File

@ -7,12 +7,16 @@ import com.soywiz.korim.qr.QRErrorCorrectLevel
open class EpcQrCodeGenerator { open class EpcQrCodeGenerator {
open fun generateEpcQrCode(param: EpcQrCodeConfig): EpcQrCode { open fun generateEpcQrCode(config: EpcQrCodeConfig): EpcQrCode {
return generateEpcQrCode(config, EpcQrCode.DefaultHeightAndWidth)
}
open fun generateEpcQrCode(config: EpcQrCodeConfig, heightAndWidth: Int = EpcQrCode.DefaultHeightAndWidth): EpcQrCode {
val qrCode = QR(correctLevel = QRErrorCorrectLevel.M) val qrCode = QR(correctLevel = QRErrorCorrectLevel.M)
val qrCodeBitmap = qrCode.msg(generateAsString(param)) val qrCodeBitmap = qrCode.msg(generateAsString(config))
return EpcQrCode(qrCodeBitmap) return EpcQrCode(qrCodeBitmap, heightAndWidth)
} }
open fun generate(param: EpcQrCodeConfig): EpcQrCodeValues { open fun generate(param: EpcQrCodeConfig): EpcQrCodeValues {

View File

@ -42,9 +42,9 @@ class MainActivity : AppCompatActivity() {
private fun generateQrCodeAsync(param: EpcQrCodeConfig, done: (Bitmap) -> Unit) { private fun generateQrCodeAsync(param: EpcQrCodeConfig, done: (Bitmap) -> Unit) {
GlobalScope.launch(Dispatchers.IO) { GlobalScope.launch(Dispatchers.IO) {
val density = resources.displayMetrics.density val density = resources.displayMetrics.density
val config = EncodeToQrCodeConfig((EncodeToQrCodeConfig.DefaultWidth * density).toInt(), (EncodeToQrCodeConfig.DefaultHeight * density).toInt()) val heightAndWidth = (350 * density).toInt()
val epcQrCode = EpcQrCodeGenerator().generateEpcQrCode(param) val epcQrCode = EpcQrCodeGenerator().generateEpcQrCode(param, heightAndWidth)
withContext(Dispatchers.Main) { withContext(Dispatchers.Main) {
done(epcQrCode.androidBitmap) done(epcQrCode.androidBitmap)

View File

@ -1,9 +1,7 @@
package net.codinux.banking.epcqrcode.rest package net.codinux.banking.epcqrcode.rest
import net.codinux.banking.epcqrcode.EpcQrCodeConfig import net.codinux.banking.epcqrcode.EpcQrCodeConfig
import net.codinux.banking.epcqrcode.EncodeToQrCodeConfig
import net.codinux.banking.epcqrcode.EpcQrCodeGenerator import net.codinux.banking.epcqrcode.EpcQrCodeGenerator
import net.codinux.banking.epcqrcode.QrCodeGenerator
import net.codinux.banking.epcqrcode.rest.dto.GenerateEpcQrCodeRequestDto import net.codinux.banking.epcqrcode.rest.dto.GenerateEpcQrCodeRequestDto
import net.codinux.banking.epcqrcode.rest.dto.GenerateEpcQrCodeResponseDto import net.codinux.banking.epcqrcode.rest.dto.GenerateEpcQrCodeResponseDto
import org.slf4j.LoggerFactory import org.slf4j.LoggerFactory
@ -24,15 +22,13 @@ class EpcQrCodeResource {
protected val epcQrCodeGenerator = EpcQrCodeGenerator() protected val epcQrCodeGenerator = EpcQrCodeGenerator()
protected val qrCodeGenerator = QrCodeGenerator()
@POST @POST
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
fun createEpcQrCode(requestDto: GenerateEpcQrCodeRequestDto): Response { fun createEpcQrCode(requestDto: GenerateEpcQrCodeRequestDto): Response {
try { try {
val qrCodeContent = epcQrCodeGenerator.generateAsString(mapToEpcQrCodeConfig(requestDto)) val epcQrCode = epcQrCodeGenerator.generateEpcQrCode(mapToEpcQrCodeConfig(requestDto), requestDto.imageHeightAndWidth)
val qrCodeBytes = qrCodeGenerator.generateQrCode(qrCodeContent, map(requestDto)) val qrCodeBytes = epcQrCode.bytes // TODO: convert to Base64
return Response.ok(GenerateEpcQrCodeResponseDto(qrCodeBytes)) return Response.ok(GenerateEpcQrCodeResponseDto(qrCodeBytes))
.header("Access-Control-Allow-Origin", "*") .header("Access-Control-Allow-Origin", "*")
@ -40,7 +36,7 @@ class EpcQrCodeResource {
} catch (e: Exception) { } catch (e: Exception) {
log.error("Could not create QR code for $requestDto", e) log.error("Could not create QR code for $requestDto", e)
return Response.serverError() return Response.status(Response.Status.INTERNAL_SERVER_ERROR.statusCode, e.localizedMessage) // TODO: it's almost always a bad idea to pass exception message to the outside
.header("Access-Control-Allow-Origin", "*") .header("Access-Control-Allow-Origin", "*")
.build() .build()
} }
@ -57,13 +53,4 @@ class EpcQrCodeResource {
) )
} }
private fun map(dto: GenerateEpcQrCodeRequestDto): EncodeToQrCodeConfig {
return EncodeToQrCodeConfig(
dto.imageWidth,
dto.imageHeight,
dto.imageFormat,
dto.encoding
)
}
} }

View File

@ -1,5 +1,6 @@
package net.codinux.banking.epcqrcode.rest.dto package net.codinux.banking.epcqrcode.rest.dto
import net.codinux.banking.epcqrcode.EpcQrCode
import net.codinux.banking.epcqrcode.EpcQrCodeCharacterSet import net.codinux.banking.epcqrcode.EpcQrCodeCharacterSet
import net.codinux.banking.epcqrcode.ImageFormat import net.codinux.banking.epcqrcode.ImageFormat
@ -18,9 +19,7 @@ class GenerateEpcQrCodeRequestDto {
var noteToUser: String? = null var noteToUser: String? = null
var imageWidth: Int = 500 var imageHeightAndWidth: Int = EpcQrCode.DefaultHeightAndWidth
var imageHeight: Int = 500
var imageFormat: ImageFormat = ImageFormat.PNG var imageFormat: ImageFormat = ImageFormat.PNG