Transform images into vintage film negatives with authentic effects. Production-ready REST API built in pure C.
- ποΈ Authentic Film Effects - Color inversion, grain, sprocket holes, amber cast
- π Bidirectional Processing - Convert to negative and back to positive
- β‘ High Performance - Written in C with zero external dependencies
- π Production Ready - Deployed on Railway with 200+ concurrent connections
- π Secure - Built-in validation, timeouts, and security headers
- π¦ Easy Deploy - One-click Railway deployment or Docker
See docs/RAILWAY_DEPLOY.md for detailed instructions.
# Clone repository
git clone https://github.com/yourusername/film-processor-api.git
cd film-processor-api
# Build
make
# Run
./bin/film_server
# Server running at http://localhost:8080docker build -f Dockerfile.railway -t film-processor .
docker run -p 8080:8080 film-processorcurl -X POST http://localhost:8080/api/to-negative \
-F "image=@photo.jpg" \
-o negative.jpg
# For Railway deployment, use HTTP/1.1 for clean transfers
curl --http1.1 -X POST https://your-app.railway.app/api/to-negative \
-F "image=@photo.jpg" \
-o negative.jpgcurl -X POST http://localhost:8080/api/to-positive \
-F "image=@negative.jpg" \
-o restored.jpg
# For Railway deployment
curl --http1.1 -X POST https://your-app.railway.app/api/to-positive \
-F "image=@negative.jpg" \
-o restored.jpgcurl http://localhost:8080/health
# {"status":"healthy","service":"film-processor","version":"2.0"}async function convertToNegative(file) {
const formData = new FormData();
formData.append('image', file);
const response = await fetch('http://localhost:8080/api/to-negative', {
method: 'POST',
body: formData
});
return await response.blob();
}import requests
def convert_to_negative(image_path):
with open(image_path, 'rb') as f:
response = requests.post(
'http://localhost:8080/api/to-negative',
files={'image': f}
)
return response.contentfilm-processor-api/
βββ src/ # Source code
β βββ server_v2.c # Production API server
β βββ film_processor.c # Core processing library
β βββ vintage_filter.c # CLI tool
βββ include/ # Header files
β βββ film_processor.h
β βββ stb_image.h
β βββ stb_image_write.h
βββ docs/ # Documentation
β βββ API.md
β βββ RAILWAY_DEPLOY.md
β βββ CHANGELOG.md
β βββ RELEASE_NOTES_v2.0.md
βββ scripts/ # Utility scripts
β βββ test_api.sh
βββ bin/ # Compiled binaries (generated)
βββ Makefile.production # Production build
βββ Dockerfile.railway # Railway deployment
βββ README.md # This file
- GCC 7.0+ or Clang 10.0+
- Make
- pthread support
- Linux/macOS/WSL
# Production build (optimized)
make
# Debug build
make debug
# Clean
make clean
# Install to /usr/local/bin
sudo make install
# Run tests
make test- β¨ Color inversion (true negative)
- ποΈ Orange/amber film base cast
- π Film grain texture
- π¬ Sprocket hole borders
- π Color restoration
- π§Ή Orange cast removal
- βοΈ Border cleanup
- π· Tone balancing
| Metric | Value |
|---|---|
| Max Concurrent Connections | 200 |
| Max Upload Size | 20MB |
| Request Timeout | 30 seconds |
| Processing Time (600x400) | ~150ms |
| Processing Time (3000x2000) | ~500ms |
| Memory Usage | ~512MB |
| Supported Formats | JPG, PNG, BMP, TGA |
- β Request size validation (20MB limit)
- β Content-Type verification
- β Timeout protection (30s)
- β Input sanitization
- β Security headers (XSS, Frame Options, Content-Type)
- β CORS enabled for web applications
| Endpoint | Method | Description |
|---|---|---|
/api/to-negative |
POST | Convert image to film negative |
/api/to-positive |
POST | Convert negative back to positive |
/health |
GET | Health check with version info |
/ |
GET | API information |
- API Documentation - Complete API reference
- Railway Deployment - Deployment guide
- Changelog - Version history
- Release Notes - Latest release details
# Health check
curl http://localhost:8080/health
# Test with image
curl -X POST http://localhost:8080/api/to-negative \
-F "image=@test.jpg" -o result.jpg
# Run automated tests
./scripts/test_api.sh test.jpg- Push to GitHub
- Connect to Railway
- Auto-deploys from
Dockerfile.railway
docker build -f Dockerfile.production -t film-api:2.0 .
docker run -d -p 8080:8080 --name film-api film-api:2.0make production
./bin/film_server --port 8080Contributions welcome! Please:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
- stb_image - Sean Barrett's excellent header-only image library
- Railway - For providing an excellent deployment platform
- Contributors - Everyone who has helped improve this project
- π Issues: GitHub Issues
- π§ Email: support@filmprocessor.com
- π Docs: docs/
Give a βοΈ if this project helped you!
Built with β€οΈ in C | Version 2.0.0 | Production Ready β