310 lines
4.4 KiB
Markdown
310 lines
4.4 KiB
Markdown
# Skinbase Thumbnails Generation Rules
|
||
|
||
## Project
|
||
Skinbase.org – Artwork / Wallpapers / Skins CDN
|
||
|
||
CDN Base URL (Public):
|
||
https://files.skinbase.org
|
||
|
||
All generated thumbnails must be publicly accessible under this domain.
|
||
|
||
---
|
||
|
||
## 1. Goals
|
||
|
||
- Generate fast-loading, high-quality thumbnails
|
||
- Optimize for CDN delivery (Cloudflare + Apache)
|
||
- Preserve visual quality
|
||
- Keep consistent sizes
|
||
- Use immutable filenames (hash-based)
|
||
|
||
---
|
||
|
||
## 2. Supported Input Formats
|
||
|
||
Source images may be:
|
||
|
||
- JPG / JPEG
|
||
- PNG
|
||
- WEBP
|
||
- TIFF
|
||
- PSD (flattened first)
|
||
|
||
Before thumbnail generation:
|
||
- Strip EXIF metadata
|
||
- Convert to RGB
|
||
- Normalize orientation
|
||
|
||
---
|
||
|
||
## 3. Output Formats
|
||
|
||
Primary output:
|
||
|
||
- WEBP (preferred)
|
||
- AVIF (optional, future use)
|
||
- JPG (fallback only if WebP fails)
|
||
|
||
Default quality:
|
||
|
||
| Format | Quality |
|
||
|--------|---------|
|
||
| WebP | 82 |
|
||
| AVIF | 45 |
|
||
| JPG | 85 |
|
||
|
||
---
|
||
|
||
## 4. Thumbnail Sizes
|
||
|
||
Generate the following sizes for every image:
|
||
|
||
| Type | Width | Height | Crop |
|
||
|------|--------|--------|------|
|
||
| xs | 150px | auto | no |
|
||
| sm | 300px | auto | no |
|
||
| md | 600px | auto | no |
|
||
| lg | 1200px | auto | no |
|
||
| sq | 400px | 400px | yes |
|
||
|
||
Rules:
|
||
- Keep aspect ratio for non-square
|
||
- Never upscale
|
||
- Use center crop for sq
|
||
|
||
---
|
||
|
||
## 5. File Naming Convention
|
||
|
||
All thumbnails must use hash-based paths.
|
||
|
||
Format:
|
||
|
||
/lg/ff/2e/ff2e9ba2277b6b8296a0011c618ebf20c8c334a2.webp
|
||
|
||
Public URL example:
|
||
|
||
https://files.skinbase.org/lg/ff/2e/ff2e9ba2277b6b8296a0011c618ebf20c8c334a2.webp
|
||
|
||
Rules:
|
||
|
||
- Hash = SHA1(original_file + size + timestamp)
|
||
- First 2 bytes = dir1
|
||
- Next 2 bytes = dir2
|
||
- Next 2 bytes = dir3
|
||
- Filename = full hash
|
||
|
||
---
|
||
|
||
## 6. Directory Structure
|
||
|
||
Base directory (server):
|
||
|
||
/opt/www/virtual/skinbase/files/
|
||
|
||
Public mapping:
|
||
|
||
/opt/www/virtual/skinbase/files/lg/...
|
||
→ https://files.skinbase.org/lg/...
|
||
|
||
Structure:
|
||
|
||
/xs/
|
||
/sm/
|
||
/md/
|
||
/lg/
|
||
/sq/
|
||
|
||
Each contains hashed subfolders.
|
||
|
||
Do not store flat files.
|
||
|
||
---
|
||
|
||
## 7. Image Processing Rules
|
||
|
||
When generating thumbnails:
|
||
|
||
1. Load source image
|
||
2. Auto-orient
|
||
3. Strip metadata
|
||
4. Resize
|
||
5. Apply mild sharpening
|
||
6. Encode WebP
|
||
7. Save to CDN path
|
||
|
||
Sharpening:
|
||
|
||
- Radius: 0.5
|
||
- Amount: 0.3
|
||
- Threshold: 0
|
||
|
||
No heavy filters allowed.
|
||
|
||
---
|
||
|
||
## 8. Background Handling
|
||
|
||
For transparent images:
|
||
|
||
- Preserve alpha channel
|
||
- Do NOT add background
|
||
- Keep transparent WebP
|
||
|
||
For JPG fallback:
|
||
|
||
- Background: #000000
|
||
|
||
---
|
||
|
||
## 9. Performance Constraints
|
||
|
||
Target limits:
|
||
|
||
| Metric | Value |
|
||
|--------|-------|
|
||
| Max size (lg) | 400 KB |
|
||
| Max size (md) | 180 KB |
|
||
| Max size (sm) | 80 KB |
|
||
| Max size (xs) | 30 KB |
|
||
| Max size (sq) | 150 KB |
|
||
|
||
If exceeded:
|
||
- Lower quality by 5
|
||
- Re-encode
|
||
|
||
---
|
||
|
||
## 10. Security Rules
|
||
|
||
- Never execute embedded scripts
|
||
- Reject SVG with scripts
|
||
- Reject malformed images
|
||
- Validate MIME type
|
||
- Validate dimensions
|
||
|
||
Max source size: 100 MB
|
||
|
||
---
|
||
|
||
## 11. Cache Compatibility
|
||
|
||
All outputs must be CDN-ready.
|
||
|
||
Headers expected:
|
||
|
||
Cache-Control: public, max-age=31536000, immutable
|
||
|
||
Never generate filenames that change.
|
||
|
||
---
|
||
|
||
## 12. Regeneration Rules
|
||
|
||
Thumbnails must be regenerated when:
|
||
|
||
- Source image changes
|
||
- Processing rules change
|
||
- Quality profile updated
|
||
|
||
Old thumbnails must remain (cache-safe).
|
||
|
||
---
|
||
|
||
## 13. Laravel Integration
|
||
|
||
When thumbnail is created:
|
||
|
||
1. Save metadata to DB
|
||
2. Store hash
|
||
3. Store size
|
||
4. Store extension
|
||
5. Store public URL
|
||
|
||
Public URL format:
|
||
|
||
https://files.skinbase.org/{size}/{dir1}/{dir2}/{hash}.webp
|
||
|
||
Where:
|
||
|
||
{size} ∈ { xs, sm, md, lg, sq }
|
||
|
||
Model fields:
|
||
|
||
- thumb_hash
|
||
- thumb_ext
|
||
- thumb_size
|
||
- thumb_width
|
||
- thumb_height
|
||
- thumb_url
|
||
|
||
---
|
||
|
||
## 14. Logging
|
||
|
||
Every generation must log:
|
||
|
||
- Source path
|
||
- Output path
|
||
- Public URL
|
||
- Size
|
||
- Time
|
||
- Result
|
||
|
||
Format: JSON
|
||
|
||
Example:
|
||
|
||
{
|
||
"source": "upload/a.jpg",
|
||
"target": "lg/ff/2e/...",
|
||
"url": "https://files.skinbase.org/lg/ff/2e/...",
|
||
"size": "lg",
|
||
"time_ms": 120,
|
||
"status": "ok"
|
||
}
|
||
|
||
---
|
||
|
||
## 15. Error Handling
|
||
|
||
If generation fails:
|
||
|
||
- Log error
|
||
- Mark record as failed
|
||
- Do not retry more than 3x
|
||
- Alert admin
|
||
|
||
---
|
||
|
||
## 16. Forbidden Actions
|
||
|
||
AI agents must NOT:
|
||
|
||
- Overwrite existing thumbnails
|
||
- Change naming rules
|
||
- Change directory layout
|
||
- Serve via PHP
|
||
- Store in public uploads
|
||
- Generate relative URLs
|
||
|
||
All URLs must be absolute and use https://files.skinbase.org
|
||
|
||
---
|
||
|
||
## 17. Future Extensions
|
||
|
||
Planned:
|
||
|
||
- AVIF support
|
||
- DPR variants (2x, 3x)
|
||
- Smart cropping
|
||
- Face detection
|
||
- AI upscaling (optional)
|
||
|
||
Do not implement without approval.
|
||
|
||
---
|
||
|
||
## End of Rules
|