• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

Flutter图像处理

武飞扬头像
hn_lgc
帮助1

Flutter中的Image类用于显示图像,他使用的压缩文件的图像格式,应该就是直接的jpg、png的文件吧,把它们加载到内存中的,然后用Uint8List的形式表示,交给Image控件就可以显示了。

这里Uint8List实际就是文件的字节数据罢了,关于这个字节数据有各种的表现形式
C 里面就是uint8 * uchar*,Java里面byte数组,byteBuffer,flutter里面就是这个uint8list了,还有byteBuffer,总结就是统统把它们当成字节数据就行了。

如果要对图像处理,压缩格式的图像很多情况下是不方便处理的,需要解码成位图形式,位图形式按照像素排列成矩阵,像素里面包含RGBA等通道,那么就方便处理很多了。
基本的流程就是 解码-处理-编码。
更全的流程就是
加载-----得到未解码的字节数组(可以显示等)----解码得到位图数组----按照位图处理----编码—显示或者保存

上面是原理,具体怎么写代码,使用什么样的API或者三方库呢?

加载

如果是本地图片,直接读取图片文件的byte就行,readAsBytes。或者使用一些库,能够做缓存处理。
如果是网络图片,可以使用CachedNetworkImage,显示图片同时获取其字节数据就是图片文件,它支持缓存,https://github.com/Baseflow/flutter_cached_network_image/issues/714
还有方法,从网络获取图片文件不显示,也支持缓存的,然后获取字节数据,没找到目前

解码

dart的image这个库可以用于图片解码image,将图片文件字节流数据传递给它的API解码就行,得到对应的Image对象,这个就是位图形式的图像了,通过它可以获取位图数组,里面就是像素数据,通道数据,图像的各种信息等,可以获取这些信息进行处理了

	import 'package:image/image.dart' as img_lib;
  /// 将压缩的图像数据转换为不压缩的像素组成的图像数据
  /// 没压缩的是不能处理的,不能区argb通道,像素数量都是不对的,比如 100 * 100 的 四通道图像数据,压缩了可能是20000 字节
  static img_lib.Image decodeImageBytes(Uint8List originalImageBytes) {
    late final img_lib.Image? image;
    final decoder = img_lib.findDecoderForData(originalImageBytes);

    if (decoder == null) throw Exception('Image not supported');

    image = decoder.decode(originalImageBytes);

    if (image == null) throw Exception('Unable to decode image');

    return image;
  }

处理

flutter中还提供了bytebuffer类,也可以通过相应的api和intlist进行转换
uintlist之间的转换,似乎可以通过fromList 进行转换
但是注意必须底层数据支持相互转换才行,否则就会数据错乱,3通道的图像用这个asUint32List转到c层的uint32list,结果坑大了,找了一天bug才找出来。asUint32List方法注释里面写了,结果没有仔细看。

使用C 处理图像

参考文章 https://juejin.cn/post/6976824832595853342 这个写得最好的找到的

https://github.com/khaifunglim97/flutter-image-processing

https://medium.com/@jeffrey.wolberg

基础

显然的,flutter处理低效 很多图像处理库是C C 的所以要用它们处理。
首先学会flutter对C 的使用,利用ffi扩展库,参考官方教程比较简单的。

首先要学会C 的一些基本知识,然后需要会原生调用C 的一些基本知识,因为flutter需要利用原生的一些机制,这两个还是有一定的难度的。
主要是没有好的教程以及C C 体系本身的易用性差,问题多。

1、将flutter的图像数据传递到C

ffi提供了操作C 内存的接口
所以,在C 分配内存得到其指针
然后把数据复制过去,最后把指针传递给C 层就完成了图像数据的传递
// Credits to Tims !
extension Uint8ListBlobConversion on Uint8List {
Pointer allocatePointer() {
final blob = calloc(length);
final blobBytes = blob.asTypedList(length);
blobBytes.setAll(0, this);
return blob;
}
}
注意!踩坑点,flutter的int不能传给c 的int32,flutter是64位,传过去概率性变成莫名其妙的值,找bug找半天
另外方式:可以直接在C 读取图像,利用OpenCV

使用OpenCV
https://github.com/westracer/flutter_native_opencv
https://github.com/AdityaMulgundkar/flutter_opencv
使用ncnn https://github.com/KoheiKanagu/ncnn_yolox_flutter
使用tflite https://github.com/shaqian/flutter_tflite

将C 图像返回给Flutter

参考 https://juejin.cn/post/6976824832595853342
/// 调用高斯模糊,这里返回的是C 的usigned char * 指针

{
final newBytes = blur(bytes, imgLengthBytes, 15);
if (newBytes == nullptr) {
print(‘高斯模糊失败’);
return null;
}

var newList = newBytes.asTypedList(imgLengthBytes.value);

/// 释放指针
malloc.free(bytes);
malloc.free(imgLengthBytes);
return newList;

}

压缩图像

flutter专门图片压缩库
前面提到的Image类提供了比较简单的压缩
C 直接用OpenCV压缩,然后传回地址也是可以的 https://medium.com/gitconnected/building-a-flutter-computer-vision-app-using-dart-ffi-opencv-and-tensorflow-part-2-81472b4ac380

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgakkii
系列文章
更多 icon
同类精品
更多 icon
继续加载