如何在React Native移动应用中生成Aztec Code
我之前在项目里也碰到过这个问题,Aztec Code确实在React Native生态里支持得比较少,不过有几个靠谱的方案能解决,给你详细说说:
解决React Native中生成Aztec Code的方案
方案1:封装原生模块(最稳定可靠)
因为React Native官方没有内置Aztec生成能力,直接用Android和iOS的原生API来实现是最靠谱的,性能也最好。
Android端实现
Android自API 28开始,androidx.core.graphics.BarcodeEncoder已经支持生成Aztec Code,步骤如下:
- 在你的Android项目中创建一个新的原生模块类,比如
AztecGeneratorModule.java:
package com.yourappname; import androidx.core.graphics.BarcodeEncoder; import android.graphics.Bitmap; import android.util.Base64; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReactContextBaseJavaModule; import com.facebook.react.bridge.ReactMethod; import com.facebook.react.bridge.Promise; import java.io.ByteArrayOutputStream; public class AztecGeneratorModule extends ReactContextBaseJavaModule { AztecGeneratorModule(ReactApplicationContext context) { super(context); } @Override public String getName() { return "AztecGenerator"; } @ReactMethod public void generateAztecCode(String data, int width, int height, Promise promise) { try { BarcodeEncoder encoder = new BarcodeEncoder(); Bitmap bitmap = encoder.encodeBitmap( data, androidx.core.graphics.BarcodeFormat.AZTEC, width, height ); ByteArrayOutputStream stream = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream); byte[] bytes = stream.toByteArray(); String base64Image = "data:image/png;base64," + Base64.encodeToString(bytes, Base64.DEFAULT); promise.resolve(base64Image); } catch (Exception e) { promise.reject("AZTEC_ERROR", e.getMessage()); } } }
- 注册这个模块到
Package类中:
package com.yourappname; import com.facebook.react.ReactPackage; import com.facebook.react.bridge.NativeModule; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.uimanager.ViewManager; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class AztecGeneratorPackage implements ReactPackage { @Override public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) { List<NativeModule> modules = new ArrayList<>(); modules.add(new AztecGeneratorModule(reactContext)); return modules; } @Override public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) { return Collections.emptyList(); } }
- 在
MainApplication.java中添加这个Package:
@Override protected List<ReactPackage> getPackages() { @SuppressWarnings("UnnecessaryLocalVariable") List<ReactPackage> packages = new PackageList(this).getPackages(); packages.add(new AztecGeneratorPackage()); // 添加这一行 return packages; }
iOS端实现
iOS的CoreImage框架提供了CIAztecCodeGenerator滤镜,可以直接生成Aztec Code:
- 创建一个新的Swift文件
AztecGeneratorModule.swift:
import Foundation import CoreImage import UIKit import React @objc(AztecGeneratorModule) class AztecGeneratorModule: NSObject, RCTBridgeModule { static func moduleName() -> String { return "AztecGenerator" } static func requiresMainQueueSetup() -> Bool { return true } @objc func generateAztecCode(_ data: String, width: Int, height: Int, resolver resolve: RCTPromiseResolveBlock, rejecter reject: RCTPromiseRejectBlock) { guard let filter = CIFilter(name: "CIAztecCodeGenerator") else { reject("AZTEC_ERROR", "Failed to create Aztec filter", nil) return } filter.setValue(data.data(using: .utf8), forKey: "inputMessage") guard let ciImage = filter.outputImage else { reject("AZTEC_ERROR", "Failed to generate Aztec image", nil) return } // 调整图片尺寸 let scaleX = CGFloat(width) / ciImage.extent.width let scaleY = CGFloat(height) / ciImage.extent.height let scaledImage = ciImage.transformed(by: CGAffineTransform(scaleX: scaleX, y: scaleY)) // 转成UIImage并转base64 let context = CIContext(options: [.useSoftwareRenderer: false]) guard let cgImage = context.createCGImage(scaledImage, from: scaledImage.extent) else { reject("AZTEC_ERROR", "Failed to convert to CGImage", nil) return } let uiImage = UIImage(cgImage: cgImage) guard let imageData = uiImage.pngData() else { reject("AZTEC_ERROR", "Failed to convert to PNG data", nil) return } let base64String = "data:image/png;base64," + imageData.base64EncodedString() resolve(base64String) } }
- 在你的iOS项目的
Bridging-Header.h中添加React的引用(如果还没加的话):
#import <React/RCTBridgeModule.h> #import <React/RCTPromiseResolveBlock.h> #import <React/RCTPromiseRejectBlock.h>
React Native端调用
在RN组件中引入原生模块,调用生成方法并显示图片:
import React, { useState } from 'react'; import { View, Image, Button, NativeModules, Alert } from 'react-native'; const { AztecGenerator } = NativeModules; const AztecCodeGenerator = () => { const [aztecImage, setAztecImage] = useState(null); const generateCode = async () => { try { const base64Image = await AztecGenerator.generateAztecCode( "你的Aztec编码内容", 300, 300 ); setAztecImage(base64Image); } catch (error) { Alert.alert("生成失败", error.message); } }; return ( <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}> <Button title="生成Aztec Code" onPress={generateCode} /> {aztecImage && <Image source={{ uri: aztecImage }} style={{ width: 300, height: 300, marginTop: 20 }} />} </View> ); }; export default AztecCodeGenerator;
方案2:使用WebView结合JavaScript库(快速实现,无需原生开发)
如果你不想折腾原生代码,可以用WebView加载本地HTML页面,借助JS库生成Aztec Code,再把结果传回RN。
步骤:
- 在RN项目的
assets文件夹下创建一个aztec-generator.html文件:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <script src="https://unpkg.com/aztec-code-generator@1.0.2/dist/aztec-code-generator.min.js"></script> </head> <body> <canvas id="aztecCanvas"></canvas> <script> window.addEventListener('message', (event) => { const data = event.data; if (data.type === 'GENERATE_AZTEC') { const canvas = document.getElementById('aztecCanvas'); // 生成Aztec Code到canvas AztecCodeGenerator.generate(data.content, canvas, { width: data.width, height: data.height }); // 把canvas转成base64传回RN const base64Image = canvas.toDataURL('image/png'); window.ReactNativeWebView.postMessage(base64Image); } }); </script> </body> </html>
- 在RN组件中使用WebView:
import React, { useState, useRef } from 'react'; import { View, Image, Button, Alert, WebView } from 'react-native'; const AztecWebGenerator = () => { const [aztecImage, setAztecImage] = useState(null); const webViewRef = useRef(null); const generateCode = () => { webViewRef.current.postMessage({ type: 'GENERATE_AZTEC', content: "你的Aztec编码内容", width: 300, height: 300 }); }; const handleMessage = (event) => { setAztecImage(event.nativeEvent.data); }; return ( <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}> <Button title="生成Aztec Code" onPress={generateCode} /> {aztecImage && <Image source={{ uri: aztecImage }} style={{ width: 300, height: 300, marginTop: 20 }} />} {/* 隐藏WebView,因为我们只需要它的生成能力 */} <WebView ref={webViewRef} source={require('./assets/aztec-generator.html')} onMessage={handleMessage} style={{ width: 0, height: 0 }} javaScriptEnabled={true} /> </View> ); }; export default AztecWebGenerator;
方案3:尝试第三方库(注意维护状态)
有些第三方库可能支持Aztec,比如react-native-barcode-builder,不过我之前用的时候发现它的Aztec支持可能有问题,你可以尝试安装测试:
npm install react-native-barcode-builder --save
然后使用:
import Barcode from 'react-native-barcode-builder'; <Barcode value="你的内容" format="AZTEC" width={300} height={300} />
不过要注意,这个库可能很久没更新了,在新的RN版本(比如0.70+)可能会有兼容性问题,所以优先推荐前两个方案。
内容的提问来源于stack exchange,提问作者MD. IBRAHIM KHALIL TANIM
相关产品推荐
相关产品推荐

