作法:旋转选定/设定的影像(颤动) [英] How to: rotate a selected/set image (Flutter)

查看:60
本文介绍了作法:旋转选定/设定的影像(颤动)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I've managed to rotate images to landscape/portrait after selecting them from Image picker (gallery/camera) ..

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

This works fine, and will continue set new images to my desired orientation ..

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

However, I'm trying to use the same method to rotate an already selected/set image and it doesn't work ..

这是我使用的逻辑:

  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 can even see that the image is getting rotated before setting state, but it still doesn't update on screen (this is showing two attempts, not multiple in one)

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

有人知道从照相机/画廊中拾取新图像时为何使用此方法,而使用已经处于状态的文件时却不知道吗?

Does anyone has any idea why this method works when picking a new image from the camera/gallery but won't when using a file that's already in the state?

我认为这可能与使用相同的文件路径有关.因此,我在下面添加了此代码,尽管它使图像刷新,但是在不到一秒钟的时间内,它仍然没有显示旋转的图像[/EDIT]

I thought it may be something to do with the same file path being used. So I added this code below and although it makes the image refresh, for a fraction of a second, it still doesn't show the rotated image [/EDIT]

  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);
    }
  }

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

Below is some code to show what's happening when selecting an image and choosing to rotate

  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;
    }
  }

推荐答案

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

You've set the FileMode when writing to FileMode.append so it will add the new image in the same file after the old image (since you copied the old file) which means that when decoding the new image only the first part will get decoded (the original image)

因此,要对其进行修复,您应该只能从写入操作中删除 mode .

So to fix it you should just be able to remove the mode from the write

这篇关于作法:旋转选定/设定的影像(颤动)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆