Flutter图像处理
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
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
怎样阻止微信小程序自动打开
PHP中文网 06-13 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01