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

Flutter中JPEG2000格式转换:电子护照芯片图片读取求助

解决Flutter中电子护照JPEG2000图片转换问题

1. Kotlin原生端实现解码逻辑

在Android项目的MainActivity.kt中注册Method Channel并实现JPEG2000解码:

import android.graphics.Bitmap
import android.graphics.BitmapFactory
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel
import java.io.ByteArrayOutputStream

class MainActivity : FlutterActivity() {
    private val CHANNEL = "com.example.passport/image_decoder"

    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->
            if (call.method == "decodeJpeg2000") {
                val imageData = call.argument<ByteArray>("imageData")
                imageData?.let {
                    // 尝试原生解码JPEG2000
                    val bitmap = BitmapFactory.decodeByteArray(it, 0, it.size)
                    if (bitmap != null) {
                        // 将Bitmap转为JPG格式的字节数组返回给Flutter
                        val outputStream = ByteArrayOutputStream()
                        bitmap.compress(Bitmap.CompressFormat.JPEG, 90, outputStream)
                        result.success(outputStream.toByteArray())
                    } else {
                        result.error("DECODE_FAILED", "原生解码JPEG2000失败", null)
                    }
                } ?: run {
                    result.error("INVALID_DATA", "图片数据为空", null)
                }
            } else {
                result.notImplemented()
            }
        }
    }
}

如果部分Android设备原生不支持JPEG2000,可引入第三方解码库增强兼容性:
在app/build.gradle的dependencies中添加:

implementation "com.twelvemonkeys.imageio:imageio-jpeg2000:3.10.1"

替换解码逻辑为:

import javax.imageio.ImageIO
import java.io.ByteArrayInputStream
import android.graphics.Canvas
import android.graphics.Paint

// ...
val inputStream = ByteArrayInputStream(it)
val bufferedImage = ImageIO.read(inputStream)
if (bufferedImage != null) {
    val bitmap = Bitmap.createBitmap(bufferedImage.width, bufferedImage.height, Bitmap.Config.ARGB_8888)
    val canvas = Canvas(bitmap)
    val paint = Paint()
    canvas.drawBitmap(bitmap, 0f, 0f, paint)
    // 后续压缩为JPG的逻辑同上
}

2. Flutter端调用原生解码方法

创建Flutter组件,通过Method Channel调用原生能力并显示转换后的图片:

import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';

class PassportImage extends StatefulWidget {
  final Uint8List jpeg2000Data;
  const PassportImage({super.key, required this.jpeg2000Data});

  @override
  State<PassportImage> createState() => _PassportImageState();
}

class _PassportImageState extends State<PassportImage> {
  Uint8List? _convertedImage;
  final MethodChannel _channel = const MethodChannel('com.example.passport/image_decoder');

  @override
  void initState() {
    super.initState();
    _decodeImage();
  }

  Future<void> _decodeImage() async {
    try {
      final Uint8List result = await _channel.invokeMethod(
        'decodeJpeg2000',
        {'imageData': widget.jpeg2000Data},
      );
      setState(() {
        _convertedImage = result;
      });
    } on PlatformException catch (e) {
      print('解码错误: ${e.message}');
    }
  }

  @override
  Widget build(BuildContext context) {
    return _convertedImage != null
        ? Image.memory(_convertedImage!)
        : const CircularProgressIndicator();
  }
}

3. 使用示例

将从dmrtd获取的Uint8List格式JPEG2000数据传入组件即可:

// 假设passportImageData是从电子护照芯片解析得到的图片数据
PassportImage(jpeg2000Data: passportImageData)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 04:36:19