You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中ESC/POS打印机图片打印异常修复求助

求助:Citypos CP-P100U打印机打印图片出现异常文本修复

我将Widget转换为图片后使用Citypos mini printer cp-p100u打印,结果图片区域出现奇怪的乱码文本,多次尝试无法解决,希望实现图片的完美打印。

打印异常表现:输出的收据中图片部分无法正常显示,存在异常乱码内容。

我的代码

void pos_print() {
  screenshotController.capture().then((Uint8List? image) async {
    if (image == null) return null;

    Completer<PrinterDevice> completer = Completer<PrinterDevice>();

    Future.delayed(Duration.zero, () {
      PrinterManager.instance
          .discovery(type: PrinterType.usb)
          .listen((printer) {
        completer.complete(printer);
      });
    });

    msg_alert("Searching for printers ...");
    PrinterDevice printer;

    try {
      printer = await completer.future.timeout(Duration(seconds: 10));
    } on TimeoutException catch (e) {
      msg_alert("We dont Find Any Printer");
      return;
    }

    msg_alert("We Found the printer , Now We Connect with it");

    try {
      await PrinterManager.instance
          .connect(
              type: PrinterType.usb,
              model: UsbPrinterInput(
                  name: printer.name,
                  productId: printer.productId,
                  vendorId: printer.vendorId))
          .timeout(Duration(seconds: 5));
    } on TimeoutException catch (e) {
      msg_alert("Failed To Connect With Printer");
      return;
    }

    msg_alert("Printing ...");

    List<int> bytes = [];
    final generator =
        Generator(PaperSize.mm80, await CapabilityProfile.load());

    bytes += generator.feed(1);
    bytes += generator.image(img.decodePng(image)!, align: PosAlign.center);
    bytes += generator.feed(1);
    bytes += generator.cut(mode: PosCutMode.partial);

    bool success;

    try {
      success = await PrinterManager.instance
          .send(type: PrinterType.usb, bytes: bytes)
          .timeout(Duration(seconds: 5));
    } on TimeoutException catch (e) {
      success = false;
    }

    if (success)
      msg_alert("Print success");
    else
      msg_alert("print error");
  }).catchError((onError) {
    print(onError);
  });
}

可能的修复方案

  • 修复图片解码逻辑:截图生成的可能是JPEG格式,强行用PNG解码会导致打印异常,先判断图片类型再解码:
    Image? decodedImage;
    try {
      decodedImage = img.decodePng(image);
    } catch (_) {
      decodedImage = img.decodeJpg(image);
    }
    if (decodedImage == null) {
      msg_alert("图片解码失败");
      return;
    }
    
  • 缩放图片适配打印纸宽度:80mm打印纸的有效打印宽度约为384像素,将图片缩放到该尺寸内避免溢出:
    final scaledImage = img.copyResize(decodedImage, width: 384);
    bytes += generator.image(scaledImage, align: PosAlign.center);
    
  • 匹配打印机CapabilityProfile:默认Profile可能不兼容Citypos打印机,尝试加载通用ESC/POS配置:
    final profile = await CapabilityProfile.load(name: 'ESC/POS');
    final generator = Generator(PaperSize.mm80, profile);
    
  • 添加打印机初始化指令:打印前发送重置指令,确保打印机处于初始状态:
    bytes += generator.reset(); // 添加初始化指令
    bytes += generator.feed(1);
    
  • 优化打印机发现逻辑:避免找到第一个设备就停止,增加目标打印机验证(替换成你的设备VID/PID):
    Future.delayed(Duration.zero, () {
      final discoveryStream = PrinterManager.instance.discovery(type: PrinterType.usb);
      discoveryStream.listen((printer) {
        // 验证是否为目标Citypos打印机
        if (printer.vendorId == 0xXXXX && printer.productId == 0xXXXX) {
          completer.complete(printer);
          discoveryStream.cancel();
        }
      });
    });
    

内容的提问来源于stack exchange,提问作者KhaledAl2mri

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 07:10:45