问题
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 ..
Here is the logic I'm using:
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;
}
}
回答1:
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)
So to fix it you should just be able to remove the mode from the write
来源:https://stackoverflow.com/questions/64498774/how-to-rotate-a-selected-set-image-flutter