A C++ microservice used to extract location and other forensic information from JPEG images.
The application needs to be compiled and linked to generate a binary for target platform. It can be run on host machine as well as in a container.
- Written in C++ with no library dependencies.
- Simple stateless microservice which can be hosted on cloud or on-premise.
- JSON logging support with ISO timestamp embedding.
- Health endpoint to monitor the service's availability.
- Native tool, which can be used as a CLI command to get JPEG EXIF data without running the server.
Any x86 Linux host can easily run this binary. Follow the instructions below :
GNU G++
and make
are enough to build this on any linux distro.
- Generate the binary : We have provided a makefile to ease build process.
make web
This will generate the binary at build/server
- Run the binary : We can run the binary using following command :
$./build/server
Listening on http://0.0.0.0:8888
By default, the logs will be redirected to stdout
. Pass the log-file as argument to enable file-logging.
./build/server $PATH_TO_LOG_FILE/log.txt
This will run the server.
To reduce the size of docker image, we have used alpine-linux as base with minimal required dependencies.
- Build the container image: Build the image using command below :
docker build . -t exif_service
- Spin up the container :
We can use docker run the container, the log directory is expected to be mounted at
/logs
.
docker run --rm -ti --net=host -v ${LOG_FILE_PATH}:/logs exif_service
The server provides two rest endpoints :
- Check health of the service : This endpoint is just like ping.
curl http://localhost:8888/health
- Run exif extraction:
The endpoint
jpeg
takesmultipart/form-data
and produces JSON output.
curl -X POST -F 'image=@{IMAGE_ABS_PATH}/image.jpg' -H Content-Type:multipart/form-data" http://localhost:8888/jpeg | json_pp
The output is a list of complete image information as per EXIF standard.
{
"focal_plane_xres" : 0,
"35m_focal_length" : 0,
"image_original_date_time" : "",
"image_width" : 0,
"expousre_bias" : 0,
"image_digitized_date_time" : "",
"exposure_time" : 0,
"f_stop" : 0,
"software" : "",
"subject_distance" : 0,
"iso_speed" : 0,
"lens_f_stop_min" : 0,
"bits_per_sample" : 0,
"image_date_time" : "",
"metering_mode" : 0,
"flash_mode" : 0,
"gps_precision" : 0,
"gps_alatitude" : 0,
"subsecond_time" : "",
"lens_f_stop_max" : 0,
"flash_returned_light" : 0,
"image_orientation" : 0,
"exposure_program" : 0,
"location" : {
"lat" : {
"minutes" : 0,
"degree" : 0,
"direction" : 63,
"seconds" : 0,
"lat" : 0
},
"lon" : {
"degree" : 0,
"minutes" : 0,
"direction" : 63,
"lon" : 0,
"seconds" : 0
}
},
"camera_make" : "",
"lens_min_focal_length" : 0,
"focal_plane_yres" : 0,
"image_copyright" : "",
"lens_make" : "",
"camera_model" : "",
"image_description" : "",
"lens_focal_length" : 0,
"lens_max_focal_length" : 0,
"lens_model" : "",
"image_height" : 0,
"flash_used" : 0
}
The values are purposefully emptied/zeroed to protect sensitive information.
Contribute to this repository by opening issues or directly making a PR!!