【问题标题】:Extract the data from QR Codes and create a new QR code with colour从二维码中提取数据并创建一个带有颜色的新二维码
【发布时间】:2019-03-04 07:26:59
【问题描述】:

有人听说过这个吗?提取QRCodes(所有二维码必须在相同的宽度和高度{square})并从每个QR Code中获取数据,并将它们组合起来。然后从每个二维码中获取每个像素值并将它们更改为hexadecimal。 你会给#FFFFFFFF#FF000000#00000000(白色,黑色,透明)等(但对于黑白QR Code,它只会有2个)。然后对于每个 QR 代码中的每个值,通过创建一个 新颜色 QR Code 其颜色根据每个十六进制的值和新颜色 QR Code 的内容将具有从之前的QR Codes中提取的内容。

比如我现在做的是提取QR Code的8个数字并合并内容,然后新建一个colour QR Code

到目前为止,我被困在了这个过程的中间。通过将值更改为hexadecimal,我已经成功提取了每个QR Code 的内容和像素。问题是我怎样才能将每个QR codehexadecimal 值更改为ARGB(alpha、Red、Green、Blue)颜色并创建一个新颜色QR Code

不过,我收到了来自 Google 的提示,有人说 MatrixToImageWriter 会很有用。但是那里并没有太多与我相似和有用的工作。好吧,我需要一些帮助。但是,我不确定它是否对我有用。

PS:如果有人愿意,我可以在这里附上我的作品。

PSS:我正在使用Zxing 库扫描并从每个QR Code 获取结果。

【问题讨论】:

  • +1,期待这个问题,因为我对你的问题很感兴趣,这似乎是结合二维码并获取更大的二维码来存储更多数据。
  • @Kopi Bryant “PS:如果有人愿意,我可以在这里附上我的作品” 是的,这会有所帮助,(可能)。
  • 给@Martin Zeitler 他的二维码示例;O)

标签: android qr-code zxing


【解决方案1】:

我刚刚编写了所需的解码/编码方法;矩阵看起来不同,因为我使用QR Droid 应用程序创建了输入二维码,使用ZXing 创建了输出二维码,这可能使用不同级别的纠错;尽管如此,两者都有相同的目标 URL,这是我的。

依赖来自存储库google()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"
}

使用的布局资源:

<?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>

以及BitMatrix的操纵;当String 可用时,encode() 方法就足够了;只是为了一个完整的例子添加了这两种方法(它从一个AppCompatImageView 读取Bitmap,然后写入另一个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;
    }
}

结果看起来像这样;其中左边是输入矩阵,右边是输出矩阵:

【讨论】:

  • 嗯,这很有帮助。如果我想将二维码的像素设置为我想要的颜色(例如,pixel[1][10] 为蓝色,pixel[20][20] 为红色,类似这样)怎么办?
  • @KopiBryant 您可以添加一个方法,该方法获取其中一种颜色的替代颜色代码(例如,通过从照片中读取,通过当前的 x/y 坐标)。请注意,颜色应以0xFF(零透明度)开头;此外,提供低对比度的颜色组合可能会妨碍正确检测。 complimentary colors 应该可以很好地工作......而且人们可以用 QR 做很多事情(......),但纠错仍然有它的限制。
  • 请参阅EncodeHintType 以获取更多设置,可以将其传递给MultiFormatWriter(在参数height 之后),它允许调整例如。纠错级别 - 或要输出的 QR 版本。
  • 好吧,如果有一些示例代码会很有帮助和感激。
  • @KopiBryant 不是问题的一部分,我已经回答了这个问题,甚至提供了进一步的线索......此外,甚至不清楚目的是什么,你想要做什么做。请参阅meta.stackoverflow.com... 编程是我的面包(正如示例 QR 码可能暗示的那样),所以我不能只是超出所要求的范围。提出一个赏金的新问题可能是你获得这样一个例子的最佳机会。
【解决方案2】:

好吧,经过几天的互联网挖掘。我找到了解决方案,我认为它有一天会对其他人有所帮助。

 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();
}

要更改 QR 码的颜色,如果您有像我这样的 arraylist 存储所有 hex 字符串。您可以使用for 循环并插入hex 字符串。

为了改变颜色,根据代码,

 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);
    }
}

Color.Black 可以替换为arraylist(在我的情况下,我将其替换为我的colorArray),Color.White 是二维码背景的颜色。

嗯,希望有一天它对某人有所帮助。 编码愉快

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-03
    • 1970-01-01
    • 1970-01-01
    • 2011-01-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多