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.

pub package

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

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 validators
  • SizeValidator - Validates file size in MB
  • DimensionValidator - Validates image dimensions
  • CorruptValidator - Detects corrupted files
  • ImageTypeDetector - Detects image type using different strategies
  • ImageValidatorFactory - Creates pre-configured validator chains
  • ValidationResult - 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.

Libraries

image_validator
Image Validator - A comprehensive Dart package for validating image files.