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;
}
相关推荐
子兮曰3 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰3 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
前端小万3 天前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝3 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
三十而立洋3 天前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
卡布鲁3 天前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js
汉堡大王95273 天前
Jev:不是聊天机器人, 而是一个智能 if 语句
前端·人工智能·后端
梦想很大很大3 天前
从运行事实到回归证据:Workrun 的 Telemetry 与 Evaluation 实践
前端·人工智能·后端
计算机魔术师3 天前
Meta Muse agent 接入 Shopify 的 Shop Pay 实现代理式购物
前端
沙蒿同学3 天前
我用 Go 搭了一条 AI Agent 流水线:从 1 张商品图到一整套淘宝详情页
前端·javascript·后端