I am a beginner in Flutter development, I have an issue about filtering the size of pixels in image. I have a class that has a function to pick an image from gallery using file_picker
, I want to filter the image that user can only upload the image that are 300x300 pixels. I have tried to modify my code, but when I try it, it seems still not working and the image more than 300x300 pixels is still can be uploaded by user. How can I fix this problem? Can anyone help me to find the solution of this problem?
Here is my code:
class UploadImageField extends StatefulWidget {
const UploadImageField({super.key, required this.onFileSelected});
final void Function(String filePath) onFileSelected;
@override
State<UploadImageField> createState() => _UploadImageFieldState();
}
class _UploadImageFieldState extends State<UploadImageField> {
String? _fileName;
File? _selectedFile;
void _pickFile() async {
final result = await FilePicker.platform.pickFiles(
type: FileType.custom,
allowedExtensions: ['jpg', 'jpeg', 'png'],
);
if (result != null && result.files.isNotEmpty) {
final file = result.files.first;
if (file.size <= 5 * 1024 * 1024) {
// Reads file data into a byte array
final imageBytes = File(file.path!).readAsBytesSync();
// Decode the image to get dimensions
final image = img.decodeImage(imageBytes);
if (image != null && image.width == 300 && image.height == 300) {
// If the size is appropriate, save the file and send the path to the callback
setState(() {
_fileName = file.name;
_selectedFile = File(file.path!);
});
widget.onFileSelected(file.path!);
} else {
// If the size does not match, provide an error message
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Image must be exactly 300x300 pixels')),
);
}
} else {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('File size exceeds 5MB')),
);
}
}
}
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Dokumen Pendukung',
style: GoogleFonts.poppins(
fontSize: 16,
fontWeight: FontWeight.w500,
),
),
const SizedBox(height: 8),
GestureDetector(
onTap: _pickFile,
child: Container(
height: 150,
width: double.infinity,
padding: const EdgeInsets.symmetric(horizontal: 8),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8),
border: Border.all(color: Colors.grey.shade600),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Icon(Icons.cloud_upload, size: 32, color: Colors.indigo),
const SizedBox(height: 8),
Text(
_fileName ?? 'Click to upload',
style: GoogleFonts.poppins(
fontSize: 14,
color: Colors.indigo,
),
),
const SizedBox(height: 4),
Text(
'JPEG, JPG, PNG or PDF (max 5MB, 300x300 pixels)',
style: GoogleFonts.poppins(
fontSize: 12,
color: Colors.indigo,
),
),
],
),
),
),
],
);
}
}
I have been try your code but it work fine maybe because I'm using decodeImageFromList(Uint8List)
Please try this code and tell me is it work for you
void pickFile() async {
final result = await FilePicker.platform.pickFiles(
type: FileType.custom,
allowedExtensions: ['jpg', 'jpeg', 'png'],
);
if (result != null && result.files.isNotEmpty) {
final file = result.files.first;
if (file.size <= 5 * 1024 * 1024) {
final imageBytes = File(file.path!).readAsBytesSync();
final image = await decodeImageFromList(imageBytes);
if (image.width == 300 && image.height == 300) {
log('correct size');
} else {
log('image width :: ${image.width}');
log('image height :: ${image.height}');
ScaffoldMessenger.of(Get.context!).showSnackBar(
const SnackBar(content: Text('Image must be exactly 300x300 pixels')),
);
}
} else {
ScaffoldMessenger.of(Get.context!).showSnackBar(
const SnackBar(content: Text('File size exceeds 5MB')),
);
}
}
}