二维码、条形码、扫一扫,横屏、竖屏、反转横屏、变形,扫码无反应等问题记录

场景:扫一扫需求出现场景,非常规UI需求。发生在HD平板上。屏幕方向固定,非垂直,非横屏。竟让是反转横屏。

        如图:

使用到的zxing库为开源:yipianfengye/android-zxingLibraryhttps://github.com/yipianfengye/android-zxingLibrary

遇到问题:1预览图变形,2,方向反转。3扫描不上。

一顿查找!!!各种解决变形问题。

起初就按照这种方式解决变形,然而代码无效。

感谢一位仁兄:https://blog.csdn.net/weimingyu1/article/details/52382182 Zxing横竖屏切换方法。

⬇️⬇️⬇️⬇️⬇️原文章加上自己的修改⬇️⬇️⬇️⬇️⬇️

Zxing横竖屏切换只需要修改

1、竖屏在DecodeHandler类中加上下面这段代码,横屏注释掉这段代码

//modify here 竖屏
/*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; // Here we are swapping, that's the difference to #11
width = height;
height = tmp;*/
//横屏 不需要处理
//反转横屏(正常的竖屏转一下,再转一下就是反转横屏了。应该有一步转到的方式,下面代码 待优化。)
/*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];
}
byte[] dd  = new byte[rotatedData.length];
for (int y = 0; y < width; y++) {
    for (int x = 0; x < height; x++)
        dd[x * width + width - y - 1] = rotatedData[x + y * height];
}*/
//上面不同屏幕方向,下面buildLuminanceSource 第一个参数 对应修改。
PlanarYUVLuminanceSource source = CameraManager.get().buildLuminanceSource(data, width, height);


2、然后修改CameraManager中的下面这段代码
# 竖屏为:

  rect.left = rect.left * cameraResolution.y / screenResolution.x;
  rect.right = rect.right * cameraResolution.y / screenResolution.x;
  rect.top = rect.top * cameraResolution.x / screenResolution.y;
  rect.bottom = rect.bottom * cameraResolution.x / screenResolution.y;
# 横屏(包括反转横屏)为:

  rect.left = rect.left * cameraResolution.x / screenResolution.x;
  rect.right = rect.right * cameraResolution.x / screenResolution.x;
  rect.top = rect.top * cameraResolution.y / screenResolution.y;
  rect.bottom = rect.bottom * cameraResolution.y / screenResolution.y;
3、修改AndroidManifest中的activity属性
  android:screenOrientation="xxxxx"
  portrait为竖屏,landscape为横屏,revertLandscape为反转横屏
4、最后修改CameraConfigurationManager类中的这行代码
  setDisplayOrientation(camera, 90);  //90为竖屏,0为横屏//modify here 0 横屏 竖屏 90 反转横屏; 180 camera.setDisplayOrientation(0);

----------------

至此  !屏幕旋转问题,解决了。预览图变形也好了。就是识别不上。

不解!各种郁闷!!!

最终布局文件在做祟!!有人说布局文件必须要那样吗!!!也怪我们的这需求有点不一样吧!!(如最上面图)

我将上图中的黑色区域放FrameLayout。

CaptureFragment替换于此。扫描没有任何反应。

为了解决这个问题。只能将在所有的布局 底下放一个全屏的FrameLayout,来放CaptureFragment。

可以扫描了!!!!!!!!!!!!!!!

问题又来了!!!!!!

外面的FrameLayout 和 Zxing的 ViewfinderView,位置不一致。

图上效果是调完之后,另外一种请款下出来的效果。

 修改     ViewfinderView  中的 

initInnerRect(Context context, AttributeSet attrs)方法。动态计算二维码区域宽高。
//左侧QR 适配 (下列数据供参考)
        //768 - 400
        int widHei = 25 * screenHei / 48;
        // 扫描框的宽度
        CameraManager.FRAME_WIDTH = widHei;
        // 扫描框的高度
        CameraManager.FRAME_HEIGHT = widHei;

CameraManager

getFramingRect()修改位置。
//左边扫描部分   右边 放大镜
int rightHei = FRAME_WIDTH * 9 / 10;
int rightWid = rightHei * 4 / 3;

//剩余部分 25:11
int leftOffset = (screenResolution.x - FRAME_WIDTH - rightWid) * 25 / 36;

int topTitleHei = DisplayUtil.dip2px(context, 86);

int topOffset = (screenResolution.y - FRAME_HEIGHT - DisplayUtil.dip2px(context, 70) - topTitleHei) * 115 / (115 + 98) + topTitleHei;

framingRect = new Rect(leftOffset, topOffset, leftOffset + FRAME_WIDTH, topOffset + FRAME_HEIGHT);

问题都解决了!!!

 

感谢博主:

1:https://blog.csdn.net/weimingyu1/article/details/52382182 Zxing横竖屏切换方法。

2:https://github.com/yipianfengye/android-zxingLibrar android-zxingLibrary

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是一个基于 C++ 和 OpenCV 库的二维码/条码扫码示例代码: ``` #include <iostream> #include <opencv2/opencv.hpp> #include <opencv2/imgproc.hpp> #include <opencv2/highgui.hpp> #include <opencv2/dnn.hpp> using namespace std; using namespace cv; using namespace cv::dnn; int main() { // 加载模型和标签 String model_file = "frozen_inference_graph.xml"; String label_file = "label_map.pbtxt"; Net net = readNetFromTensorflow(model_file); std::vector<String> labels; std::ifstream ifs(label_file.c_str()); std::string line; while (std::getline(ifs, line)) { if (line.find("display_name:") != std::string::npos) { labels.push_back(line.substr(15, line.length() - 16)); } } // 打开摄像头 VideoCapture cap(0); if (!cap.isOpened()) { cout << "Failed to open camera." << endl; return -1; } // 循环读取像并识别二维码/条码 Mat frame; while (cap.read(frame)) { // 转换为灰度像 Mat gray; cvtColor(frame, gray, COLOR_BGR2GRAY); // 识别二维码/条码 std::vector<Mat> codes; QRCodeDetector detector; String data = detector.detectAndDecode(gray, codes); // 显示结果 if (!data.empty()) { putText(frame, data, Point(50, 50), FONT_HERSHEY_SIMPLEX, 1, Scalar(0, 0, 255), 2); } else { Mat blob = blobFromImage(frame, 1.0, Size(300, 300), Scalar(127.5, 127.5, 127.5), true, false); net.setInput(blob); Mat detections = net.forward(); Mat detectionMat(detections.size[2], detections.size[3], CV_32F, detections.ptr<float>()); for (int i = 0; i < detectionMat.rows; i++) { float confidence = detectionMat.at<float>(i, 2); if (confidence > 0.5) { int classId = static_cast<int>(detectionMat.at<float>(i, 1)); String className = labels[classId - 1]; int x1 = static_cast<int>(detectionMat.at<float>(i, 3) * frame.cols); int y1 = static_cast<int>(detectionMat.at<float>(i, 4) * frame.rows); int x2 = static_cast<int>(detectionMat.at<float>(i, 5) * frame.cols); int y2 = static_cast<int>(detectionMat.at<float>(i, 6) * frame.rows); rectangle(frame, Point(x1, y1), Point(x2, y2), Scalar(0, 0, 255)); putText(frame, className, Point(x1, y1 - 10), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 0, 255)); } } } imshow("Barcode Scanner", frame); if (waitKey(1) == 27) { break; } } // 释放资源 cap.release(); destroyAllWindows(); return 0; } ``` 上述代码首先加载模型文件和标签文件,然后打开摄像头并循环读取像。对于每帧像,首先将像转换为灰度像,然后使用 OpenCV 的 QRCodeDetector 类识别二维码/条码。如果识别到了二维码/条码,则在像中绘制识别结果。否则,使用 OpenCV 的 dnn 模块和 TensorFlow 模型识别物体,并在像中绘制识别结果。 需要注意的是,上述代码仅适用于识别单个二维码/条码,并且对于复杂像中的二维码/条码识别效果可能不理想。如果需要更高效、更准确的二维码/条码识别算法,可以考虑使用深度学习模型或者其他高级算法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值