gpt4 book ai didi

android - 我想扫描经典二维码和倒置(浅暗)二维码。该怎么办?

转载 作者:可可西里 更新时间:2023-10-31 22:04:12 28 4
gpt4 key购买 nike

我正在使用已弃用的 Camera 类。我在 onPreviewFrame(byte[] data, Camera camera) 方法中进行处理。 Zbar 扫描仪没有触发“尝试反向”扫描的选项。我发现我可以在我的 android 相机上设置负色效果,它非常适合扫描倒置的 QR 码,但它停止检测正常的。

我正在尝试找到一种欺骗的方法,比如让同一台相机有 2 个实例,一个应用了负面效果,一个没有应用负面效果,只显示无效果的一个,但它不允许我这样做。

每次显示一帧时都会调用下面的代码。

private Camera.PreviewCallback previewCb = new Camera.PreviewCallback() {
public void onPreviewFrame(byte[] data, Camera camera) {
Camera.Parameters parameters = camera.getParameters();
Camera.Size size = parameters.getPreviewSize();

Image barcode = new Image(size.width, size.height, "Y800");
barcode.setData(data);
int result = scanner.scanImage(barcode);

这就是我设置负面影响的方式。

Camera.Parameters params = mCamera.getParameters();
params.setColorEffect(Camera.Parameters.EFFECT_NEGATIVE);
mCamera.setParameters(params);

另一种方法是处理我自己从预览回调中获得的 YUV 字节数组并应用负面效果,但我不确定如何在不进行大量转换的情况下执行此操作。

有什么想法吗?

最佳答案

在数周未找到任何答案/被误导后,我设法让它来回转换 YUV 数据。在 ZBarScannerView.java 中,这是我的 onPreviewFrame(..) 的样子:

@Override
public void onPreviewFrame(byte[] data, Camera camera) {
Camera.Parameters parameters = camera.getParameters();
Camera.Size size = parameters.getPreviewSize();
int width = size.width;
int height = size.height;

switcher = !switcher;


if(DisplayUtils.getScreenOrientation(getContext()) == Configuration.ORIENTATION_PORTRAIT) {
byte[] rotatedData = new byte[data.length];
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++)
rotatedData[x * height + height - y - 1] = data[x + y * width];
}
int tmp = width;
width = height;
height = tmp;
data = rotatedData;
}

Image barcode = new Image(width, height, "Y800");

if (switcher) {
int[] pixels = applyGrayScale(data,width,height);
Bitmap bm = Bitmap.createBitmap(pixels,width,height, Bitmap.Config.ARGB_8888);
bm = MyUtils.createInvertedBitmap(bm, width, height);

pixels = new int[width*height];
bm.getPixels(pixels, 0, bm.getWidth(), 0, 0, bm.getWidth(), bm.getHeight());

encodeYUV420SP(data, pixels, bm.getWidth(), bm.getHeight());
}


barcode.setData(data);

int result = mScanner.scanImage(barcode);

if (result != 0) {
stopCamera();
if(mResultHandler != null) {
SymbolSet syms = mScanner.getResults();
Result rawResult = new Result();
for (Symbol sym : syms) {
String symData = sym.getData();
if (!TextUtils.isEmpty(symData)) {
rawResult.setContents(symData);
rawResult.setBarcodeFormat(BarcodeFormat.getFormatById(sym.getType()));
break;
}
}
mResultHandler.handleResult(rawResult);
}
} else {
camera.setOneShotPreviewCallback(this);
}
}

也将其添加到类中(来自 Here):

void encodeYUV420SP(byte[] yuv420sp, int[] argb, int width, int height) {
final int frameSize = width * height;

int yIndex = 0;
int uvIndex = frameSize;

int a, R, G, B, Y, U, V;
int index = 0;
for (int j = 0; j < height; j++) {
for (int i = 0; i < width; i++) {

a = (argb[index] & 0xff000000) >> 24; // a is not used obviously
R = (argb[index] & 0xff0000) >> 16;
G = (argb[index] & 0xff00) >> 8;
B = (argb[index] & 0xff) >> 0;

// well known RGB to YUV algorithm
Y = ((66 * R + 129 * G + 25 * B + 128) >> 8) + 16;
U = ((-38 * R - 74 * G + 112 * B + 128) >> 8) + 128;
V = ((112 * R - 94 * G - 18 * B + 128) >> 8) + 128;

// NV21 has a plane of Y and interleaved planes of VU each sampled by a factor of 2
// meaning for every 4 Y pixels there are 1 V and 1 U. Note the sampling is every other
// pixel AND every other scanline.
yuv420sp[yIndex++] = (byte) ((Y < 0) ? 0 : ((Y > 255) ? 255 : Y));
if (j % 2 == 0 && index % 2 == 0) {
yuv420sp[uvIndex++] = (byte) ((V < 0) ? 0 : ((V > 255) ? 255 : V));
yuv420sp[uvIndex++] = (byte) ((U < 0) ? 0 : ((U > 255) ? 255 : U));
}

index++;
}
}
}

这负责在反转后将 int 数组转换回字节数组。

此外,我还使用了这些代码 fragment ,这些代码 fragment 是我在 stackExchange 的某个地方找到的(我太久不记得在哪里了),在一个名为 MyUtils.java 的实用程序类中做了一些小改动:

public class MyUtils {

public static Integer sizeWidth;
public static Integer sizeHeight;


public static Bitmap createInvertedBitmap(Bitmap src, Integer width, Integer height) {

sizeWidth = width;
sizeHeight = height;

ColorMatrix colorMatrix_Inverted =
new ColorMatrix(new float[] {
-1, 0, 0, 0, 255,
0, -1, 0, 0, 255,
0, 0, -1, 0, 255,
0, 0, 0, 1, 0});

ColorFilter ColorFilter_Sepia = new ColorMatrixColorFilter(
colorMatrix_Inverted);

Bitmap bitmap = Bitmap.createBitmap(sizeWidth, sizeHeight,
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);

Paint paint = new Paint();

paint.setColorFilter(ColorFilter_Sepia);
canvas.drawBitmap(src, 0, 0, paint);

return bitmap;
}


public static int[] applyGrayScale(byte [] data, int width, int height) {
int p;
int size = width*height;
int[] pixels = new int[size];
for(int i = 0; i < size; i++) {
p = data[i] & 0xFF;
pixels[i] = 0xff000000 | p<<16 | p<<8 | p;
}
return pixels;
}

最后,在 ZBarScannerView 类范围内将 Boolean switcher = true 添加到类中。变量“切换器”用于在检查倒码或非倒码之间切换。

请询问您是否有任何问题,我为此苦苦挣扎了很长时间,我觉得是的,为了便于阅读,答案可能需要一些编辑。

关于android - 我想扫描经典二维码和倒置(浅暗)二维码。该怎么办?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29983908/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com