加入下方官方优快云班级,得鸿蒙礼盒
本期活动时间:2025年8月1日-12月31日
如有问题欢迎私聊我呀!
问题现象
当前在H5页面长按二维码图片会触发拖拽动作,如何禁用图片拖拽事件并实现长按识别H5页面的二维码图片。
背景知识
- 禁用H5页面图片拖拽事件:应用侧调用前端页面函数修改img标签的draggable属性。
- 监听H5特定元素的长按事件:通过onContextMenuShow可监听H5中图片的长按事件。
- 识别图像中的二维码:detectBarcode.decodeImage接口可直接识别图像数据中的码图。
解决方案
长按识别H5页面的二维码图片实现步骤如下:
- 通过runJavaScript禁用图片的拖拽事件。
- 通过onContextMenuShow监听图片的长按事件并获取到图片的url。
- 根据URL获取网络图片数据并通过detectBarcode.decodeImage接口识别图片中的二维码。
- Web组件绑定onContextMenuShow监听图片长按事件,获取图片的url并解码。
import web_webview from '@ohos.web.webview'; import promptAction from '@ohos.promptAction'; import { BusinessError } from '@ohos.base'; import { http } from '@kit.NetworkKit'; import { image } from '@kit.ImageKit'; import { detectBarcode, scanBarcode, scanCore } from '@kit.ScanKit'; @Entry @Component struct WebQRScanner { controller: web_webview.WebviewController = new web_webview.WebviewController(); build() { Column() { Web({ src: 'https://example.com', controller: this.controller }) .onPageEnd(() => { // 禁用图片拖拽 this.disableDragScript(); }) .onContextMenuShow((event) => { if (event.param.getMediaType() === ContextMenuMediaType.Image) { // 获取图片并识别二维码 this.scanQRFromWebImage(event.param.getSourceUrl()); return false; } return true; }) } } } - 禁用H5中图片的拖拽事件。
disableDragScript() { const jsCode = ` var images = document.getElementsByTagName('img'); for (var i = 0; i < images.length; i++) { images[i].draggable = false; } true; `; this.controller.runJavaScript(jsCode, (error: BusinessError) => { if (error) { console.error('注入JavaScript失败:', error); } }); } - 根据URL获取网络图片数据。
private async downloadImage(url: string): Promise<ArrayBuffer> { return new Promise((resolve, reject) => { const httpRequest = http.createHttp(); httpRequest.request( url, { method: http.RequestMethod.GET, expectDataType: http.HttpDataType.ARRAY_BUFFER }, (err, data) => { if (err) { reject(new Error(`图片获取失败: ${err.message}`)); return; } if (data && data.result) { resolve(data.result as ArrayBuffer); } else { reject(new Error('未获取到图片数据')); } } ); }); } - 识别图中二维码。
async scanQRFromWebImage(url: string) { promptAction.showToast({ message: '开始识别二维码...' }); try { // 1.下载网络图片 const imageData = await this.downloadImage(url); // 2.创建ImageSource const imageSource = image.createImageSource(imageData); const pixelMap = await imageSource.createPixelMap(); // 3.调用二维码识别能力 const result = await this.decodeImageBuffer(pixelMap); if (result) { promptAction.showToast({ message: result }); } else { promptAction.showToast({ message: '识别失败' }); } // 释放资源 pixelMap.release(); imageSource.release(); } catch (error) { const err = error as BusinessError; promptAction.showToast({ message: err.message }); } } async decodeImageBuffer(pixelMap: image.PixelMap) { pixelMap.convertPixelFormat(image.PixelMapFormat.NV12) let info = await pixelMap.getImageInfo() let pixelBytesNumber: number = pixelMap.getPixelBytesNumber(); let buffer = new ArrayBuffer(pixelBytesNumber) await pixelMap.readPixelsToBuffer(buffer) let byteImg: detectBarcode.ByteImage = { byteBuffer: buffer, width: info.size.width, height: info.size.height, format: detectBarcode.ImageFormat.NV21 }; let options: scanBarcode.ScanOptions = { scanTypes: [scanCore.ScanType.ALL], enableMultiMode: true, enableAlbum: false }; try { return detectBarcode.decodeImage(byteImg, options).then((result: detectBarcode.DetectResult) => { return JSON.stringify(result) }).catch((error: BusinessError) => { return 'code' + error.code + 'message' + error.message }); } catch (error) { return 'code' + error.code + 'message' + error.message } }
2643

被折叠的 条评论
为什么被折叠?



