image_validator 0.2.0
image_validator: ^0.2.0 copied to clipboard
A comprehensive Dart package for image file validation supporting JPEG, PNG, WebP, HEIF, and AVIF formats with robust validation for file integrity, dimensions, and file sizes.
Image Validator #
A simple, powerful Dart package for validating image files before upload or storage. Supports JPEG, PNG, WebP, HEIF, and AVIF formats with built-in checks for file size, dimensions, and corruption.
Why Use This Package? #
Before uploading or saving images to your server, you need to ensure they meet your requirements. This package helps you:
- ✅ Validate file size (prevent huge uploads)
- ✅ Check image dimensions (ensure proper width/height)
- ✅ Detect corrupted files (avoid broken images)
- ✅ Support multiple formats (JPEG, PNG, WebP, HEIF, AVIF)
- ✅ Work across all platforms (Android, iOS, Web, Desktop)
Quick Start #
import 'dart:io';
import 'package:image_validator/image_validator.dart';
// 1. Detect image type
final file = File('path/to/image.jpeg');
final detector = ImageTypeDetector(
type: DetectorType.hybrid,
allowedtypes: [ImageType.jpeg, ImageType.png],
);
final imageType = detector.detect(file);
// 2. Set up validation rules
final sizeValidator = SizeValidator(
maxSizeInMB: 10,
imagetype: imageType,
);
// 3. Validate the image
final result = await sizeValidator.validate(file);
// 4. Check result
if (result.isValid) {
print('✓ Image is ready to upload!');
} else {
print('✗ Validation failed: ${result.errorMessage}');
}
Installation #
Add to your pubspec.yaml:
dependencies:
image_validator: ^0.2.0
Then run:
flutter pub get
Requirements: Flutter >=3.3.0 | Dart >=2.18.0 <4.0.0
Platform Support: ✅ Android | iOS | macOS | Web | Linux | Windows
Core Concepts #
Public Validators #
The package provides three main validator types that work with all supported formats:
SizeValidator - File Size Validation
Validates that image files meet size constraints:
SizeValidator(
maxSizeInMB: 10,
minSizeInMB: 0.1, // Optional
imagetype: ImageType.jpeg,
)
DimensionValidator - Image Dimension Validation
Validates that images meet width/height constraints:
DimensionValidator(
maxWidth: 3000,
maxHeight: 3000,
minWidth: 100, // Optional
minHeight: 100, // Optional
imagetype: ImageType.jpeg,
)
CorruptValidator - File Integrity Validation
Detects corrupted or invalid image files:
CorruptValidator(
imagetype: ImageType.jpeg,
)
Supported Formats #
| Format | MIME Type | Extensions |
|---|---|---|
| JPEG | image/jpeg | .jpg, .jpeg |
| PNG | image/png | .png |
| WebP | image/webp | .webp |
| HEIF | image/heif | .heif, .heic |
| AVIF | image/avif | .avif |
Factory Pattern (Recommended) #
The ImageValidatorFactory lets you define all validation rules once and reuse them throughout your app:
import 'dart:io';
import 'package:image_validator/image_validator.dart';
Future<void> validateImage(File imageFile) async {
// Detect image type
final detector = ImageTypeDetector(
type: DetectorType.hybrid,
allowedtypes: [
ImageType.jpeg,
ImageType.png,
ImageType.webp,
ImageType.heif,
ImageType.avif,
],
);
final imageType = detector.detect(imageFile);
if (imageType == ImageType.unsupported) {
print('Unsupported image format');
return;
}
// Create factory with validation rules for all formats
final factory = ImageValidatorFactory(
jpeg: [
SizeValidator(maxSizeInMB: 10, imagetype: ImageType.jpeg),
DimensionValidator(
maxWidth: 3000,
maxHeight: 3000,
minWidth: 100,
minHeight: 100,
imagetype: ImageType.jpeg,
),
CorruptValidator(imagetype: ImageType.jpeg),
],
png: [
SizeValidator(maxSizeInMB: 10, imagetype: ImageType.png),
DimensionValidator(
maxWidth: 3000,
maxHeight: 3000,
imagetype: ImageType.png,
),
CorruptValidator(imagetype: ImageType.png),
],
webp: [
SizeValidator(maxSizeInMB: 10, imagetype: ImageType.webp),
DimensionValidator(
maxWidth: 3000,
maxHeight: 3000,
imagetype: ImageType.webp,
),
CorruptValidator(imagetype: ImageType.webp),
],
heif: [
SizeValidator(maxSizeInMB: 10, imagetype: ImageType.heif),
DimensionValidator(
maxWidth: 3000,
maxHeight: 3000,
imagetype: ImageType.heif,
),
CorruptValidator(imagetype: ImageType.heif),
],
avif: [
SizeValidator(maxSizeInMB: 10, imagetype: ImageType.avif),
DimensionValidator(
maxWidth: 3000,
maxHeight: 3000,
imagetype: ImageType.avif,
),
CorruptValidator(imagetype: ImageType.avif),
],
allowedtypes: [
ImageType.jpeg,
ImageType.png,
ImageType.webp,
ImageType.heif,
ImageType.avif,
],
);
// Validate the image
final result = await factory.validate(file: imageFile);
// Handle the result
if (result.isValid) {
print('✓ Image validation passed!');
print('Image type: ${result.fileType}');
} else {
print('✗ Validation failed: ${result.errorMessage}');
}
}
Benefits:
- ✅ Define rules once, use everywhere
- ✅ Easy to maintain and update
- ✅ Sequential validation (stops at first failure)
- ✅ Type-safe validation per format
Image Type Detection #
Detect image types using the ImageTypeDetector with different strategies:
final detector = ImageTypeDetector(
type: DetectorType.hybrid,
allowedtypes: [ImageType.jpeg, ImageType.png, ImageType.webp],
);
final imageType = detector.detect(file);
Detection Strategies #
-
DetectorType.hybrid- Combines file signature + extension (recommended)- Most reliable, uses magic bytes and file extension
-
DetectorType.signature- File magic bytes only- Fast and reliable, independent of file name
-
DetectorType.extension- File extension only- Fastest, but can be fooled by renamed files
// Using different strategies
final hybridDetector = ImageTypeDetector(
type: DetectorType.hybrid,
allowedtypes: [ImageType.jpeg, ImageType.png],
);
final signatureDetector = ImageTypeDetector(
type: DetectorType.signature,
allowedtypes: [ImageType.jpeg, ImageType.png],
);
final extensionDetector = ImageTypeDetector(
type: DetectorType.extension,
allowedtypes: [ImageType.jpeg, ImageType.png],
);
Validation Result #
All validators return a ValidationResult object:
class ValidationResult {
final bool isValid; // true if validation passed
final String? errorMessage; // Error description if failed
final ImageType? fileType; // Detected image type
final File? file; // Original file reference
}
Usage:
final validator = SizeValidator(
maxSizeInMB: 10,
imagetype: ImageType.jpeg,
);
final result = await validator.validate(file);
if (result.isValid) {
uploadToServer(result.file!);
} else {
showError(result.errorMessage!);
}
Real-World Example #
import 'package:image_picker/image_picker.dart';
class ProfilePictureUploader {
final ImageValidatorFactory _validator = ImageValidatorFactory(
jpeg: [
SizeValidator(maxSizeInMB: 5, imagetype: ImageType.jpeg),
DimensionValidator(
maxWidth: 2000,
maxHeight: 2000,
minWidth: 200,
minHeight: 200,
imagetype: ImageType.jpeg,
),
CorruptValidator(imagetype: ImageType.jpeg),
],
png: [
SizeValidator(maxSizeInMB: 5, imagetype: ImageType.png),
DimensionValidator(
maxWidth: 2000,
maxHeight: 2000,
minWidth: 200,
minHeight: 200,
imagetype: ImageType.png,
),
CorruptValidator(imagetype: ImageType.png),
],
allowedtypes: [ImageType.jpeg, ImageType.png],
);
Future<void> uploadProfilePicture() async {
final picker = ImagePicker();
final pickedFile = await picker.pickImage(source: ImageSource.gallery);
if (pickedFile == null) return;
final file = File(pickedFile.path);
final detector = ImageTypeDetector(
type: DetectorType.hybrid,
allowedtypes: [ImageType.jpeg, ImageType.png],
);
final imageType = detector.detect(file);
if (imageType == ImageType.unsupported) {
showError('Unsupported image format');
return;
}
final result = await _validator.validate(file: file);
if (result.isValid) {
await uploadToServer(file);
} else {
showError(result.errorMessage!);
}
}
}
API Overview #
Main Classes #
ImageValidator- Abstract base class for all validatorsSizeValidator- Validates file size in MBDimensionValidator- Validates image dimensionsCorruptValidator- Detects corrupted filesImageTypeDetector- Detects image type using different strategiesImageValidatorFactory- Creates pre-configured validator chainsValidationResult- Result of validation containing status and metadata
Enums #
ImageType- Supported image formats (jpeg, png, webp, heif, avif, unsupported)DetectorType- Detection strategies (extension, signature, hybrid)
Contributing #
Contributions are welcome! Help make this package better:
- 🐛 Report bugs or issues
- ✨ Submit feature requests
- 🔧 Create pull requests
- 💬 Share feedback
License #
See LICENSE file for details.
Need Help? Check the example folder for complete working code or open an issue on GitHub.