当前位置:   article > 正文

arm下编译并运行zbar实现图片二维码解析_zbar识别模糊二维码 assert

zbar识别模糊二维码 assert
  1. 目标
    1. 在linux开发板上实现jpg图片二维码的解析功能
  2. 验证流程
    1. 生成指定内容的二维码图片
    2. 利用djpeg将jpg图片解析成rgb数据
    3. 将rgb数据输入到zbar进行内容识别
  3. 二维码生成
    1. 很多网页版可以直接根据输入内容生成二维码图片
    2. 下载图片,另存为jpg格式 hello.jpg
  4. djpeg工具
    1. 下载源码Directory Listing of /files (ijg.org)
    2. 编译
      1. ./configure --host=arm-linux-gnueabihf --target=arm-linux-gnueabihf --prefix=/home/xxx/linux/nfs/rootfs2/bin/jpg
      2. make install
    3. 开发板上面运行测试
      1. cd /bin/jpg
      2. ./djpeg hello.jpg > hw.ppm
  5. ppm格式说明
    1. ppm头部为P6. 图像长度 图像宽度. 最大像素.
      1. P6代表格式为pixelmap binary 
    2. 后面接着的就是长宽对应的各个pixel的rgb数据
  6. zbar库
    1. 下载源码ZBar bar code reader - Download (sourceforge.net)
    2. 编译lib
      1. ./configure --prefix=/home/xxx/linux/nfs/rootfs2/bin/zbar --disable-video --without-imagemagick --without-gtk --without-qt --without-python CFLAGS=""  --host=arm-linux-gnueabihf --target=arm-linux-gnueabihf

      2. make install

      3. 注意:配置里面加了很多--without项,是为了编译通过,免得去折腾那些环境;向zbar本身也是支持直接解析img的,但是编译会报错,因此采取曲线救国方式,通过直接调用zbar的lib来实现解析;本质上大同小异

  7. 调用zbar库的应用程序

    1. 程序主要分为两部分

      1. 一部分是将djpeg生成的ppm文件转换成y800数据

      2. 另一部分是将y800数据输入到zbar的库去解析,这部分主要是参考zbarimg.c

    2. code:头文件

      1. #include <stdio.h>
      2. #include <stdlib.h>
      3. #include <string.h>
      4. typedef struct{
      5. char *filename;
      6. int w;
      7. int h;
      8. char *buf;
      9. }ppm_t;
      10. int ppm2y800(ppm_t *ppm);
    3. code:part1

      1. #include "ppm.h"
      2. int ppm2y800(ppm_t *ppm)
      3. {
      4. FILE *fd = fopen(ppm->filename, "rb");
      5. if (NULL == fd){
      6. printf("open %s failed.\n", ppm->filename);
      7. return -1;
      8. }
      9. fseek(fd, 0, SEEK_END);
      10. int len = ftell(fd);
      11. printf("%s len:%d\n", ppm->filename, len);
      12. fseek(fd, 0, SEEK_SET);
      13. unsigned char *pbuf = malloc(len);
      14. int ret = fread(pbuf, 1, len, fd);
      15. if (ret != len){
      16. printf("read %s failed.\n", ppm->filename);
      17. return -2;
      18. }
      19. if (0x50 != pbuf[0] || 0x36 != pbuf[1] || 0x0a != pbuf[2]){
      20. printf("head:%c %c is not P6. \n", pbuf[0], pbuf[1]);
      21. return -3;
      22. }
      23. // find width
      24. int idx = 3;
      25. while(pbuf[idx] != 0x20){
      26. idx++;
      27. }
      28. char str[10] = {0};
      29. memcpy(str, pbuf+3, idx-3);
      30. ppm->w = strtol(str, NULL, 10);
      31. printf("ppm->w:%d\n", ppm->w);
      32. // find height
      33. idx++;
      34. int idxe = idx;
      35. while(pbuf[idxe] != 0x0a){
      36. idxe++;
      37. }
      38. memcpy(str, pbuf+idx, idxe-idx);
      39. str[idxe-idx] = 0;
      40. ppm->h = strtol(str, NULL, 10);
      41. printf("ppm->h:%d\n", ppm->h);
      42. // find head tail
      43. idxe++;
      44. while(pbuf[idxe] != 0x0a){
      45. idxe++;
      46. }
      47. // check len is valid or not
      48. int explen = idxe + 1 + ppm->w * ppm->h * 3;
      49. if (len != explen){
      50. printf("ppm w:%d h:%d idxe:%d explen:%d is not fit len:%d. \n", ppm->w, ppm->h, idxe, explen, len);
      51. return -3;
      52. }
      53. // malloc and set y buf
      54. unsigned char *ybuf = malloc(ppm->w * ppm->h);
      55. unsigned char r, g, b;
      56. for (int i = 0; i < ppm->w * ppm->h; i++){
      57. r = pbuf[idxe + 1 + i * 3];
      58. g = pbuf[idxe + 2 + i * 3];
      59. b = pbuf[idxe + 3 + i * 3];
      60. ybuf[i] = (char)(0.257 * r + 0.504 * g + 0.098 * b + 16);
      61. }
      62. ppm->buf = ybuf;
      63. printf("ybuf[0]:%x rgb:%x %x %x\n", ybuf[0], r, g, b);
      64. free(pbuf);
      65. fclose(fd);
      66. return 0;
      67. }
    4. code:part2

      1. #include <assert.h>
      2. #include <zbar.h>
      3. #include "ppm.h"
      4. ppm_t ppm = {0};
      5. static zbar_processor_t *processor = NULL;
      6. static int notfound = 0, exit_code = 0;
      7. static int num_images = 0, num_symbols = 0;
      8. static int xmllvl = 0;
      9. char *xmlbuf = NULL;
      10. unsigned xmlbuflen = 0;
      11. int main(char argc, char **argv){
      12. int found = 0;
      13. for (int i = 0; i < argc; i++){
      14. printf("%s ", argv[i]);
      15. }
      16. if (argc < 2){
      17. printf("argc:%d is less than 2.\n", argc);
      18. return -1;
      19. }
      20. ppm.filename = argv[1];
      21. ppm2y800(&ppm);
      22. // FILE *fd = fopen("400x400_y800.yuv", "wb");
      23. // fwrite(ppm.buf, 1, ppm.h*ppm.w, fd);
      24. // fclose(fd);
      25. processor = zbar_processor_create(0);
      26. assert(processor);
      27. if(zbar_processor_init(processor, NULL, 0)) {
      28. zbar_processor_error_spew(processor, 0);
      29. return(1);
      30. }
      31. zbar_image_t *zimage = zbar_image_create();
      32. assert(zimage);
      33. zbar_image_set_format(zimage, *(unsigned long*)"Y800");
      34. zbar_image_set_size(zimage, ppm.w, ppm.h);
      35. zbar_image_set_data(zimage, ppm.buf, ppm.h*ppm.w, zbar_image_free_data);
      36. zbar_process_image(processor, zimage);
      37. // output result data
      38. const zbar_symbol_t *sym = zbar_image_first_symbol(zimage);
      39. for(; sym; sym = zbar_symbol_next(sym)) {
      40. zbar_symbol_type_t typ = zbar_symbol_get_type(sym);
      41. if(typ == ZBAR_PARTIAL)
      42. continue;
      43. else if(!xmllvl)
      44. printf("%s%s:%s\n",
      45. zbar_get_symbol_name(typ),
      46. zbar_get_addon_name(typ),
      47. zbar_symbol_get_data(sym));
      48. else if(xmllvl < 0)
      49. printf("%s\n", zbar_symbol_get_data(sym));
      50. else {
      51. if(xmllvl < 3) {
      52. xmllvl++;
      53. // printf("<index num='%u'>\n", seq);
      54. }
      55. zbar_symbol_xml(sym, &xmlbuf, &xmlbuflen);
      56. printf("%s\n", xmlbuf);
      57. }
      58. found++;
      59. num_symbols++;
      60. }
      61. if(xmllvl > 2) {
      62. xmllvl--;
      63. printf("</index>\n");
      64. }
      65. fflush(stdout);
      66. zbar_image_destroy(zimage);
      67. zbar_processor_destroy(processor);
      68. return 0;
      69. }
    5. 编译:

      1. arm-linux-gnueabihf-gcc $^ $(CFLAGS) $(LDFLAGS)  -lzbar -o zbar

  8. 运行测试

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/爱喝兽奶帝天荒/article/detail/974539
推荐阅读
相关标签
  

闽ICP备14008679号