我已经设法旋转图像后,选择他们从图像选择器(画廊/相机)的风景/肖像。
这工作正常,并将继续设置新的图像到我想要的方向。
然而,我试图使用相同的方法来旋转一个已经选择/设置的图像,它不工作。
下面是我使用的逻辑:
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]我想这可能是因为使用了相同的文件路径。所以我在下面添加了这段代码,虽然它使图像刷新,但在几分之一秒内,它仍然不显示旋转后的图像[/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;
}
}
3条答案
按热度按时间insrf1ej1#
您已在写入
FileMode.append
时设置了FileMode
,因此它将在同一文件中的旧图像之后添加新图像(因为您复制了旧文件),这意味着在解码新图像时,仅解码第一部分(原始图像)因此,要修复此问题,您只需从写操作中删除
mode
即可i7uq4tfw2#
不要使用原始文件,在原始文件上创建一个新的,我把这个代码作为一个例子。我知道这是晚了,但也许它可以帮助别人
hgb9j2n63#
我有同样的问题,我的照片捕捉应用程序,其中使用两个相机(正面和背面)。
问题是前置摄像头拍摄的照片被水平翻转了。
我所做的是检测前置摄像头是否在使用中,如果没有,就水平翻转图像;按原样返回图像。