mirror of https://github.com/status-im/qzxing.git
Added new implementation of QrCode encoding.
It is backward compatible with the version that was active till now, though, it also enables an advanced operation for configuring options during encoding.
This commit is contained in:
parent
b9823b7d7f
commit
bec02cb83e
|
@ -3,11 +3,20 @@ import QtQuick.Controls 2.0
|
|||
import QtQuick.Layouts 1.3
|
||||
|
||||
ApplicationWindow {
|
||||
id: mainWindow
|
||||
visible: true
|
||||
width: 640
|
||||
height: 480
|
||||
|
||||
minimumWidth: formatGroupBox.width +
|
||||
errorCorrectionlevelGroupBox.width +
|
||||
sizeGroupBox.width +
|
||||
6 * advancedOptions.spacing
|
||||
|
||||
property bool isAdvancedOptionsEnabled: advancedSwitch.position;
|
||||
|
||||
ColumnLayout {
|
||||
id: mainLayout
|
||||
anchors {
|
||||
fill: parent
|
||||
margins: 10
|
||||
|
@ -18,17 +27,110 @@ ApplicationWindow {
|
|||
selectByMouse: true
|
||||
text: "Hello world!"
|
||||
}
|
||||
GroupBox {
|
||||
|
||||
Row {
|
||||
Layout.fillWidth: true
|
||||
|
||||
Label {
|
||||
id: resultLabel
|
||||
text: "Result barcode image"
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
height: 1
|
||||
width: parent.width - resultLabel.width - advancedSwitch.width
|
||||
}
|
||||
|
||||
Switch {
|
||||
id: advancedSwitch
|
||||
text: "Advanced"
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
}
|
||||
|
||||
Row {
|
||||
id: advancedOptions
|
||||
Layout.fillWidth: true
|
||||
visible: mainWindow.isAdvancedOptionsEnabled
|
||||
clip: true
|
||||
|
||||
spacing: 5
|
||||
|
||||
GroupBox {
|
||||
id: formatGroupBox
|
||||
title: "Format"
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
ComboBox {
|
||||
id: formatCombo
|
||||
model: ["qrcode"]
|
||||
}
|
||||
}
|
||||
|
||||
GroupBox {
|
||||
id: errorCorrectionlevelGroupBox
|
||||
title: "Error Correction Level"
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
ComboBox {
|
||||
id: errorCorrectionlevelCombo
|
||||
model: ["L", "M", "Q", "H"]
|
||||
}
|
||||
}
|
||||
|
||||
GroupBox {
|
||||
id: sizeGroupBox
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
title: "Size"
|
||||
GridLayout {
|
||||
RadioButton {
|
||||
id: radioButtonSize120
|
||||
text: "120x120"
|
||||
}
|
||||
RadioButton {
|
||||
id: radioButtonSize240
|
||||
checked: true
|
||||
text: "240x240"
|
||||
}
|
||||
RadioButton {
|
||||
id: radioButtonSize320
|
||||
text: "320x320"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
title: "Result barcode image"
|
||||
border.width: 1
|
||||
border.color: "#bdbebf"
|
||||
clip: true
|
||||
|
||||
Image{
|
||||
id:resultImage
|
||||
anchors.centerIn: parent
|
||||
source: "image://QZXing/qrcode/" + inputField.text
|
||||
|
||||
source: mainLayout.getImageRequestString()
|
||||
cache: false;
|
||||
}
|
||||
}
|
||||
|
||||
function getImageRequestString() {
|
||||
if(mainWindow.isAdvancedOptionsEnabled) {
|
||||
var width;
|
||||
var height;
|
||||
if (radioButtonSize120.checked) {width = "120"; height = "120"}
|
||||
else if (radioButtonSize240.checked) {width = "240"; height = "240"}
|
||||
else if (radioButtonSize320.checked) {width = "320"; height = "320"}
|
||||
|
||||
return "image://QZXing/encode/" + inputField.text +
|
||||
"?width="+width+
|
||||
"&height="+height+
|
||||
"&corretionLevel=" + errorCorrectionlevelCombo.currentText +
|
||||
"&format=" + formatCombo.currentText
|
||||
}
|
||||
else
|
||||
return "image://QZXing/encode/" + inputField.text;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -490,7 +490,8 @@ QString QZXing::decodeSubImageQML(const QUrl &imageUrl,
|
|||
|
||||
QImage QZXing::encodeData(const QString& data,
|
||||
const EncoderFormat encoderFormat,
|
||||
const QSize encoderImageSize)
|
||||
const QSize encoderImageSize,
|
||||
const EncodeErrorCorrectionLevel errorCorrectionLevel)
|
||||
{
|
||||
QImage image;
|
||||
|
||||
|
@ -498,7 +499,16 @@ QImage QZXing::encodeData(const QString& data,
|
|||
switch (encoderFormat) {
|
||||
case EncoderFormat_QR_CODE:
|
||||
{
|
||||
Ref<qrcode::QRCode> barcode = qrcode::Encoder::encode(data.toStdString(), qrcode::ErrorCorrectionLevel::L );
|
||||
Ref<qrcode::QRCode> barcode = qrcode::Encoder::encode(
|
||||
data.toStdString(),
|
||||
errorCorrectionLevel == EncodeErrorCorrectionLevel_H ?
|
||||
qrcode::ErrorCorrectionLevel::H :
|
||||
(errorCorrectionLevel == EncodeErrorCorrectionLevel_Q ?
|
||||
qrcode::ErrorCorrectionLevel::Q :
|
||||
(errorCorrectionLevel == EncodeErrorCorrectionLevel_M ?
|
||||
qrcode::ErrorCorrectionLevel::M :
|
||||
qrcode::ErrorCorrectionLevel::L)));
|
||||
|
||||
Ref<qrcode::ByteMatrix> bytesRef = barcode->getMatrix();
|
||||
const std::vector< std::vector <zxing::byte> >& bytes = bytesRef->getArray();
|
||||
image = QImage(bytesRef->getWidth(), bytesRef->getHeight(), QImage::Format_ARGB32);
|
||||
|
@ -508,7 +518,7 @@ QImage QZXing::encodeData(const QString& data,
|
|||
qRgb(0,0,0) :
|
||||
qRgb(255,255,255));
|
||||
|
||||
image = image.scaled(240, 240);
|
||||
image = image.scaled(encoderImageSize);
|
||||
break;
|
||||
}
|
||||
case EncoderFormat_INVALID:
|
||||
|
|
11
src/QZXing.h
11
src/QZXing.h
|
@ -84,6 +84,13 @@ public:
|
|||
EncoderFormat_QR_CODE
|
||||
};
|
||||
|
||||
enum EncodeErrorCorrectionLevel {
|
||||
EncodeErrorCorrectionLevel_L = 0,
|
||||
EncodeErrorCorrectionLevel_M,
|
||||
EncodeErrorCorrectionLevel_Q,
|
||||
EncodeErrorCorrectionLevel_H
|
||||
};
|
||||
|
||||
QZXing(QObject *parent = NULL);
|
||||
~QZXing();
|
||||
|
||||
|
@ -160,8 +167,8 @@ public slots:
|
|||
*/
|
||||
static QImage encodeData(const QString& data,
|
||||
const EncoderFormat encoderFormat = EncoderFormat_QR_CODE,
|
||||
const QSize encoderImageSize = QSize(240, 240)/*,
|
||||
const errorcorrectionleve*/);
|
||||
const QSize encoderImageSize = QSize(240, 240),
|
||||
const EncodeErrorCorrectionLevel errorCorrectionLevel = EncodeErrorCorrectionLevel_L);
|
||||
|
||||
/**
|
||||
* Get the prossecing time in millisecond of the last decode operation.
|
||||
|
|
|
@ -11,23 +11,68 @@ QImage QZXingImageProvider::requestImage(const QString &id, QSize *size, const Q
|
|||
{
|
||||
int slashIndex = id.indexOf('/');
|
||||
if (slashIndex == -1) {
|
||||
qWarning() << "Can't parse url" << id << ". Usage is <format>/<data>";
|
||||
qWarning() << "Can't parse url" << id << ". Usage is encode?<format>/<data>";
|
||||
return QImage();
|
||||
}
|
||||
|
||||
QUrl formatUrl = id.left(slashIndex);
|
||||
QString encodeFormat = formatUrl.path();
|
||||
if (encodeFormat != "qrcode") {
|
||||
qWarning() << "Encoding format" << encodeFormat << "is not supported. Only qrcode is supported";
|
||||
//Detect operation (ex. encode)
|
||||
QString operationName = id.left(slashIndex);
|
||||
if(operationName != "encode")
|
||||
{
|
||||
qWarning() << "Operation not supported: " << operationName;
|
||||
return QImage();
|
||||
}
|
||||
|
||||
QList<QPair<QString, QString>> encodeOptions = QUrlQuery(formatUrl).queryItems();
|
||||
Q_UNUSED(encodeOptions)
|
||||
int optionAreaIndex = id.lastIndexOf('?');
|
||||
|
||||
QString data = id.mid(slashIndex + 1);
|
||||
QString data;
|
||||
QImage result;
|
||||
if(optionAreaIndex >= 0)
|
||||
{
|
||||
int startOfDataIndex = slashIndex + 1;
|
||||
data = id.mid(startOfDataIndex, optionAreaIndex - (startOfDataIndex));
|
||||
|
||||
//The dummy option has been added due to a bug(?) of QUrlQuery
|
||||
// it could not recognize the first key-value pair provided
|
||||
QUrlQuery optionQuery("options?dummy=&" + id.mid(optionAreaIndex + 1));
|
||||
|
||||
QString width = optionQuery.queryItemValue("width");
|
||||
QString height = optionQuery.queryItemValue("height");
|
||||
QString corretionLevel = optionQuery.queryItemValue("corretionLevel");
|
||||
QString format = optionQuery.queryItemValue("format");
|
||||
|
||||
if(format != "qrcode")
|
||||
{
|
||||
qWarning() << "Format not supported: " << format;
|
||||
return QImage();
|
||||
}
|
||||
|
||||
if(height.isEmpty() && !width.isEmpty())
|
||||
height = width;
|
||||
|
||||
if(width.isEmpty() && height.isEmpty())
|
||||
width = height;
|
||||
|
||||
QZXing::EncodeErrorCorrectionLevel correctionLevelEnum;
|
||||
if(corretionLevel == "H")
|
||||
correctionLevelEnum = QZXing::EncodeErrorCorrectionLevel_H;
|
||||
else if(corretionLevel == "Q")
|
||||
correctionLevelEnum = QZXing::EncodeErrorCorrectionLevel_Q;
|
||||
else if(corretionLevel == "M")
|
||||
correctionLevelEnum = QZXing::EncodeErrorCorrectionLevel_M;
|
||||
else
|
||||
correctionLevelEnum = QZXing::EncodeErrorCorrectionLevel_L;
|
||||
|
||||
result = QZXing::encodeData(data, QZXing::EncoderFormat_QR_CODE,
|
||||
QSize(width.toInt(), height.toInt()),
|
||||
correctionLevelEnum);
|
||||
}
|
||||
else
|
||||
{
|
||||
data = id.mid(slashIndex + 1);
|
||||
result = QZXing::encodeData(data);
|
||||
}
|
||||
|
||||
QImage result = QZXing::encodeData(data);
|
||||
*size = result.size();
|
||||
return result;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue