Has anyone heard of this before ? Extract the QR
Codes
(all the QR Codes must be in same Width and Height {square}) and get the data from each QR Code
, and combine them. Then get the every pixel value from each QR Code and change them to hexadecimal
.
You will give #FFFFFFFF
, #FF000000
, #00000000
(white,black, transparent) and the like (but for black and white QR Code
, it would only 2 of them). Then for each value from each QR
Code, by creating a new colour QR Code
which the colour is according to the value from each hexadecimal and the content of the new colour QR Code
will have the content that was extracted from the previous QR Codes
.
For example, what I am doing now is extract 8 numbers of QR Code
and combine the content, then create a new colour QR Code
.
By now, I am stuck in the middle of the process. I have successfully extracted the content and the pixel of each QR Code
by changing the value to hexadecimal
. the problem is how can I can change the hexadecimal
value from each QR code
to ARGB
(alpha, Red, Green, Blue) colour and create a new colour QR Code
.
However, I have tip from Google, some say MatrixToImageWriter
would be useful. But there is not really much work there that is similar and useful to me. Well, I need some help here. However, I am not sure whether it will be useful for me or not.
Zxing
library to scan and get the result from each QR Code
.All in one QR code refers to adding multiple links using one QR code. This type of solution is called the Multi-URL QR code. Multi-URL QR has four types of features such as Multi-URL QR code for location, time redirection, amount of scans and language redirection.
I've just wrote the desired decode/encode methods; the matrix look different because I've created the input QR code with the QR Droid application and the output QR code with ZXing, which might use a different level of error correction; nevertheless both have the same destination URL, which is mine.
The dependencies originate from repositories google()
and mavenCentral()
:
dependencies {
implementation "androidx.appcompat:appcompat:1.0.2"
// https://mvnrepository.com/artifact/com.google.zxing
implementation "com.google.zxing:core:3.3.3"
implementation "com.google.zxing:android-core:3.3.0"
}
The layout resource used:
<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.LinearLayoutCompat
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:gravity="center">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/inputImage"
android:src="@drawable/qrcode"
android:layout_height="200dp"
android:layout_width="200dp"
android:padding="8dp"/>
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/outputImage"
android:layout_height="200dp"
android:layout_width="200dp"
android:padding="8dp"/>
</androidx.appcompat.widget.LinearLayoutCompat>
And the manipulation of the BitMatrix
; where the encode()
method should suffice, when having the String
available; just added both methods for the sake of a complete example (it reads the Bitmap
from one AppCompatImageView
and then writes to another one AppCompatImageView
):
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.util.Log;
import androidx.annotation.ColorInt;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.AppCompatImageView;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.LuminanceSource;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.NotFoundException;
import com.google.zxing.RGBLuminanceSource;
import com.google.zxing.Result;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;
public class MainActivity extends AppCompatActivity {
private AppCompatImageView mInputImage;
private AppCompatImageView mOutputImage;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setContentView(R.layout.layout_main);
this.mInputImage = this.findViewById(R.id.inputImage);
this.mOutputImage = this.findViewById(R.id.outputImage);
Bitmap bitmap = ((BitmapDrawable) this.mInputImage.getDrawable()).getBitmap();
String data = this.decode(bitmap);
bitmap = this.encode(data, bitmap.getWidth(), bitmap.getHeight(), 0xFFFFD034,0xFF06425C);
this.mOutputImage.setImageBitmap(bitmap);
}
private String decode(Bitmap bitmap) {
String data = null;
MultiFormatReader reader = new MultiFormatReader();
int[] intArray = new int[bitmap.getWidth() * bitmap.getHeight()];
bitmap.getPixels(intArray, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(), bitmap.getHeight());
LuminanceSource source = new RGBLuminanceSource(bitmap.getWidth(), bitmap.getHeight(), intArray);
BinaryBitmap binary = new BinaryBitmap(new HybridBinarizer(source));
try {
Result result = reader.decode(binary);
data = result.getText();
} catch (NotFoundException e) {
e.printStackTrace();
}
Log.d("ZXing", "decoded: " + data);
return data;
}
private Bitmap encode(String contents, int width, int height, @ColorInt int foreground, @ColorInt int background) {
MultiFormatWriter writer = new MultiFormatWriter();
BitMatrix matrix = null;
Bitmap bitmap = null;
try {
matrix = writer.encode(contents, BarcodeFormat.QR_CODE, width, height);
} catch (WriterException e) {
e.printStackTrace();
}
if(matrix != null) {
int[] pixels = new int[width * height];
for (int y = 0; y < height; y++) {
int offset = y * width;
for (int x = 0; x < width; x++) {
pixels[offset + x] = matrix.get(x, y) ? foreground : background;
}
}
bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
}
return bitmap;
}
}
The result looks alike this; where the left one is the input matrix and the right one is the output matrix:
Well, after few days of digging from the Internet. I have found the solution and I think it would help someone else someday.
QRCodeWriter qw = new QRCodeWriter();
try {
HashMap<EncodeHintType, Object> hints = new HashMap<>();
hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
hints.put(EncodeHintType.MARGIN, margin);
BitMatrix matrix = qw.encode(msg, BarcodeFormat.QR_CODE, width, height, hints);
Bitmap bmp = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
for (int x = 0; x < width; x++) {
for (int y = 0; y < width; y++) {
bmp.setPixel(x, y, matrix.get(x, y) ? Color.BLACK : Color.WHITE);
}
}
return bmp;
} catch (WriterException e) {
e.printStackTrace();
}
To change the color of the QR Code and if you have an arraylist
like mine that store all the hex
String. You can using for
loops and to insert the hex
String.
For changing the color, based on the code,
for (int x = 0; x < width; x++) {
for (int y = 0; y < width; y++) {
bmp.setPixel(x, y, matrix.get(x, y) ? Color.BLACK : Color.WHITE);
}
}
The Color.Black can be replace with the arraylist
(in my case, I replace it with my colorArray
) and Color.White is the color for the background of a QR Code.
Well, hope it helps someone somedays. Happy coding.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With