【问题标题】:How to: rotate a selected/set image (Flutter)如何:旋转选定/设置的图像 (Flutter)
【发布时间】:2022-05-13 21:47:28
【问题描述】:

从图像选择器(图库/相机)中选择图像后,我设法将图像旋转为横向/纵向..

这很好用,并将继续将新图像设置为我想要的方向..

但是,我正在尝试使用相同的方法来旋转已选择/设置的图像,但它不起作用..

这是我使用的逻辑:

import 'package:image/image.dart' as img;

  void _rotateImage(File file) async {
    print('>>> rotating image');
    try {
      List<int> imageBytes = await file.readAsBytes();
      final originalImage = img.decodeImage(imageBytes);
      print('>>> original width: ${originalImage.width}');
      img.Image fixedImage;
      fixedImage = img.copyRotate(originalImage, 90);
      print('>>> fixed width: ${fixedImage.width}');
      final fixedFile = await file.writeAsBytes(img.encodeJpg(fixedImage));
      setState(() {
        print('>>> setting state');
        _image = fixedFile;
      });
    } catch (e) {
      print(e);
    }
  }

我什至可以看到图像在设置状态之前已经旋转,但它仍然没有在屏幕上更新(这显示了两次尝试,而不是多次尝试)

I/flutter (18314): >>> rotating image
I/flutter (18314): >>> original width: 450
I/flutter (18314): >>> fixed width: 360
I/flutter (18314): >>> setting state
I/flutter (18314): >>> rotating image
I/flutter (18314): >>> original width: 360
I/flutter (18314): >>> fixed width: 450
I/flutter (18314): >>> setting state

有谁知道为什么这种方法在从相机/图库中选择新图像时有效,但在使用已处于状态的文件时无效?

[编辑] 我认为这可能与正在使用的相同文件路径有关。所以我在下面添加了这段代码,虽然它使图像刷新,但在几分之一秒内,它仍然不显示旋转后的图像 [/EDIT]

import 'package:image/image.dart' as img;

  void _rotateImage(File file) async {
    try {
      Random random = new Random();
      int randomNumber = random.nextInt(1000000);

      final newFile = await file.copy(
          '/data/user/0/!PRIVATE!/cache/rotatedImage$randomNumber.jpg');

      List<int> imageBytes = await newFile.readAsBytes();

      final originalImage = img.decodeImage(imageBytes);

      img.Image fixedImage;
      fixedImage = img.copyRotate(originalImage, 90);

      final fixedFile = await newFile.writeAsBytes(img.encodeJpg(fixedImage),
          mode: FileMode.append, flush: true);

      setState(() {
        _image = fixedFile;
      });
    } catch (e) {
      print(e);
    }
  }

下面是一些代码,用于显示选择图像并选择旋转时发生的情况

import 'package:image/image.dart' as img;

  void _pickImage() async {
    Navigator.pop(context);
    try {
      final pickedFile =
          await _imagePicker.getImage(source: ImageSource.gallery);
      File file = File(pickedFile.path);
      if (pickedFile != null && _rotateToLandscape) {
        await _setImageToLandscape(file);
      } else if (pickedFile != null) {
        await _setImageToPortrait(file);
      }
    } catch (e) {
      print(e);
    }
  }

  Future<void> _setImageToLandscape(File file) async {
    print('>>> setting image to landscape');
    try {
      setState(() {
        _loading = true;
      });
      var decodedImage = await decodeImageFromList(file.readAsBytesSync());
      int width = decodedImage.width;
      int height = decodedImage.height;
      if (width > height) {
        print('>>> returing original image');
        _setSelectedImage(file);
      } else if (width < height) {
        print('>>> rotating image');
        List<int> imageBytes = await file.readAsBytes();
        final originalImage = img.decodeImage(imageBytes);
        img.Image fixedImage;
        fixedImage = img.copyRotate(originalImage, -90);
        final fixedFile = await file.writeAsBytes(img.encodeJpg(fixedImage));
        _setSelectedImage(fixedFile);
      }
    } catch (e) {
      print(e);
    } finally {
      setState(() {
        _loading = false;
      });
    }
  }



 void _setSelectedImage(File file) {
    switch (_selectedImage) {
      case 1:
        setState(() {
          _image = file;
          widget.setImage(image: file);
        });
        break;
      case 2:
        setState(() {
          _image2 = file;
          widget.setImage(image2: file);
        });
        break;
      case 3:
        setState(() {
          _image3 = file;
          widget.setImage(image3: file);
        });
        break;
    }
  }

【问题讨论】:

标签: flutter dart


【解决方案1】:

您在写入FileMode.append 时设置了FileMode,因此它将在旧图像之后的同一文件中添加新图像(因为您复制了旧文件),这意味着在解码新图像时只有第一部分将被解码(原始图像)

所以要修复它,您应该能够从写入中删除 mode

【讨论】:

    【解决方案2】:
    Future<File?> _rotateImage(
          String url, String fileExt, AttachmentModel item) async {
        try {
          File file;
          if (item.file == null) {
            file = await urlToFile(url, fileExt, true);
          } else {
            file = await urlToFile(url, fileExt, false);
            List<int> temp = await item.file!.readAsBytes();
            await file.writeAsBytes(temp);
          }
    
          List<int> imageBytes = await file.readAsBytes();
          final originalImage = img.decodeImage(imageBytes);
          print('previous width: ${originalImage?.width}');
          img.Image newImage;
          newImage = img.copyRotate(originalImage!, 90);
          print('width: ${newImage.width}');
          final fixedFile = await file.writeAsBytes(img.encodeJpg(newImage));
          int index = attachments!.indexOf(item);
          attachments![index] = AttachmentModel(
            attachmentUrl: fixedFile.path,
            fileExt: fileExt,
            file: fixedFile,
          );
          setState(() {});
          return fixedFile;
        } catch (e) {
          print(e);
          return null;
        }
      }
    
      Future<File> urlToFile(String imageUrl, String fileExt, bool isNet) async {
        Directory tempDir = await getTemporaryDirectory();
        String tempPath = tempDir.path;
        File file = File(tempPath + DateTime.now().toString() + '.$fileExt');
        if (!isNet) return file;
        Uri uri = Uri.parse(imageUrl);
        http.Response response = await http.get(uri);
        await file.writeAsBytes(response.bodyBytes);
        return file;
      }
    

    不要使用原始文件,在原始文件上创建一个新文件,我以这段代码为例。我知道为时已晚,但也许它可以帮助某人

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-01-14
      • 1970-01-01
      • 1970-01-01
      • 2016-09-23
      • 1970-01-01
      • 2019-05-28
      • 1970-01-01
      相关资源
      最近更新 更多