Merge branch 'promag-2019-08-add-border-feature' from #126 which adds support to

boarder option during Qr encoding.
This commit is contained in:
Nikos Ftylitakis 2019-09-29 20:20:39 +03:00
commit 703667de30
5 changed files with 79 additions and 20 deletions

View File

@ -206,8 +206,10 @@ Image{
Or use the encoding function with the optional custom settings that are passed like URL query parameters: Or use the encoding function with the optional custom settings that are passed like URL query parameters:
<<<<<<< HEAD
| attribute name | value | description | | attribute name | value | description |
| -------------- | ---------- | --------------------------------------------- | | --------------- | ---------- | --------------------------------------------- |
| border | true, false | whether the image has a border |
| correctionLevel | L, M, Q, H | the error correction level | | correctionLevel | L, M, Q, H | the error correction level |
| format | qrcode | the encode formatter. Currently only QR Code. | | format | qrcode | the encode formatter. Currently only QR Code. |

View File

@ -10,6 +10,7 @@ ApplicationWindow {
minimumWidth: formatGroupBox.width + minimumWidth: formatGroupBox.width +
errorCorrectionlevelGroupBox.width + errorCorrectionlevelGroupBox.width +
borderStatus.width +
5 * advancedOptions.spacing 5 * advancedOptions.spacing
property bool isAdvancedOptionsEnabled: advancedSwitch.position; property bool isAdvancedOptionsEnabled: advancedSwitch.position;
@ -75,6 +76,12 @@ ApplicationWindow {
model: ["L", "M", "Q", "H"] model: ["L", "M", "Q", "H"]
} }
} }
Switch {
id: borderStatus
text: "Border"
anchors.verticalCenter: parent.verticalCenter
}
} }
Rectangle { Rectangle {
@ -102,7 +109,8 @@ ApplicationWindow {
if(mainWindow.isAdvancedOptionsEnabled) { if(mainWindow.isAdvancedOptionsEnabled) {
return "image://QZXing/encode/" + inputField.text + return "image://QZXing/encode/" + inputField.text +
"?correctionLevel=" + errorCorrectionlevelCombo.currentText + "?correctionLevel=" + errorCorrectionlevelCombo.currentText +
"&format=" + formatCombo.currentText "&format=" + formatCombo.currentText +
"&border=" + borderStatus.position;
} }
else else
return "image://QZXing/encode/" + inputField.text; return "image://QZXing/encode/" + inputField.text;

View File

@ -575,34 +575,55 @@ QString QZXing::decodeSubImageQML(const QUrl &imageUrl,
QImage QZXing::encodeData(const QString& data, QImage QZXing::encodeData(const QString& data,
const EncoderFormat encoderFormat, const EncoderFormat encoderFormat,
const QSize encoderImageSize, const QSize encoderImageSize,
const EncodeErrorCorrectionLevel errorCorrectionLevel) const EncodeErrorCorrectionLevel errorCorrectionLevel,
const bool border)
{
return encodeData(data,
QZXingEncoderConfig(encoderFormat,
encoderImageSize,
errorCorrectionLevel,
border));
}
QImage QZXing::encodeData(const QString &data, const QZXingEncoderConfig &encoderConfig)
{ {
QImage image; QImage image;
try { try {
switch (encoderFormat) { switch (encoderConfig.format) {
case EncoderFormat_QR_CODE: case EncoderFormat_QR_CODE:
{ {
Ref<qrcode::QRCode> barcode = qrcode::Encoder::encode( Ref<qrcode::QRCode> barcode = qrcode::Encoder::encode(
data.toStdString(), data.toStdString(),
errorCorrectionLevel == EncodeErrorCorrectionLevel_H ? encoderConfig.errorCorrectionLevel == EncodeErrorCorrectionLevel_H ?
qrcode::ErrorCorrectionLevel::H : qrcode::ErrorCorrectionLevel::H :
(errorCorrectionLevel == EncodeErrorCorrectionLevel_Q ? (encoderConfig.errorCorrectionLevel == EncodeErrorCorrectionLevel_Q ?
qrcode::ErrorCorrectionLevel::Q : qrcode::ErrorCorrectionLevel::Q :
(errorCorrectionLevel == EncodeErrorCorrectionLevel_M ? (encoderConfig.errorCorrectionLevel == EncodeErrorCorrectionLevel_M ?
qrcode::ErrorCorrectionLevel::M : qrcode::ErrorCorrectionLevel::M :
qrcode::ErrorCorrectionLevel::L))); qrcode::ErrorCorrectionLevel::L)));
Ref<qrcode::ByteMatrix> bytesRef = barcode->getMatrix(); Ref<qrcode::ByteMatrix> bytesRef = barcode->getMatrix();
const std::vector< std::vector <zxing::byte> >& bytes = bytesRef->getArray(); const std::vector< std::vector <zxing::byte> >& bytes = bytesRef->getArray();
image = QImage(int(bytesRef->getWidth()), int(bytesRef->getHeight()), QImage::Format_ARGB32); const int width = int(bytesRef->getWidth()) + (encoderConfig.border ? 2 : 0);
for(size_t i=0; i<bytesRef->getWidth(); i++) const int height = int(bytesRef->getHeight()) + (encoderConfig.border ? 2 : 0);
for(size_t j=0; j<bytesRef->getHeight(); j++) const QRgb black = qRgb(0, 0, 0);
image.setPixel(int(i), int(j), bytes[j][i] ? const QRgb white = qRgb(255, 255, 255);
qRgb(0,0,0) :
qRgb(255,255,255));
image = image.scaled(encoderImageSize); image = QImage(width, height, QImage::Format_ARGB32);
image.fill(white);
int offset = encoderConfig.border ? 1 : 0;
for (size_t i=0; i<bytesRef->getWidth(); ++i) {
for (size_t j=0; j<bytesRef->getHeight(); ++j) {
if (bytes[j][i]) {
image.setPixel(offset+int(i), offset+int(j), black);
}
}
}
image = image.scaled(encoderConfig.imageSize);
break; break;
} }
case EncoderFormat_INVALID: case EncoderFormat_INVALID:

View File

@ -36,6 +36,7 @@ class MultiFormatReader;
class ResultMetadata; class ResultMetadata;
} }
class ImageHandler; class ImageHandler;
struct QZXingEncoderConfig;
/** /**
* A class containing a very very small subset of the ZXing library. * A class containing a very very small subset of the ZXing library.
@ -179,10 +180,17 @@ public slots:
/** /**
* The main encoding function. Currently supports only Qr code encoding * The main encoding function. Currently supports only Qr code encoding
*/ */
static QImage encodeData(const QString &data,
const QZXingEncoderConfig &encoderConfig);
/**
* Overloaded function of encodeData.
*/
static QImage encodeData(const QString& data, static QImage encodeData(const QString& data,
const EncoderFormat encoderFormat = EncoderFormat_QR_CODE, const EncoderFormat encoderFormat = EncoderFormat_QR_CODE,
const QSize encoderImageSize = QSize(240, 240), const QSize encoderImageSize = QSize(240, 240),
const EncodeErrorCorrectionLevel errorCorrectionLevel = EncodeErrorCorrectionLevel_L); const EncodeErrorCorrectionLevel errorCorrectionLevel = EncodeErrorCorrectionLevel_L,
const bool border = false);
/** /**
* Get the prossecing time in millisecond of the last decode operation. * Get the prossecing time in millisecond of the last decode operation.
@ -230,5 +238,20 @@ private:
bool isThreaded; bool isThreaded;
}; };
typedef struct QZXingEncoderConfig
{
QZXing::EncoderFormat format;
QSize imageSize;
QZXing::EncodeErrorCorrectionLevel errorCorrectionLevel;
bool border;
QZXingEncoderConfig(const QZXing::EncoderFormat encoderFormat_ = QZXing::EncoderFormat_QR_CODE,
const QSize encoderImageSize_ = QSize(240, 240),
const QZXing::EncodeErrorCorrectionLevel errorCorrectionLevel_ = QZXing::EncodeErrorCorrectionLevel_L,
const bool border_ = false) :
format(encoderFormat_), imageSize(encoderImageSize_),
errorCorrectionLevel(errorCorrectionLevel_), border(border_) {}
} QZXingEncoderConfig;
#endif // QZXING_H #endif // QZXING_H

View File

@ -28,8 +28,9 @@ QImage QZXingImageProvider::requestImage(const QString &id, QSize *size, const Q
QString data; QString data;
QZXing::EncoderFormat format = QZXing::EncoderFormat_QR_CODE; QZXing::EncoderFormat format = QZXing::EncoderFormat_QR_CODE;
QZXing::EncodeErrorCorrectionLevel correctionLevel = QZXing::EncodeErrorCorrectionLevel_L; QZXing::EncodeErrorCorrectionLevel correctionLevel = QZXing::EncodeErrorCorrectionLevel_L;
bool border = false;
int customSettingsIndex = id.lastIndexOf(QRegularExpression("\\?(correctionLevel|format)=")); int customSettingsIndex = id.lastIndexOf(QRegularExpression("\\?(correctionLevel|format|border)="));
if(customSettingsIndex >= 0) if(customSettingsIndex >= 0)
{ {
int startOfDataIndex = slashIndex + 1; int startOfDataIndex = slashIndex + 1;
@ -56,12 +57,16 @@ QImage QZXingImageProvider::requestImage(const QString &id, QSize *size, const Q
correctionLevel = QZXing::EncodeErrorCorrectionLevel_M; correctionLevel = QZXing::EncodeErrorCorrectionLevel_M;
else if(correctionLevelString == "L") else if(correctionLevelString == "L")
correctionLevel = QZXing::EncodeErrorCorrectionLevel_L; correctionLevel = QZXing::EncodeErrorCorrectionLevel_L;
if (optionQuery.hasQueryItem("border")) {
border = QVariant(optionQuery.queryItemValue("border")).toBool();
}
} else } else
{ {
data = id.mid(slashIndex + 1); data = id.mid(slashIndex + 1);
} }
QImage result = QZXing::encodeData(data, format, requestedSize, correctionLevel); QImage result = QZXing::encodeData(data, format, requestedSize, correctionLevel, border);
*size = result.size(); *size = result.size();
return result; return result;
} }