camera.js 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. const vs = `
  2. attribute vec3 aPos;
  3. attribute vec2 aVertexTextureCoord;
  4. varying highp vec2 vTextureCoord;
  5. void main(void){
  6. gl_Position = vec4(aPos, 1);
  7. vTextureCoord = aVertexTextureCoord;
  8. }
  9. `
  10. const fs = `
  11. varying highp vec2 vTextureCoord;
  12. uniform sampler2D uSampler;
  13. void main(void) {
  14. gl_FragColor = texture2D(uSampler, vTextureCoord);
  15. }
  16. `
  17. const vertex = [
  18. -1, -1, 0.0,
  19. 1, -1, 0.0,
  20. 1, 1, 0.0,
  21. -1, 1, 0.0
  22. ]
  23. const vertexIndice = [
  24. 0, 1, 2,
  25. 0, 2, 3
  26. ]
  27. const texCoords = [
  28. 0.0, 0.0,
  29. 1.0, 0.0,
  30. 1.0, 1.0,
  31. 0.0, 1.0
  32. ]
  33. function createShader(gl, src, type) {
  34. const shader = gl.createShader(type)
  35. gl.shaderSource(shader, src)
  36. gl.compileShader(shader)
  37. if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
  38. console.error(`Error compiling shader: ${gl.getShaderInfoLog(shader)}`)
  39. }
  40. return shader
  41. }
  42. const buffers = {}
  43. function createRenderer(canvas, width, height) {
  44. const gl = canvas.getContext('webgl')
  45. if (!gl) {
  46. console.error('Unable to get webgl context.')
  47. return null
  48. }
  49. const info = wx.getSystemInfoSync()
  50. gl.canvas.width = info.pixelRatio * width
  51. gl.canvas.height = info.pixelRatio * height
  52. gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight)
  53. const vertexShader = createShader(gl, vs, gl.VERTEX_SHADER)
  54. const fragmentShader = createShader(gl, fs, gl.FRAGMENT_SHADER)
  55. const program = gl.createProgram()
  56. gl.attachShader(program, vertexShader)
  57. gl.attachShader(program, fragmentShader)
  58. gl.linkProgram(program)
  59. if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
  60. console.error('Unable to initialize the shader program.')
  61. return null
  62. }
  63. gl.useProgram(program)
  64. const texture = gl.createTexture()
  65. gl.activeTexture(gl.TEXTURE0)
  66. gl.bindTexture(gl.TEXTURE_2D, texture)
  67. gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true)
  68. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST)
  69. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST)
  70. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)
  71. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE)
  72. gl.bindTexture(gl.TEXTURE_2D, null)
  73. buffers.vertexBuffer = gl.createBuffer()
  74. gl.bindBuffer(gl.ARRAY_BUFFER, buffers.vertexBuffer)
  75. gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertex), gl.STATIC_DRAW)
  76. buffers.vertexIndiceBuffer = gl.createBuffer()
  77. gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buffers.vertexIndiceBuffer)
  78. gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(vertexIndice), gl.STATIC_DRAW)
  79. const aVertexPosition = gl.getAttribLocation(program, 'aPos')
  80. gl.vertexAttribPointer(aVertexPosition, 3, gl.FLOAT, false, 0, 0)
  81. gl.enableVertexAttribArray(aVertexPosition)
  82. buffers.trianglesTexCoordBuffer = gl.createBuffer()
  83. gl.bindBuffer(gl.ARRAY_BUFFER, buffers.trianglesTexCoordBuffer)
  84. gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(texCoords), gl.STATIC_DRAW)
  85. const vertexTexCoordAttribute = gl.getAttribLocation(program, 'aVertexTextureCoord')
  86. gl.enableVertexAttribArray(vertexTexCoordAttribute)
  87. gl.vertexAttribPointer(vertexTexCoordAttribute, 2, gl.FLOAT, false, 0, 0)
  88. const samplerUniform = gl.getUniformLocation(program, 'uSampler')
  89. gl.uniform1i(samplerUniform, 0)
  90. return (arrayBuffer, width, height) => {
  91. gl.bindTexture(gl.TEXTURE_2D, texture)
  92. gl.texImage2D(
  93. gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, arrayBuffer
  94. )
  95. gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0)
  96. }
  97. }
  98. Page({
  99. onShareAppMessage() {
  100. return {
  101. title: 'camera',
  102. path: 'packageComponent/pages/media/camera/camera'
  103. }
  104. },
  105. data: {
  106. theme: 'light',
  107. src: '',
  108. videoSrc: '',
  109. position: 'back',
  110. mode: 'scanCode',
  111. result: {},
  112. frameWidth: 0,
  113. frameHeight: 0,
  114. width: 288,
  115. height: 358,
  116. showCanvas: false,
  117. },
  118. onReady() {
  119. this.ctx = wx.createCameraContext()
  120. // const selector = wx.createSelectorQuery();
  121. // selector.select('#webgl')
  122. // .node(this.init)
  123. // .exec()
  124. },
  125. init(res) {
  126. if (this.listener) {
  127. this.listener.stop()
  128. }
  129. const canvas = res.node
  130. const render = createRenderer(canvas, this.data.width, this.data.height)
  131. // if (!render || typeof render !== 'function') return
  132. this.listener = this.ctx.onCameraFrame((frame) => {
  133. render(new Uint8Array(frame.data), frame.width, frame.height)
  134. const {
  135. frameWidth,
  136. frameHeight,
  137. } = this.data
  138. if (frameWidth === frame.width && frameHeight === frame.height) return
  139. this.setData({
  140. frameWidth: frame.width,
  141. frameHeight: frame.height,
  142. })
  143. })
  144. this.listener.start()
  145. },
  146. takePhoto() {
  147. this.ctx.takePhoto({
  148. quality: 'high',
  149. success: (res) => {
  150. this.setData({
  151. src: res.tempImagePath
  152. })
  153. }
  154. })
  155. },
  156. startRecord() {
  157. this.ctx.startRecord({
  158. success: () => {
  159. console.log('startRecord')
  160. }
  161. })
  162. },
  163. stopRecord() {
  164. this.ctx.stopRecord({
  165. success: (res) => {
  166. this.setData({
  167. src: res.tempThumbPath,
  168. videoSrc: res.tempVideoPath
  169. })
  170. }
  171. })
  172. },
  173. togglePosition() {
  174. this.setData({
  175. position: this.data.position === 'front'
  176. ? 'back' : 'front'
  177. })
  178. },
  179. error(e) {
  180. console.log(e.detail)
  181. },
  182. handleShowCanvas() {
  183. this.setData({
  184. showCanvas: !this.data.showCanvas
  185. }, () => {
  186. if (this.data.showCanvas) {
  187. const selector = wx.createSelectorQuery()
  188. selector.select('#webgl')
  189. .node(this.init)
  190. .exec()
  191. }
  192. })
  193. },
  194. onLoad() {
  195. this.setData({
  196. theme: wx.getSystemInfoSync().theme || 'light'
  197. })
  198. if (wx.onThemeChange) {
  199. wx.onThemeChange(({theme}) => {
  200. this.setData({theme})
  201. })
  202. }
  203. }
  204. })