AirCAMERA_1030.lua 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. local AirCAMERA_1030 =
  2. {
  3. id = camera.USB,
  4. -- capture_photo_buff:拍照使用的zbuff缓冲区
  5. -- opend:是否已经成功打开
  6. }
  7. -- 摄像头事件回调函数
  8. local function camera_scan_cbfunc(id, str)
  9. log.info("camera_scan_cbfunc", id, str)
  10. --str为string类型时,表示扫码模式下扫码结果的回调
  11. --str为扫码识别后的解码字符串
  12. if type(str) == 'string' then
  13. log.info("scan code result", str)
  14. --str为false时,表示摄像头没有正常工作
  15. elseif str == false then
  16. log.error("no data")
  17. --str为number类型时,表示拍摄到的照片字节大小
  18. else
  19. log.info("capture photo data", str)
  20. sys.publish("AirCAMERA_1030_CAPTURE_IND", true)
  21. end
  22. end
  23. --打开AirCAMERA_1030摄像头;
  24. --usb_port_id:number类型;
  25. -- 表示USB端口号,当存在USB HUB时,才有意义,如果没有USB HUB,使用1即可;
  26. -- 取值范围:1到4;
  27. -- 如果没有传入此参数,则默认为1;
  28. --width:number类型;
  29. -- 表示摄像头拍照时的宽度,单位为像素;
  30. -- 取值范围:大于0,并且和height的乘积不能超过1280*720;
  31. -- 如果没有传入此参数,则默认为1280;
  32. --height:number类型;
  33. -- 表示摄像头拍照时的宽度,单位为像素;
  34. -- 取值范围:大于0,并且和width的乘积不能超过1280*720;
  35. -- 如果没有传入此参数,则默认为720;
  36. --返回值:成功返回true,失败返回false
  37. function AirCAMERA_1030.open(usb_port_id, width, height)
  38. --如果没有传入参数,usb_port_id,width和height都使用默认值
  39. usb_port_id = usb_port_id or 1
  40. width = width or 1280
  41. height = height or 720
  42. --判断usb_port_id参数的合法性
  43. if not (usb_port_id>=1 and usb_port_id<=4) then
  44. log.error("AirCAMERA_1030.open error", "invalid usb_port_id", usb_port_id)
  45. return false
  46. end
  47. --判断width和height参数的合法性
  48. if width<0 or height<0 or width*height>1280*720 then
  49. log.error("AirCAMERA_1030.open error", "invalid width or height", width, height)
  50. return false
  51. end
  52. --如果没有分配过存储照片的内存数据,此处申请200KB的zbuff内存空间
  53. --如果拍照过程中,发现200KB的空间不够使用,会自动扩充空间
  54. if AirCAMERA_1030.capture_photo_buff==nil then
  55. AirCAMERA_1030.capture_photo_buff = zbuff.create(200 * 1024, 0, zbuff.HEAP_PSRAM)
  56. if AirCAMERA_1030.capture_photo_buff == nil then
  57. log.error("AirCAMERA_1030.open error", "malloc mem fail")
  58. return false
  59. end
  60. end
  61. --初始化摄像头
  62. if not camera.init({id = AirCAMERA_1030.id, sensor_width = width, sensor_height = height, usb_port = usb_port_id}) then
  63. log.error("AirCAMERA_1030.open error", "camera.init fail")
  64. AirCAMERA_1030.capture_photo_buff:free()
  65. AirCAMERA_1030.capture_photo_buff = nil
  66. return false
  67. end
  68. --注册摄像头事件回调函数camera_scan_cbfunc
  69. --摄像头的异步事件都会通过回调函数通知结果
  70. camera.on(AirCAMERA_1030.id, "scanned", camera_scan_cbfunc)
  71. --设置摄像头已经成功打开的标志
  72. AirCAMERA_1030.opend = true
  73. return true
  74. end
  75. --使用AirCAMERA_1030摄像头拍照;必须在task中使用
  76. --返回值:成功返回照片的zbuff内存数据,失败返回false
  77. function AirCAMERA_1030.capture()
  78. --检查是否运行在task中
  79. local co, is_main = coroutine.running()
  80. -- Lua 5.1: 直接返回协程(主协程返回 nil)
  81. -- Lua 5.2+: 返回协程和是否是主协程
  82. if type(co) == "thread" and is_main then
  83. log.error("AirCAMERA_1030.capture error", "must in task", type(co) == "thread", is_main)
  84. return false
  85. end
  86. if co == nil then
  87. log.error("AirCAMERA_1030.capture error", "must in task", co)
  88. return false
  89. end
  90. --如果摄像头没有打开
  91. if not AirCAMERA_1030.opend then
  92. log.error("AirCAMERA_1030.capture error", "camera isn't opend")
  93. return false
  94. end
  95. if not camera.start(AirCAMERA_1030.id) then
  96. log.error("AirCAMERA_1030.capture error", "camera.start fail")
  97. return false
  98. end
  99. --启动拍照动作,拍照质量90%,如果拍照成功,照片数据存储到AirCAMERA_1030.capture_photo_buff的zbuff内存中
  100. if not camera.capture(AirCAMERA_1030.id, AirCAMERA_1030.capture_photo_buff, 1) then
  101. log.error("AirCAMERA_1030.capture error", "camera.capture sync fail")
  102. return false
  103. end
  104. --阻塞等待拍照结果,如果5秒钟没有等到结果,超时失败退出阻塞等待状态
  105. result = sys.waitUntil("AirCAMERA_1030_CAPTURE_IND", 5000)
  106. --打印拍摄的照片字节大小
  107. log.info("AirCAMERA_1030.capture", "photo size", AirCAMERA_1030.capture_photo_buff:used())
  108. if not result then
  109. log.error("AirCAMERA_1030.capture error", "camera.capture async fail")
  110. return false
  111. end
  112. --停止拍照
  113. camera.stop(AirCAMERA_1030.id)
  114. --返回存储照片数据的zbuff内存
  115. return AirCAMERA_1030.capture_photo_buff
  116. end
  117. --关闭AirCAMERA_1030摄像头
  118. --返回值:成功返回true,失败返回false
  119. function AirCAMERA_1030.close()
  120. --如果摄像头还没有打开,直接返回成功
  121. if not AirCAMERA_1030.opend then
  122. log.info("AirCAMERA_1030.close ok", "no open, needn't close")
  123. return true
  124. end
  125. --关闭摄像头
  126. camera.close(AirCAMERA_1030.id)
  127. --释放存储照片数据的zbuff内存
  128. if AirCAMERA_1030.capture_photo_buff ~= nil then
  129. AirCAMERA_1030.capture_photo_buff:free()
  130. AirCAMERA_1030.capture_photo_buff = nil
  131. end
  132. --复位摄像头已经成功打开的标志
  133. AirCAMERA_1030.opend = false
  134. return true
  135. end
  136. return AirCAMERA_1030