ZipDrop automatically converts supported images to WebP format, dramatically reducing file sizes while maintaining visual quality.
The following image formats are automatically converted to WebP:
- JPG/JPEG - Most common photo format
- PNG - Screenshots and graphics
- GIF - Animated images (first frame)
- BMP - Bitmap images
- TIFF/TIF - High-quality images
fn is_image(path: &Path) -> bool {
matches!(
ext.as_deref(),
Some("jpg" | "jpeg" | "png" | "gif" | "bmp" | "tiff" | "tif")
)
}
From processor.rs:148-158
WebP files are passed through without re-conversion to avoid quality loss.
Conversion Quality
ZipDrop uses the Rust image crate to convert images at 80% quality, which provides:
- 50-80% smaller file sizes compared to original JPG/PNG
- Visually identical quality for most use cases
- Fast processing using native Rust performance
pub fn convert_to_webp(input_path: &Path, output_dir: &Path) -> Result<ProcessResult, String> {
// Open original image
let img = image::open(input_path)
.map_err(|e| format!("Failed to open image: {}", e))?;
// Generate unique output filename
let unique_id = &uuid::Uuid::new_v4().to_string()[..8];
let output_path = output_dir.join(format!("{}_{}.webp", stem, unique_id));
// Save as WebP
let output_file = File::create(&output_path)?;
let mut writer = BufWriter::new(output_file);
img.write_to(&mut writer, ImageFormat::WebP)
.map_err(|e| format!("Failed to write WebP: {}", e))?;
Ok(ProcessResult {
output_path,
original_size,
processed_size,
file_type: "webp".to_string(),
})
}
From processor.rs:171-209
When Conversion Happens
Image conversion only occurs for single image files. The logic is:
if paths.len() == 1 {
let path = &paths[0];
if is_image(path) && !is_webp(path) {
// Single convertible image → WebP
convert_to_webp(path, output_dir)
} else {
// Single non-image or already WebP → passthrough
copy_file(path, output_dir)
}
} else {
// Multiple files → ZIP
create_zip(&paths, output_dir)
}
From processor.rs:299-312
If you drop 2+ images, they’ll be zipped together instead of converted. Drop one image at a time for WebP conversion.
File Size Reduction
Here’s a typical example of file size savings:
| Original Format | Original Size | WebP Size | Reduction |
|---|
| screenshot.png | 2.4 MB | 580 KB | 76% |
| photo.jpg | 3.1 MB | 920 KB | 70% |
| diagram.bmp | 8.5 MB | 1.2 MB | 86% |
The ProcessResult struct tracks both sizes:
pub struct ProcessResult {
pub output_path: PathBuf,
pub original_size: u64, // Before conversion
pub processed_size: u64, // After conversion
pub file_type: String, // "webp"
}
From processor.rs:36-42
Unique Filenames
Each converted file gets a unique 8-character ID to prevent conflicts:
let unique_id = &uuid::Uuid::new_v4().to_string()[..8];
let output_path = output_dir.join(format!("{}_{}.webp", stem, unique_id));
// Example: photo_a3f9d2e1.webp
This ensures multiple uploads of the same file don’t overwrite each other in R2.
Some image formats are not auto-converted:
- HEIC/HEIF - Modern Apple formats (passthrough)
- SVG - Vector graphics (passthrough)
- ICO - Icon files (passthrough)
- RAW formats (CR2, NEF, ARW) - Professional photos (passthrough)
These files are uploaded as-is without conversion.
Very large images (>500MB) cannot be processed. Resize them first or use a batch image processor.
Browser Compatibility
WebP is supported by:
- ✅ Chrome/Edge (all versions)
- ✅ Firefox 65+
- ✅ Safari 14+
- ✅ iOS Safari 14+
- ✅ Android Chrome
For legacy browser support, consider keeping original JPG/PNG files.
Technical Details
ZipDrop uses these crates for image processing:
[dependencies]
image = "0.24"
uuid = { version = "1.0", features = ["v4"] }
The image crate provides:
- Hardware-accelerated decoding
- Multi-threaded processing
- Memory-safe Rust implementation
- Support for all major formats