如何解决生成的二维码无法使用的问题
=================

#### 问题现象

在HarmonyOS中生成二维码异常，生成的二维码无法使用。应用的业务逻辑主要分两步：

1.  把后端返回的base64字符串解码。
2.  根据解码后的Byte数组生成二维码。

 let content = "AQDwAUUBAAIZAAAAAAABBJWHOWbBlc8AHgOj0dsvCpdMZpMy3f+3+887rj5/ydMF+V50PqwhbHkSoZAgAAAAZrRmzyACrsxSAWIgAQEBAQEBAAAAAJiWfwAAAAAAAAAAAAAAAAoAAFlCQgAAAAAAJLChYJ0Mi0Pw/wSMZ8D2ByTDvmtxRinyNDCP0+VzsVoTaaXIcfNv4i8Ru6P3uHWjCVGUS3WE8faSSvxdnkLgnGa0Zs/bnwae2W8jT5krtgt2I4c+yg691kbq8zcYBEOmvioBUZ6B6e9D1c5jc3N0FmQsO0SAXVu0U4CMSao4xBxgIg+m";
 _// base64字符串解码_
 let that = new util.Base64Helper();
 let uArrayRes = that.decodeSync(content,util.Type.MIME)
 let str = buffer.from(uArrayRes.buffer).toString()
 _// ISO-8859-1编码_
 let textEncoder = new util.TextEncoder('iso-8859-1')
 let res = textEncoder.encodeInto(str)
 let resStr = buffer.from(res.buffer).toString()
 let options: generateBarcode.CreateOptions = {
   scanType: scanCore.ScanType.QR\_CODE,
   height: 800,
   width: 800,
   level: generateBarcode.ErrorCorrectionLevel.LEVEL\_Q
 }
 _// 码图生成接口，成功返回PixelMap格式图片_
 generateBarcode.createBarcode(resStr, options)

按照以上代码生成后的二维码如下图，需要通过二维码读取字符串的**二进制字节**信息，扫码后得到的是字符串信息。最终导致扫码设备无法识别，说明二维码生成失败。

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/6c/v3/jtDUPDDQRHqgLNaqEblGMg/zh-cn_image_0000002628392618.png?HW-CC-KV=V1&HW-CC-Date=20260709T134242Z&HW-CC-Expire=86400&HW-CC-Sign=A5A45357F5BD0D627EE5C04AD2C50C29009E1EAC2FA8A24CA59FFA527FAF17BF "点击放大")

#### 背景知识

根据指定编码格式的字符串，[创建新的Buffer对象](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-buffer#bufferfrom-4)。

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/fa/v3/FfRl1Ya-QlCrCGdi_bR-fA/note_3.0-zh-cn.png?HW-CC-KV=V1&HW-CC-Date=20260709T134242Z&HW-CC-Expire=86400&HW-CC-Sign=2475EA211F7ACA7C3FD60D2E08DA5AEC9453004762B587B512B8B823C7778C13)

generateBarcode目前不支持在模拟器上运行。

#### 问题定位

需要通过二维码读取字符串的二进制字节信息，扫码后得到的是字符串信息。

[TextEncoder](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-util#textencoder)用于将字节数组解码为字符串，支持多种不同的编码格式。

使用TextEncoder解码结果为字符串，而不是业务需要的二进制字节信息，所以需要更换解码方式。

#### 分析结论

数据转为二进制参数应该使用buffer.from，其中encoding入参Latin1是ISO-8859-1的别名。

修改转码方式为：

buffer.from(str, 'latin1').buffer;

入参由字符串改为ArrayBuffer，成功生成预期码图。

#### 修改建议

ISO-8859-1编码采用buffer.from操作转为二进制数据，不再通过textEncoder.encodeInto进行转换，Latin1是ISO-8859-1的别名，向下兼容ASCII格式。

_// 导入码图生成需要的图片模块、错误码模块_
import { scanCore, generateBarcode } from '@kit.ScanKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { image } from '@kit.ImageKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { buffer, util } from '@kit.ArkTS';

const TAG: string = 'Create barcode';

@Entry
@Component
struct Index {
  @State pixelMap1: image.PixelMap | undefined = undefined;

  build() {
    Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
      Button('generateBarcode Promise').onClick(() => {
        this.pixelMap1 = undefined;
        let content =
          'AQDwAUUBAAIZAAAAAAABBJWHOWbBlc8AHgOj0dsvCpdMZpMy3f+3+887rj5/ydMF+V50PqwhbHkSoZAgAAAAZrRmzyACrsxSAWIgAQEBAQEBAAAAAJiWfwAAAAAAAAAAAAAAAAoAAFlCQgAAAAAAJLChYJ0Mi0Pw/wSMZ8D2ByTDvmtxRinyNDCP0+VzsVoTaaXIcfNv4i8Ru6P3uHWjCVGUS3WE8faSSvxdnkLgnGa0Zs/bnwae2W8jT5krtgt2I4c+yg691kbq8zcYBEOmvioBUZ6B6e9D1c5jc3N0FmQsO0SAXVu0U4CMSao4xBxgIg+m';
       _ // base64字符串解密_
        let that = new util.Base64Helper();
        let uArrayRes = that.decodeSync(content, util.Type.MIME);
      _  // ISO-8859-1编码_
        let str = buffer.from(uArrayRes.buffer).toString();
        let contentBuffer: ArrayBuffer = buffer.from(str, 'latin1').buffer;
        let options: generateBarcode.CreateOptions = {
          scanType: scanCore.ScanType.QR\_CODE,
          height: 800,
          width: 800,
          level: generateBarcode.ErrorCorrectionLevel.LEVEL\_Q
        };
      _  // 码图生成接口，成功返回PixelMap格式图片_
        generateBarcode.createBarcode(contentBuffer, options).then((pixelMap: image.PixelMap) => {
          this.pixelMap1 = pixelMap;
          hilog.info(0x0001, TAG, 'Succeeded in creating barCode.');
        }).catch((error: BusinessError) => {
          hilog.error(0x0001, TAG, \`Failed to createBarCode. Code: ${error.code}, message: ${error.message}\`);
        });
      })
        .margin({ top: 20, bottom: 20 });
    _  // 获取生成码后显示_
      if (this.pixelMap1) {
        Image(this.pixelMap1).width(300).height(300).objectFit(ImageFit.Contain);
      }
    }
    .width('100%')
    .height('100%');

  }
}