最近遇到一个项目需求,这里记录下。将图片进行顺时针旋转90°和逆时针90°,保证图片都铺满矩形框区域
import 'dart:async';
import 'dart:io';
import 'dart:math';
import 'dart:ui' as ui;import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
class MyHomePage extends StatefulWidget {const MyHomePage({super.key});@overrideState<MyHomePage> createState() => _MyHomePageState();
}class _MyHomePageState extends State<MyHomePage> {double rate = 4 / 6;String imageUrl ='https://ss0.baidu.com/94o3dSag_xI4khGko9WTAnF6hhy/zhidao/pic/item/b2de9c82d158ccbfb40a4fd81bd8bc3eb035419a.jpg';double imageWidth = 0;double imageHeight = 0;double scale = 1;double angle = 0;Future? future;@overridevoid initState() {future = download();super.initState();}@overrideWidget build(BuildContext context) {return Scaffold(backgroundColor: const Color(0xFFF5F9FA),appBar: AppBar(title: const Text('图片旋转'),),body: FutureBuilder(future: future,builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot) {if (snapshot.data == null) {return const SizedBox();}Uint8List bytes = snapshot.data;return Column(children: [ElevatedButton(onPressed: () {changeAngle(false);},child: const Text('逆时针')),ElevatedButton(onPressed: () {changeAngle(true);},child: const Text('顺时针')),AspectRatio(aspectRatio: rate,child: Container(width: double.infinity,height: double.infinity,color: Colors.blue,padding: const EdgeInsets.all(6),child: LayoutBuilder(builder: (c, b) {if (angle % pi != 0) {scale = getMinMaxScaleSingle(b.maxWidth, b.maxHeight);} else {scale = 1;}return Transform.scale(scale: scale,child: Transform.rotate(angle: angle,child: Image.memory(bytes),),);},),),)],);},),);}changeAngle(bool clockwise) {if (clockwise) {angle += pi / 2;if (angle == pi * 2) angle = 0;} else {angle -= pi / 2;if (angle == -pi * 2) angle = 0;}if (mounted) setState(() {});}//获得单个图片区域的最小最大缩放比例double getMinMaxScaleSingle(double width, double height) {final fittedSizes = getFittedSizes(width, height);double imgWidth = fittedSizes.destination.width;double imgHeight = fittedSizes.destination.height;if (angle % pi != 0) {imgWidth = fittedSizes.destination.height;imgHeight = fittedSizes.destination.width;}double scaleX = width / imgWidth;double scaleY = height / imgHeight;double minScale = scaleX > scaleY ? scaleY : scaleX;return minScale;}FittedSizes getFittedSizes(double width, double height) {return applyBoxFit(BoxFit.contain, Size(imageWidth, imageHeight), Size(width, height));}Future download() async {var httpClient = HttpClient();try {var request = await httpClient.getUrl(Uri.parse(imageUrl));var response = await request.close();var imageByte = await consolidateHttpClientResponseBytes(response);var codec = await ui.instantiateImageCodec(imageByte);ui.FrameInfo fi = await codec.getNextFrame();imageWidth = fi.image.width * 1.0;imageHeight = fi.image.height * 1.0;return imageByte;} catch (error) {return null;}}
}