精华内容
下载资源
问答
  • 二维码扫描模块使用的是窜口通信,可以使用USB转TTL配合微信小程序(二维码生成器)生成二维码,模块RXD,TXD一定要跟TTL的RXD,TXD反接,使用窜口调休助手就可以观察二维码扫描模块的的效果 STM32搭配二模块扫描...

    这里使用的是SMT32F103RCT6核心板

    二维码扫描模块使用的是窜口通信,可以使用USB转TTL配合微信小程序(二维码生成器)生成二维码,模块RXD,TXD一定要跟TTL的RXD,TXD反接,使用窜口调休助手就可以观察二维码扫描模块的的效果

    STM32搭配二模块扫描模块实现门禁

    二维码启动C文件

    #include <string.h>
    #include "QR_Scaner.h"
    #include "usart.h"
    #include "systick.h"

    uint8_t        TmpBuf[1];
    uint8_t        QRScanerRxBuf[1024];
    __IO uint32_t    QR_Scaner_RxIdx = 0;

    uint8_t complete_flag = 0;

    void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
    {
        if(huart->Instance == USART2)
        {
            if(TmpBuf[0] != 0x00)
                QRScanerRxBuf[QR_Scaner_RxIdx++] = TmpBuf[0];
            
            //HAL_UART_Transmit(&huart1, (uint8_t *)TmpBuf, 1, 0xffff);
            
            if(QR_Scaner_RxIdx >= sizeof(QRScanerRxBuf))
            {
                memset(QRScanerRxBuf, 0x00, sizeof(QRScanerRxBuf));
                QR_Scaner_RxIdx = 0;
                printf("QRScanerRxBuf 已满\r\n");
            }
            
            HAL_UART_Receive_IT(&huart2, TmpBuf, 1);
        }
    }

    char multip_scaner_cmd[] = "AT+SCAN=0\r\n";    //全速扫码
    char single_scaner_cmd[] = "AT+SCAN=1\r\n";    //单次扫码

    int scan_mode_set(uint8_t mode)
    {
        memset(QRScanerRxBuf, 0x00, sizeof(QRScanerRxBuf));
        QR_Scaner_RxIdx = 0;    
        
        switch(mode)
        {
            case 0:
                HAL_UART_Transmit(&huart2, (uint8_t *)multip_scaner_cmd, strlen(multip_scaner_cmd), 100);
                break;
            case 1:
                HAL_UART_Transmit(&huart2, (uint8_t *)single_scaner_cmd, strlen(single_scaner_cmd), 100);
                break;
            default:
                return -1;
        }    
            
        delayms(20);

        if(strstr((char *)QRScanerRxBuf, "[AT]OK\r\n"))
        {
            return 0;
        }
        else
        {
            return -1;
        }
    }

    #define QR_SCANER_RESET_RETURN        "OK! - [QBoard][A very outstanding Bar Code Scanner]\r\n"

    #define PASS_WORD    "1234567890"            // 默认的门禁密码,修改成自己的密码,也就是二维码的内容。

    void QR_Door_Control(void)
    {    
        uint32_t tick_start = 0;
        
        printf("---欢迎使用二维码门禁系统---\r\n");
        
        memset(QRScanerRxBuf, 0x00, sizeof(QRScanerRxBuf));
        QR_Scaner_RxIdx = 0;
        


        // 启动串口接收
        HAL_UART_Receive_IT(&huart2, TmpBuf, 1);
        
        // 等待二维码扫描模块启动
        tick_start = get_systicks();
        while(1)
        { 
            if(QR_Scaner_RxIdx==0)
            {
                printf("\r\n .二维码扫描模块已启动...\r\n");
                break;
            }
            if(query_time(tick_start, 5000))
            {
                goto exit;
            }
        }
        printf("\r\n .已进入扫码识别模式,请扫码开门--->\r\n");

        memset(QRScanerRxBuf, 0x00, sizeof(QRScanerRxBuf));
        QR_Scaner_RxIdx = 0;    
        while(1)
        {
            if(QR_Scaner_RxIdx==0)
            {        
                /* 等待数据收完 */
                delayms(100);
                
                /* 对比收到的数据和密码 */
                if(strcmp((char *)QRScanerRxBuf, PASS_WORD"\r\n") == 0)
                {
                    //printf("密码是:%s", (char *)QRScanerRxBuf);
                    printf("\r\n .门禁密码正确 <---\r\n");
                    delayms(1000);
                }
                else
                {
                    printf("\r\n .门禁密码错误!\r\n");
                    delayms(1000);
                }
                
                // 门已关闭,重新开始扫码开门
                if(scan_mode_set(1) != 0)
                {
                    printf("设置单次扫码模式失败2\r\n");
                    break;
                }    
                
                memset(QRScanerRxBuf, 0x00, sizeof(QRScanerRxBuf));
                QR_Scaner_RxIdx = 0;                
            }    
        }
        
    exit:
        
        printf("进入扫码识别模式失败,请检查硬件连接。\r\n");
        printf("QRScanerRxBuf:%s", QRScanerRxBuf);
    }

    #ifndef __QR_SCANER_H__
    #define __QR_SCANER_H__

    void QR_Door_Control(void);

    #endif

    主函数

    int main(void)
    {
      /* USER CODE BEGIN 1 */

      /* USER CODE END 1 */

      /* MCU Configuration----------------------------------------------------------*/

      /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
      HAL_Init();

      /* USER CODE BEGIN Init */

      /* USER CODE END Init */

      /* Configure the system clock */
      SystemClock_Config();

      /* USER CODE BEGIN SysInit */

      /* USER CODE END SysInit */

      /* Initialize all configured peripherals */
      MX_GPIO_Init();
      MX_USART2_UART_Init();
      MX_USART1_UART_Init();
      /* USER CODE BEGIN 2 */
      
      QR_Door_Control();    
      LED_Control();
      /* USER CODE END 2 */

      /* Infinite loop */
      /* USER CODE BEGIN WHILE */
        printf("rest\n");
      while (1)
      {
       LED_R_ON;
      /* USER CODE END WHILE */

      /* USER CODE BEGIN 3 */

      }
      /* USER CODE END 3 */

    }

     

     

     

     

    展开全文
  • 前言 该模块是小编在做工程实训的物流小车所用,当时因为某些特殊原因,不得不放弃视觉识别,...因为工训的二维码内容位数字,如123,所以测试时小编自己生成了一个二维码123+321这种,故一下代码均以此来写的。 首先us

    前言

    该模块是博主在做工程实训的物流小车所用,当时因为某些特殊原因,不得不放弃视觉识别,因此想到用模块去代替功能。该模块就是当时在淘宝买的。虽然不如openmv那些效率高,但还是可以完成功能,当时用得也还不错,接上电源后,直接就可扫描,给的例程实在复杂,作为新手的我很多地方不是很懂,就自己试着搞了,还好最后实现了功能,使用的是正点原子stm32f1开发板。

    模块接线图(MD300)

    在这里插入图片描述
    其他的就不放了。

    代码

    其实这个模块主要问题还是在数据的接收处理上。我用的是串口调试助手,显示我要的数据的提取、测试。因为工训的二维码内容位数字,如123,所以测试时自己生成了一个二维码123+321这种,故一下代码均以此来写的。

    首先usart.c串口重定向

    //在usart.c中重定向fputc函数 
    int fputc(int ch, FILE *f)
    {      
    	while((USART1->SR&0X40)==0);//循环发送,直到发送完毕   
        USART1->DR = (u8) ch;      
    	return ch;
    }
    

    数据接收

    char e[10];
    char f[10];
    int i=0;
    int j=0;
    
    void USART1_IRQHandler(void)                	//串口1中断服务程序
    	{
    	
    #if SYSTEM_SUPPORT_OS 		//如果SYSTEM_SUPPORT_OS为真,则需要支持OS.
    	OSIntEnter();    
    #endif
    		
    	if(USART_GetITStatus(USART1,USART_IT_RXNE)) // 中断标志,判断中断标志位非空
     {
    	 
    	 e[i] = USART_ReceiveData(USART1);//定义一个数组接收数据
    	 if (e[i]!= '+')//跳过‘+’
    	 {
    
    	   f[j]=e[0]; 
    	   //这里小编测试了许多次,发现数据总是接收到数组的第一位,这里真的搞了好久才发现
    	   j++;
    	   printf("数据是%s",f[j]);
    	   
    	 }
    

    结语

    要拿到主函数的话一定要定义全局变量,当时我后面又在lcd上显示测试的时候,因为这个又卡了许久,总的来说,这个模块很简单,但一些细节确实要注意,一定要注意!!!

    规格书:https://download.csdn.net/download/qq_47941078/16744853?spm=1001.2014.3001.5501

    展开全文
  • 这个资料是条形码二维码扫描识别模块GM65在STM32F103ZET6上示例程序,主要用到的是串口通信和触摸屏显示器。
  • Android二维码扫描模块可简单集成(基于ZXing实现)

    Android二维码扫描模块可简单集成(基于ZXIng实现)

    一、该模块实现代码地址:https://github.com/M075097/MoZXing

    相对于官方Demo,有以下特点:

    • 1、修改横屏为竖屏,以及修改为竖屏后一维的条码识别依然需要横向扫描的问题
    • 2、修改扫描区域的视图效果,模仿支付宝的网格扫描效果,也可根据自己需求做简单的定制
    • 3、增加从相册选取图片识别的功能
    • 4、移除解码过程中的定位及可能结果的展示回调
    • 5、优化从相机调用到给出解码结果之间的调用,集成更简单
    • 6、自测有限,代码健壮性需要提升

    二、从ZXing源码开始(版本3.3.1)

    2.1 ZXing的github地址:https://github.com/zxing/zxing

    可以直接clone其仓库中的代码到本地,也可以直接下载https://github.com/zxing/zxing/releases页面的最新的打包源码。

    以3.3.1版本为例,工程构建使用AndroidStudio

    该源码中实际工程中需要用的是目录.\android及.\android-core及目录core下的代码。

    其中android下的即是一个.\android的实例工程,该目录下的代码主要是提供一个扫码界面,并捕捉实时图片数据供解码使用,具体解码处理在.\core下的代码完成

    .\android-core下只有一个文件:CameraConfigurationUtils.java,该文件作用是相机的相关属性设置类。我们可以直接copy到.\android下的合适位置

    .\core下是ZXing解码的核心处理代码,我们可以直接编译该文件夹下的代码为一个jar,进行依赖,也可以直接在项目build.gradle中添加依赖: compile ‘com.google.zxing:core:3.3.1’

    2.2 运行源码

    本例用的是AndroidStudio,过程如下:

    • 1.新建一个默认工程,把.\android 以module的形式导入该工程中,导入的时候直接使用默认转换,把原工程转化为一个AS工程
    • 2.copy .\andriod-core下的文件CameraConfigurationUtils.java 到.\android下,这里我们copy到原路径相同的camera下。
    • 在该Module下的build.gradle 中添加依赖:

      dependencies {
      compile fileTree(dir: 'libs', include: ['*.jar'])
      compile 'com.google.zxing:core:3.3.1'
      }
      
    • 运行该工程即可
    2.3 该官方Demo中我们一般需要改的地方:
    • 1.官方Demo是横屏,我们需要更改为竖屏
    • 2.官方的扫码,一般需要修改为方形,且扫码效果需要可自定义
    • 3.官方Demo中再扫描过程中会回调并在扫描区域绘制出识别到的定位相关信息,实际中一般不需要,可以移除掉该功能
    • 4.官方Demo中没有从相册的图片中识别二维码的示例(底层解码是支持的)
    • 5.官方的Demo中从相机调用和图像展示以及解码三个部分界限不是很清楚,我们如果想集成到自己的工程中的时候略显繁琐

    三、ZXing源码中主线的类图及时序图整理

    3.1 ZXing Demo中的主要工作流程简单来说就是打开摄像头并在摄像头的预览回调中把数据传给解析核心,并把结果回传。解析内核的代码我们暂时不需要更改,但是可以拆开,以便更换解析内核,而我们的主要的工作是封装相机调用,并添加相册图片的识别和解析内核到一块以便我们自己简单的集成。
    3.2 ZXing类图及说明

    3.3 ZXing时序图

    3.4 整个调用过程源码分析如下:
    3.4.1 在打开CaptureActivity后,在onResume()中创建CameraManager类,并且在该类中创建Camera的PreviewCallback并创建Camera的参数设置管理类CameraConfigurationManager

    CaptureActivity类代码如下:

    <类CaptureActivity>
    protected void onResume() {
    super.onResume();
    ....
    cameraManager = new CameraManager(getApplication());
    ....
    SurfaceView surfaceView = (SurfaceView) findViewById(R.id.preview_view);
    SurfaceHolder surfaceHolder = surfaceView.getHolder();
    if (hasSurface) {//SurfaceView 已经被初始化并创建出来
      // The activity was paused but not stopped, so the surface still exists. Therefore
      // surfaceCreated() won't be called, so init the camera here.
      initCamera(surfaceHolder);
    } else {//SurfaceView还没有被初始化完毕,需要在其回调中打开相机
      // Install the callback and wait for surfaceCreated() to init the camera.
      surfaceHolder.addCallback(this);
    }
    }
    

    CameraManager类的构造函数如下

     public CameraManager(Context context) {
    this.context = context;
    this.configManager = new CameraConfigurationManager(context);//相机的参数设置管理类
    previewCallback = new PreviewCallback(configManager);//相机的预览回掉系统级
    }
    
    3.4.2 然后再CaptureActivity中会调用initCamera(surfaceHolder),在此处需要初始化一个SurfaceView,并取得其SurfaceHolder,并需要保证该SurfaceView已经被创建,代码及注释如下

    initCamera(SurfaceHolder)

    initCamera(SurfaceHodler surfaceHolder){
         cameraManager.openDriver(surfaceHolder);//此处打开相机,并设置相机的相关属性,然后把相机预览图像通过SurfaceHodler显示在SurfaceView,(cameraObject.setPreviewDisplay(holder))
      // Creating the handler starts the preview, which can also throw a RuntimeException.
      if (handler == null) {
        handler = new CaptureActivityHandler(this, decodeFormats, decodeHints, characterSet, cameraManager);//新建处理事件调度中心,在初始化时会创建一个,子线程,并在该线程中解析条码,解析完毕后,在回传到该CaptureActivityHandler中处理
      }
    }
    
    3.4.3 我们看下CaptureActivityHandler的构造函数,在该构造函数中,会初始化一个子线程DecodeThread用来解析条形码并开启,同时开启相机的预览。需要注意的是此时的相机已经初始化完毕

    构造函数如下:

     CaptureActivityHandler(CaptureActivity activity,
                         Collection<BarcodeFormat> decodeFormats,
                         Map<DecodeHintType,?> baseHints,
                         String characterSet,
                         CameraManager cameraManager) {
    this.activity = activity;
    decodeThread = new DecodeThread(activity, decodeFormats, baseHints, characterSet,
        new ViewfinderResultPointCallback(activity.getViewfinderView()));
    decodeThread.start();
    state = State.SUCCESS;
    
    // Start ourselves capturing previews and decoding.
    this.cameraManager = cameraManager;
    cameraManager.startPreview();
    restartPreviewAndDecode();
    }
    
    3.4.4 DecodeThread继承自Thread,在该Thread的run函数中会新见一个消息队列,并用于解析条形码

    其run函数如下

      @Override
      public void run() {
        Looper.prepare();
        handler = new DecodeHandler(activity, hints);//在该子线程中新建一个消息队列,以接收数据并解析条形码的信息
        handlerInitLatch.countDown();
        Looper.loop();
      }
    
    3.4.5 在DecodeHandler中的处理信息的主要代码如下:

    handleMessage()代码如下,该信息的发送正是在CameraManager初始化时初始化的相机的PreviewCallBack中调用的

    @Override
     public void handleMessage(Message message) {
    if (message == null || !running) {
      return;
    }
    switch (message.what) {
      case R.id.decode:
        decode((byte[]) message.obj, message.arg1, message.arg2);
        break;
      case R.id.quit:
        running = false;
        Looper.myLooper().quit();
        break;
    }
    }
    
    3.4.6 PreViewCallback的代码如下:

    在相机预览到图片之后会调用previewHandler处理消息,该previewHandler的设置是通过CameraManager的requestPreviewFrame(Handler handler, int message)设置,而该方法的调用是在CaptureActivityHandler中调用的其中的handler传入的正是decodeThread.getHandler()即DecodeHandler

    final class PreviewCallback implements Camera.PreviewCallback {
    
      private static final String TAG = PreviewCallback.class.getSimpleName();
    
      private final CameraConfigurationManager configManager;
      private Handler previewHandler;
      private int previewMessage;
    
      PreviewCallback(CameraConfigurationManager configManager) {
        this.configManager = configManager;
      }
    
      void setHandler(Handler previewHandler, int previewMessage) {
        this.previewHandler = previewHandler;
        this.previewMessage = previewMessage;
      }
    
      @Override
      public void onPreviewFrame(byte[] data, Camera camera) {
        Point cameraResolution = configManager.getCameraResolution();
        Handler thePreviewHandler = previewHandler;
        if (cameraResolution != null && thePreviewHandler != null) {
          Message message = thePreviewHandler.obtainMessage(previewMessage, cameraResolution.x,
              cameraResolution.y, data);
          message.sendToTarget();
          previewHandler = null;
        } else {
          Log.d(TAG, "Got preview callback, but no handler or resolution available");
        }
      }
    
    }
    
    3.4.7 中间还有重要的一个过程即为设置需要解码的格式都哪些,Demo中有两种设置,在DecodeThread的构造函数中可以看出,最终支持哪些解码格式由此处决定

    DecodeThread构造函数如下

     DecodeThread(CaptureActivity activity,
               Collection<BarcodeFormat> decodeFormats,
               Map<DecodeHintType,?> baseHints,
               String characterSet,
               ResultPointCallback resultPointCallback) {
    
    this.activity = activity;
    handlerInitLatch = new CountDownLatch(1);
    
    hints = new EnumMap<>(DecodeHintType.class);
    if (baseHints != null) {
      hints.putAll(baseHints);
    }
    
    // The prefs can't change while the thread is running, so pick them up once here.
    if (decodeFormats == null || decodeFormats.isEmpty()) {//没有设置,则根据设置要解码的格式重新进行添加
      SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
      decodeFormats = EnumSet.noneOf(BarcodeFormat.class);
      if (prefs.getBoolean(PreferencesActivity.KEY_DECODE_1D_PRODUCT, true)) {
        decodeFormats.addAll(DecodeFormatManager.PRODUCT_FORMATS);
      }
      if (prefs.getBoolean(PreferencesActivity.KEY_DECODE_1D_INDUSTRIAL, true)) {
        decodeFormats.addAll(DecodeFormatManager.INDUSTRIAL_FORMATS);
      }
      if (prefs.getBoolean(PreferencesActivity.KEY_DECODE_QR, true)) {
        decodeFormats.addAll(DecodeFormatManager.QR_CODE_FORMATS);
      }
      if (prefs.getBoolean(PreferencesActivity.KEY_DECODE_DATA_MATRIX, true)) {
        decodeFormats.addAll(DecodeFormatManager.DATA_MATRIX_FORMATS);
      }
      if (prefs.getBoolean(PreferencesActivity.KEY_DECODE_AZTEC, false)) {
        decodeFormats.addAll(DecodeFormatManager.AZTEC_FORMATS);
      }
      if (prefs.getBoolean(PreferencesActivity.KEY_DECODE_PDF417, false)) {
        decodeFormats.addAll(DecodeFormatManager.PDF417_FORMATS);
      }
    }
    hints.put(DecodeHintType.POSSIBLE_FORMATS, decodeFormats);
    
    if (characterSet != null) {
      hints.put(DecodeHintType.CHARACTER_SET, characterSet);
    }
    hints.put(DecodeHintType.NEED_RESULT_POINT_CALLBACK, resultPointCallback);
    Log.i("DecodeThread", "Hints: " + hints);
    

    }

    四、根据需求我们需要做如下优化

    4.1.我们设置扫码界面为竖屏,在Manifest文件的相关Activity标签中添加以下属性
    android:configChanges="keyboard|orientation"
    android:screenOrientation="portrait"
    

    同是,我们在onresum()不再根据当前手机的物理方向去修改activity的方向,而是直接设置,该方法为Activity的方法

    activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT);
    
    4.2.解决修改为竖屏后,一维条形码仍需要横置手机才能扫描出结果的问题,该问题原因是相机的预览的图像是竖直方向的,但是实际在相机的PreviewCallback中的数据依然是横向的格式,此时解码器在解码一维的条形码时等于是纵向解析条形码,而对于一维码纵向识别不到,当横置手机时才是以横向解析条形码。因此我们可以直接转置在相机的PreviewCallback中拿到的数据,转置后即相当于数据为纵向格式,具体操作如下:
    @Override
    public void onPreviewFrame(byte[] data, Camera camera) {
        Point cameraResolution = configManager.getCameraResolution();//拿取相机的分辨率
        int previewHeight = cameraResolution.y;
        int previewWidth = cameraResolution.x;
        byte[] rotatedData = new byte[data.length];//新建转置byte数组
        for (int y = 0; y < previewHeight; y++) {//转置原数组,纵向横向数据互换
            for (int x = 0; x < previewWidth; x++)
                rotatedData[x * previewHeight + previewHeight - y - 1] = data[x + y * previewWidth];
        }
        int tmp = previewWidth;
        previewWidth = previewHeight;
        previewHeight = tmp;//更改记录数据的宽高
        data = rotatedData;
        .... 
        //发送数据到解码子线程中进行解码
    }
    

    另外,同时需要修改CameraManaget中的有效数据区域的生成方法,

    public synchronized Rect getFramingRectInPreview() {
        if (framingRectInPreview == null) {
            Rect framingRect = getFramingRect();
            if (framingRect == null) {
                return null;
            }
            Rect rect = new Rect(framingRect);
            Point cameraResolution = configManager.getCameraResolution();
            Point screenResolution = configManager.getScreenResolution();
            if (cameraResolution == null || screenResolution == null) {
                // Called early, before wakeup even finished
                return null;
            }
           /* 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;*/
    
            //FIX 竖屏一维码扫不出,在转置相机PreviewCallback中的数据后,该有效裁剪区域不不修改会导致,裁剪时裁剪范围超出数据范围,此时相机preview图像为纵向,cameraResolution.y相当于图像的宽,cameraResolution.x相当于图像的高
            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;
            framingRectInPreview = rect;
        }
        Log.d(TAG, "getFramingRectInPreview: framingRectInPreview" + framingRectInPreview.toString()+"--framingRect="+framingRect.toString());
        return framingRectInPreview;
    }
    
    4.3 添加解析相册中的图片的方法
    4.3.1 在ZXing解码中可以使用 RGBLuminanceSource 构建解码所需的BinaryBitmap,而RGBLuminanceSource需要的构造参数是图像的像素数据,类型为int[],我们可以通过以下方法从有效的相册图片路径path生成所需的数据:
    //从有效的绝对路径地址中生成构建BinaryBitmap所需要的图片像素数据 int[]
     public static PicDataInfo getPicInfo(String picPath) {
        if(TextUtils.isEmpty(picPath)){
            return null;
        }
        PicDataInfo picDataInfo = new PicDataInfo();//自定义的类用来保存生成的数据
        try {
            File picFile = new File(picPath);
            if (!picFile.exists()) {
                return null;
            }
    
            FileInputStream fis = new FileInputStream(picFile);
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024 * 10];
            int len = 0;
            while ((len = fis.read(buffer)) != -1) {
                baos.write(buffer, 0, len);
            }
            baos.flush();
            picDataInfo.data = baos.toByteArray();
            baos.close();
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inJustDecodeBounds = true; // 先获取原大小
            Bitmap bitmap = BitmapFactory.decodeByteArray(picDataInfo.data, 0, picDataInfo.data.length);
            picDataInfo.height = bitmap.getHeight();
            picDataInfo.width = bitmap.getWidth();
            int[] pixData = new int[picDataInfo.width * picDataInfo.height];
            bitmap.getPixels(pixData, 0, picDataInfo.width, 0, 0, picDataInfo.width, picDataInfo.height);//生成pixData
            picDataInfo.pixData = pixData;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            return picDataInfo;
        }
    }
    
    4.3.2 通过上一步生成的pixData,对其进行解码,代码如下
    //解码相册中的图片数据
    public String decodeCode(int[] pixels, Rect validArea) {
        Result rawResult = null;
        RGBLuminanceSource source = new RGBLuminanceSource(validArea.width(), validArea.height(), pixels);
        if (source != null) {
            BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
            try {
                rawResult = multiFormatReader.decodeWithState(bitmap);
                Log.d(TAG, "decode result:" + rawResult.toString());
            } catch (ReaderException re) {
                // continue
            } finally {
                multiFormatReader.reset();
            }
        }
        if (rawResult != null) {
            return rawResult.getText();
        }
        return null;
    }
    

    4.4.自定义扫描窗口的动画及样式,我们不需要在解析过程中回显可能的的定位位置,所以官方Demo中原有的ViewFinderView,大部分我们不需使用,并且在构建解码器所需的解码规则标志集合(Map ”DecodeHintType,Object>)中不需要设置相关回调方法。我们唯一需要的是CameraManager中根据相机参数生成的一个有效扫描区域,我们需要在该区域上绘制相关的效果即可

    扫描动画效果的实现可以参考该链接:http://blog.csdn.net/M075097/article/details/78533141

    五、根据以上封装的一个方便集成和使用简单的版本,如有需要可以进行参考,使用方式见工程目录下的README,源码地址为:https://github.com/M075097/MoZXing

    该工程特点如下:

    • 1.依照常用的主线裁掉不需要的代码
    • 2.修改扫面页面为纵向
    • 3.添加了从相册选取图片识别的功能
    • 4.修改了扫码窗口的样式,并可部分定制扫描窗口
    • 5.给予了简单的封装,集成进现有工程更为简单和清晰
    • 6.底层的ZXing解码核心没有改变,只是上层的相机调用/预览,及相关逻辑处理进行了调整
    展开全文
  • 在代码编制上巧妙地利用构成计算机内部逻辑基础的"0"、"1"比特流的概念,使用若干个与二进制相对应的几何形体来表示文字数值信息,通过图象输入设备或光电扫描设备自动识读以实现信息自动处理:它具有条码技术的一些...
  • dewo 二维码扫描设备开发文档,lib,源代码
  • STM32F103ZET6控制二维码模块GM65(扫描数据为123任意排列组合,可自己修改需要扫描内容)
  • 二维码扫描技术代码

    2017-10-31 11:56:07
    亲测,可以使用。利用zxingbarcode的精简包,android studio的软件工具制作的。
  • arduino GM65扫码模块

    2019-01-23 22:02:40
    ARDUINO gm65扫码模块 + string强转 int 进行大小比较
  • 微光二维码扫描器通讯协议V2.8
  • Zxing可以实现使用手机的内置的摄像头完成条形码的扫描及解码。该项目可实现的条形码编码和解码。目前支持以下格式:UPC-A,UPC-E、EAN-8,EAN-13、39码、93码。ZXing是个很经典的条码/二维码识别的开源类库,以前在...
  • 二维码扫描的源代码Demo
  • GM65模块配套代码,在STM32精英板战舰,扫描二维码会有LED的闪烁
  • 这是一个系列,我们将其命名为android最佳实践,如果你还没有看之前的文章: Android最佳实践(一) ...上一节,我们编写了contact模块,极大的简化了联系人的获取,而且提供了两种方式,一种是通过手机内置app获...

    这是一个系列,我们将其命名为android最佳实践,如果你还没有看之前的文章:

    Android最佳实践(一)

    android最佳实践(二)

    android最佳实践(三)

    android最佳实践(四)

    android最佳实践(五)

    上一节,我们编写了contact模块,极大的简化了联系人的获取,而且提供了两种方式,一种是通过手机内置app获取联系人手机号码,另外一种是通过自写UI,来获取得到联系人手机号码。
    这一节,我们将会编写qrcode模块,该模块致力于简化扫描二维码的代码编写,同时也加上了Android 6.0的动态权限检查。

    那么我们开始吧。

    多模块的管理

    现阶段,我们已经有两个模块了,那么其对应得buildToolsVersion等都是一样,那以后模块多了,更改这些参数是不是会非常麻烦,有人说了我可以在project中定义变量,然后在各个子模块中引用,那么真的有必要吗,是否有更简单的办法。

    下面是我的project中的build.gradle文件,其含义是除了app模块,其他子模块一律为依赖模块,且定义了一些参数和内部库,当我们的子模块有自己特殊的库,你需要复写dependencies就可以了。

    subprojects{
        configure(allprojects - project(':app')) {
            apply plugin: 'com.android.library'
            android {
                compileSdkVersion 23
                buildToolsVersion '23.0.2'
    
                defaultConfig {
                    minSdkVersion 16
                    targetSdkVersion 23
                    versionCode 1
                    versionName "1.0"
                }
                lintOptions {
                    abortOnError false
                }
            }
            dependencies {
                testCompile 'junit:junit:4.12'
                compile 'com.android.support:appcompat-v7:23.1.1'
            }
            apply from: '../gradle/maven_push.gradle'
        }
    }
    

    那么例如我们的扫描二维码模块,你就应该在该子模块的gradle文件中添加如下代码:

    dependencies{
        compile 'com.google.zxing:core:3.2.0'
    }
    

    该含义为添加google提供的zxing依赖包,大家可以根据zxing依赖包进行二次开发,但是你会发现,使用zxing难度颇大,为何没有人进行其相关的二次封装,我能够更简单的调用呢,这就是我写该模块的目的。

    工厂模式

    该模块使用工厂模式,将实现和接口分离,同时为未来提供多样化的产品带来可能,用户可定制扫描二维码界面。同时提供了,该模块适合于activity和fragment以及v4包中的fragment。

    用法

    在你的activity或者你的fragment中调用:

    QrcodeFactory.newQrcode(this).start();
    

    因为该方法会调用相关的界面,所以如果你想接收数据,需要在该类中重写onActivityResult方法,在该方法内部调用QrCode模块的onActivityResult方法。例如这样:

    @Override
        public void onActivityResult(int requestCode, int resultCode, final Intent data) {
            mQrcode.onActivityResult(requestCode, resultCode, data, new QrcodeCallback() {
                @Override
                public void onSuccess(@NonNull QrcodeInfo info) {
                    String textInfo = "二维码信息" + info.getResult() + "图片高度" + info.getHeight() + "图片宽度" + info.getWidth();
                    mText.setText(textInfo);
                    mImageView.setImageBitmap(info.getQrCodeImage());
                }
    
                @Override
                public void onFailed(@NonNull String errMsg) {
                    mText.setText(errMsg);
                }
            });
        }
        

    当你的app需要Android6.0的适配,你需要对获取动态权限结果,你需要在该类中重写onRequestPermissionsResult方法,例如这样:

    @Override
        public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
            mQrcode.onRequestPermissionsResult(requestCode, permissions, grantResults, new com.neu.qrcode.callback.PermissionResultCallback() {
                @Override
                public void denyPermission() {
                    mText.setText("App无权限");
                }
            });
        }
    

    后续

    扫描二维码模块,因为每个公司都想有自己的扫描界面,所以自定义化扫描界面显得尤为重要,而利用camera自定义扫描界面,代码量和难度颇大,该项目后续会添加部分UI模板,适用于扫描界面的定制。大家可以fork或star我的github,https://github.com/neuyu/android-best-practices

    展开全文
  • 本资源是详细写明了 微光二维码扫码器的串口协议
  • 实现二维码识别的流程 开启Camera 创建ImageReader 通过ImageReader获取surface对像 设置surface对象给camera并启动preview 当有preview数据产生时ImageReader的onImageAvailable回调会被调用 调用ImageReader 的...
  • 第一步:将libzxing Modile导入项目中 点击OK,然后点击File——Structure... * 参数:1....这样,一个简单的二维码扫描生成App就完成了 依赖包下载地址: https://download.csdn.net/my 如需要:可私信
  • 二维码项目开发学习必备!!!由开源Zxing项目修改而来,简单易用;包括手机二维码扫描和识别模块;基于Android;
  • 最近项目上需要开发扫描二维码进行签到的功能,主要用于开会签到的场景,所以为了避免作弊,我们再开发时只采用直接扫描的方式,并且要屏蔽从相册读取图片,此外还在二维码扫描成功...iOS系统原生的二维码扫描模块
  • 扫描二维码功能模块,可以放到项目里使用,完美支持多屏幕分辨率。
  • 51单片机二维码识别

    千次阅读 2019-07-23 10:05:39
    现在在做一个硬件项目,主要是用“高端的”51单片机连一个摄像头完成二维码识别的问题。 目录: 一、解决方案 二、详细分析 一、解决方案: 现在的需求是:给出二维码(可能存在图像偏移、旋转等问题),输出...
  • 条码二维码扫描demo

    2019-07-29 15:43:38
    可用于扫描现有的大多数条码与二维码 欢迎学习使用
  • 如果使用ZBar解码并且使用ZXing3.1.0扫描,只需要修改ZXingProj中的DecodeHandler解码模块,将ZXing的解码换成ZBar即可 如: private void decode(byte[] data, int width, int height) { Size size = activity....
  • 请注意:本图片来自杭州城章科技有限公司提供的GROW GM65 条码二维码扫描识别模块 兼容大部分条码和二维码产品,图片仅供参考,GROW GM65 条码二维码扫描识别模块 兼容大部分条码和二维码产品会因为批次的不同可能与...
  • android开发二维码扫描

    万次阅读 2017-08-02 19:40:57
    最近项目开发中,遇到了二维码的问题!于是就去Google,搜索结果提及最多的就是ZXing了!当然这也是Google推荐的! ZXingGithub地址:https://code.google.com/p/zxing/ 但是ZXing存在的问题也很明显:包太大,...
  •  Barcode模块管理条码扫描,提供常见的条码(二维码及一维码)的扫描识别功能,可调用设备的摄像头对条码图片扫描进行数据输入。通过plus.barcode可获取条码码管理对象。 二、实现的效果 三、实现 代码 <!...
  • MUI 结合 HTML5+ 实现的二维码扫描功能

    千次阅读 热门讨论 2019-04-21 12:07:10
    MUI 结合 HTML5+ 实现的二维码扫描功能 一、说明 二维码的扫描在手机APP的开发中是很常见的一个需求,毕竟用的也多嘛。html5+ 提供了Barcode模块管理条码扫描,支持常见的条码(一维码及二维码)的扫描识别功能。...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 22,062
精华内容 8,824
关键字:

二维码扫描模块