Flutter 图片裁剪旋转翻转编辑器

 

实现

这部分我觉得不太好讲,全是数学几何相关的计算。当初开始写的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;
}

旋转,翻转,重置

  • 定义key,以方便操作ExtendedImageEditorState

final GlobalKey editorKey =GlobalKey();

  • 顺时针旋转90°

editorKey.currentState.rotate(right: true);

  • 逆时针旋转90°

editorKey.currentState.rotate(right: false);

  • 翻转(镜像)

editorKey.currentState.flip();

  • 重置

editorKey.currentState.reset();

裁剪数据

添加 image 库到 pubspec.yaml, 它是用来裁剪/旋转/翻转图片数据的

dependencies:
  image: any
  • 从ExtendedImageEditorState中获取裁剪区域以及图片数据
      var cropRect = editorKey.currentState.getCropRect();
      ui.Image imageData = editorKey.currentState.image;
  • 将flutter的图片数据转换为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)

最后

如果你看到了这里,觉得文章写得不错就给个赞呗!欢迎大家评论讨论!如果你觉得那里值得改进的,请给我留言。一定会认真查询,修正不足,定期免费分享技术干货。谢谢!

你可能感兴趣的:(移动互联网,Android程序员,Android开发,Android)