This project provides an API to extract statistical information from images, including EXIF data and color analysis (average and dominant colors).
- EXIF Data Extraction: Retrieves standard EXIF (Exchangeable image file format) data from images.
- Processes and validates GPS information, filtering out empty or default values.
- Handles non-serializable EXIF values by converting them to string representations.
- Color Analysis:
- Average Color: Calculates the average color of an image. Supports multiple averaging methods:
arithmetic(default)geometric(Configurable via theAVERAGING_METHODenvironment variable).
- Dominant Color: Identifies the most prominent color in an image using HSV color space clustering.
- Average Color: Calculates the average color of an image. Supports multiple averaging methods:
- Image Processing:
- Handles image input via file upload or URL.
- Resizes large images (max dimension > 512px) to a thumbnail for faster processing while preserving aspect ratio.
- Converts images to RGBA format and filters out transparent pixels before color analysis.
- LitServe Integration: Built using
litservefor efficient serving.
The server is implemented in server.py.
The makefile provides a convenient way to run the server:
make runThis command uses uv run server.py.
You can also run it directly using a Python interpreter capable of running the dependencies (e.g., after setting up a virtual environment and installing packages):
python server.pyThe server can be configured using the following environment variables:
PORT: Port to run the server on (default:8010).LOG_LEVEL: Logging level (e.g.,INFO,DEBUG; default:INFO).AVERAGING_METHOD: Method for calculating average color (arithmetic,harmonic,geometric; default:arithmetic).NUM_API_SERVERS: Number of API server instances (default:1).WORKERS_PER_DEVICE: Number of worker threads per device (default:1).
-
Description: Analyzes an image and returns its EXIF data and color statistics.
-
Request:
- Method:
POST - Content-Type:
multipart/form-data(for file uploads) orapplication/json(for URL inputs). - Body:
- For file upload: Form data with a file field named
content. - For URL input: JSON object with a key
contentwhose value is the image URL string (e.g.,{"content": "http://example.com/image.jpg"}).- Note: The server includes a hack to replace
localhost:3210withbackend:3210in URLs, which might be relevant for specific deployment scenarios.
- Note: The server includes a hack to replace
- For file upload: Form data with a file field named
- Method:
-
Response:
application/json- Success (200 OK):
If
{ "exif_data": { // ... various EXIF tags and values ... "GPSInfo": { /* GPS data if valid, otherwise omitted */ } }, "color_data": { "avg_color": { "rgb": [0.R, 0.G, 0.B], // RGB values (0-1 range) "hex": "#RRGGBB", // Hex color code "method": "method_used" }, "dominant_color": { "rgb": [0.R, 0.G, 0.B], // RGB values (0-1 range) "hex": "#RRGGBB" // Hex color code } } }color_datacould not be determined (e.g., image has no valid pixels), it might benull. Ifexif_datacould not be extracted, it might be empty or partially filled.
- Success (200 OK):
The client.py script provides a simple command-line interface to send an image to the API and print the response.
Usage:
python client.py [path_to_your_image]If no image path is provided, it defaults to trying to send snowman.png from the current directory.
The script will:
- Check if the image file exists.
- Send a POST request to
http://127.0.0.1:8001/statswith the image file. - Print the HTTP status code and the JSON response from the server.
Example (using uv via Makefile):
First, ensure you have an image (e.g., snowman.png, which can be downloaded using make snowman.png). Then:
make client-testThis will run uv run client.py snowman.png (implicitly, as snowman.png is the default if no argument is given to client.py after uv run).
To test with a different image:
uv run client.py my_image.jpgThe makefile includes a curl-test target that demonstrates how to interact with the API using curl.
Command from Makefile:
curl -X POST -F "[email protected]" http://127.0.0.1:8001/stats | jqExplanation:
curl -X POST: Sends a POST request.-F "[email protected]": Sends the filesnowman.pngas part of amultipart/form-datarequest. The@symbol tellscurlto read the content from the specified file. The field name iscontent.http://127.0.0.1:8001/stats: The URL of the API endpoint.| jq: Pipes the JSON output tojqfor pretty-printing.
Usage (via Makefile):
make curl-testThis target first ensures snowman.png is downloaded if it doesn't exist (due to the snowman.png dependency in the Makefile rule).
The makefile provides several useful targets:
run: Runs the server usinguv run server.py.snowman.png: Downloads a sample image (snowman.png) from Hugging Face if it doesn't already exist in the current directory. This is used for testing.curl-test: Tests the API endpoint usingcurlwithsnowman.png. It depends on thesnowman.pngtarget. The output is piped tojqfor readability.client-test: Tests the API endpoint using theclient.pyscript withsnowman.png(by default). It runsuv run client.py.
Key dependencies include:
litserve: For the API server framework.Pillow (PIL): For image manipulation.numpy: For numerical operations, especially on pixel data.requests: Used byserver.pyto fetch images from URLs and byclient.pyto interact with the API.uv: Used in the Makefile for running python scripts and managing environments (implied).
uv run will ensure dependencies are installed.
If you need a requirements.txt file, the command
uv pip compile pyproject.toml -o requirements.txtcan be used to gnerate one.