Flutter 裁剪图片

在ble传入数据的时候对图片要一定的要求,比如:尺寸、文件大小等。 1、输入图片形状:长方形、正方形 2、目标大小 3、输入裁剪和压缩后的图片 4、代码如下

ini 复制代码
/// 将图片裁剪为正方形并缩放到 [squareSize] x [squareSize],
/// 然后通过调整 JPEG 质量压缩至 [targetSize] 字节以内。
/// [imageBytes]  : 原始图像字节数据
/// [squareSize]  : 最终正方形的边长(像素),例如 360
/// [targetSize]  : 目标文件大小(字节)
/// [minQuality]  : 允许的最低 JPEG 质量(1-100),防止过度压缩
/// 返回压缩后的 JPEG 字节数据,如果解码失败则返回原图。
static Future<Uint8List> compressToSize(
  Uint8List imageBytes,
  int squareSize,
  int targetSize, {
  int minQuality = 85,
}) async {
  final original = img.decodeImage(imageBytes);
  if (original == null) return imageBytes; // 解码失败,返回原图

  // 1. 裁剪为正方形(基于最小边居中裁剪)
  img.Image squareImage;
  final int srcWidth = original.width;
  final int srcHeight = original.height;

  if (srcWidth > srcHeight) {
    // 宽度大于高度:以高度为边长,裁剪左右
    final int cropX = (srcWidth - srcHeight) ~/ 2;
    squareImage = img.copyCrop(
      original,
      x: cropX,
      y: 0,
      width: srcHeight,
      height: srcHeight,
    );
  } else if (srcHeight > srcWidth) {
    // 高度大于宽度:以宽度为边长,裁剪上下
    final int cropY = (srcHeight - srcWidth) ~/ 2;
    squareImage = img.copyCrop(
      original,
      x: 0,
      y: cropY,
      width: srcWidth,
      height: srcWidth,
    );
  } else {
    // 已是正方形,无需裁剪
    squareImage = original;
  }

  // 2. 缩放到目标正方形尺寸
  final resizedImage = img.copyResize(
    squareImage,
    width: squareSize,
    height: squareSize,
  );

  // 3. 二分法调整 JPEG 质量
  int low = 1;
  int high = 100;
  int bestQuality = 100;
  Uint8List bestBytes = img.encodeJpg(resizedImage, quality: bestQuality);

  // 如果最高质量已经小于目标,直接返回
  if (bestBytes.length <= targetSize) {
    return bestBytes;
  }

  const int maxIterations = 10;
  for (int i = 0; i < maxIterations; i++) {
    int mid = (low + high) ~/ 2;
    if (mid < minQuality) break;

    final compressedBytes = img.encodeJpg(resizedImage, quality: mid);
    if (compressedBytes.length <= targetSize) {
      // 满足要求,尝试更高质量
      bestQuality = mid;
      bestBytes = compressedBytes;
      low = mid + 1;
    } else {
      high = mid - 1;
    }

    if (low > high) break;
  }

  return bestBytes;
}
相关推荐
ITMan彪叔2 小时前
赋能UE运行态编辑平台: 网络图片下载的插件改造与复盘
前端
RANxy2 小时前
🚀 Umi Max 项目从0到1:企业级 React 脚手架实战
前端·前端框架
拾年2752 小时前
深入理解 V8 引擎:从代码执行到垃圾回收的完整链路
前端·javascript·v8
Master_Azur2 小时前
javaScript进阶
前端
markfeng82 小时前
React入门教学
前端·react.js
ze_juejin2 小时前
Object.defineProperty vs Proxy 对比总结
前端
wing982 小时前
我的AI编程体验:从白嫖到付费,我为什么最终留下了Codex
前端·人工智能·程序员
京东云开发者2 小时前
京东Taro Native框架静态布局直渲提速
前端
程序员小羊!2 小时前
03JavaScript预备知识
前端