这部分我觉得不太好讲,全是数学几何相关的计算。当初开始写的extended_image的时候,就留意了一下可能会扩展的功能实现的可能性,代码之间也做好了铺垫。大家都问,功能能抽离出来吗? 我说不能,从开始基础就决定它将会拥有这些功能。简单提一下,图片的显示区域不等于图片的layout区域,它受BoxFix等参数的影响。而Flutter里面的 Transform是对整个layout区域起作用的,明显不符合我们的需求。所以从一开始我就放弃直接使用Transform对图片进行处理,直接通过算法在绘制图片的时候进行缩放,平移,旋转,翻转等操作。
ExtendedImage.network(
imageTestUrl,
fit: BoxFit.contain,
mode: ExtendedImageMode.editor,
extendedImageEditorKey: editorKey,
initEditorConfigHandler: (state) {
return EditorConfig(
maxScale: 8.0,
cropRectPadding: EdgeInsets.all(20.0),
hitTestSize: 20.0,
cropAspectRatio: _aspectRatio.aspectRatio);
},
);
ExtendedImage 相关参数设置
参数 | 描述 | 默认 |
---|---|---|
mode | 图片模式,默认/手势/编辑 (none,gestrue,editor) | none |
initGestureConfigHandler | 编辑器配置的回调(图片加载完成时).你可以根据图片的信息比如宽高,来初始化 | - |
extendedImageEditorKey | key of ExtendedImageEditorState 用于裁剪旋转翻转 | - |
EditorConfig 参数
参数 | 描述 | 默认 |
---|---|---|
maxScale | 最大的缩放倍数 | 5.0 |
cropRectPadding | 裁剪框跟图片layout区域之间的距离。最好是保持一定距离,不然裁剪框边界很难进行拖拽 | EdgeInsets.all(20.0) |
cornerSize | 裁剪框四角图形的大小 | Size(30.0, 5.0) |
cornerColor | 裁剪框四角图形的颜色 | primaryColor |
lineColor | 裁剪框线的颜色 | scaffoldBackgroundColor.withOpacity(0.7) |
lineHeight | 裁剪框线的高度 | 0.6 |
eidtorMaskColorHandler | 蒙层的颜色回调,你可以根据是否手指按下来设置不同的蒙层颜色 | scaffoldBackgroundColor.withOpacity(pointerdown ? 0.4 : 0.8) |
hitTestSize | 裁剪框四角以及边线能够拖拽的区域的大小 | 20.0 |
animationDuration | 当裁剪框拖拽变化结束之后,自动适应到中间的动画的时长 | Duration(milliseconds: 200) |
tickerDuration | 当裁剪框拖拽变化结束之后,多少时间才触发自动适应到中间的动画 | Duration(milliseconds: 400) |
cropAspectRatio | 裁剪框的宽高比 | null(无宽高比)) |
这是一个double类型,你可以自定义裁剪框的宽高比。 如果为null,那就没有宽高比限制。 如果小于等于0,宽高比等于图片的宽高比。 下面是一些定义好了的宽高比
class CropAspectRatios {
/// no aspect ratio for crop
static const double custom = null;
/// the same as aspect ratio of image
/// [cropAspectRatio] is not more than 0.0, it's original
static const double original = 0.0;
/// ratio of width and height is 1 : 1
static const double ratio1_1 = 1.0;
/// ratio of width and height is 3 : 4
static const double ratio3_4 = 3.0 / 4.0;
/// ratio of width and height is 4 : 3
static const double ratio4_3 = 4.0 / 3.0;
/// ratio of width and height is 9 : 16
static const double ratio9_16 = 9.0 / 16.0;
/// ratio of width and height is 16 : 9
static const double ratio16_9 = 16.0 / 9.0;
}
final GlobalKey
editorKey.currentState.rotate(right: true);
editorKey.currentState.rotate(right: false);
editorKey.currentState.flip();
editorKey.currentState.reset();
添加 image 库到 pubspec.yaml, 它是用来裁剪/旋转/翻转图片数据的
dependencies:
image: any
var cropRect = editorKey.currentState.getCropRect();
ui.Image imageData = editorKey.currentState.image;
var data = await imageData.toByteData(format: ui.ImageByteFormat.png);
image.Image src = decodePng(data.buffer.asUint8List());
if (editorKey.currentState.editAction.hasEditAction) {
var editAction = editorKey.currentState.editAction;
src = copyFlip(src, flipX: editAction.flipX, flipY: editAction.flipY);
if (editAction.hasRotateAngle) {
double angle = (editAction.rotateAngle ~/ (pi / 2)) * 90.0;
src = copyRotate(src, angle);
}
}
var cropData = copyCrop(src, cropRect.left.toInt(), cropRect.top.toInt(),
cropRect.width.toInt(), cropRect.height.toInt());
encodePng(cropData)
如果你看到了这里,觉得文章写得不错就给个赞呗!欢迎大家评论讨论!如果你觉得那里值得改进的,请给我留言。一定会认真查询,修正不足,定期免费分享技术干货。谢谢!