Lust is a static image server designed to automatically convert uploaded image to several formats and preset sizes

Overview

Lust Logo

What is Lust?

Lust is a static image server designed to automatically convert uploaded image to several formats and preset sizes with scaling in mind.

Lust stores images via any of given database backends:

  • Redis / KeyDB
  • Cassandra / ScyllaDB
  • PostgreSQL
  • MySQL / MariaDB
  • Sqlite (file / temp file only)

Getting started

Installation

Building from Source

To building from source, just clone this repo via git clone https://github.com/chillfish8/lust.git and then run cargo build --release.

Docker Images

Lust has a set of pre-built, optimised docker images ready to go, they just require having a config.json attached to them and away you go.

Example Dockerfile:

FROM chillfish8/lust:latest

ADD ./config.json /etc/lust/config.json

You can run the image via docker run, you may wish to expose your set ports etc...

After Installation

See the getting started page for more information after installation.

Caching

Lust makes use of a Least Recently Used in-memory cache which can be adjusted for your needs via the cache_size key in the configuration file. The larger the number the more images it will cache at once and vice versa. NOTE: With bigger images this can create much higher RAM usage

Scaling

Lust's ability to scale is purely down to the backend you use, something like SQLite will obviously suffer at any sort of scale and is meant only really for development purposes. Personally I recommend PostgreSQL (leading to vertical scaling storage) or Scylla (Horizontally scaling storage) depending on your needs. If you want a very small amount of cached images then Postgres will out perform Scylla considerably at random reads however, Scylla is far more suites to large scaling and distributed system as well as large amounts of writes.

Performance of each database generally doesn't matter too much due to the processing time of each image being more than the IO latency when adding images and the cache supporting reads, that being said if you have a lot of random inconsistent reads PostgreSQL will likely be the best, or if you want large distributed scaling Scylla will allow you to scale horizontally.

If you want the best of both worlds I would recommend looking at KeyDB (Redis) with disk persistence, when setup correctly this can be an incredibly powerful setup.

Formats

Lust supports any of the following formats:

  • Png
  • JPEG
  • GIF
  • Webp

Any uploaded images will be given a unique uuid and be re-encoded into all the other enabled formats in all presets. This is especially useful when you want to serve several variants of the same image with different formats.

Presets

The server can take several sizing presets which can be targeted via the size query parameter when getting an image. These presets will mean every image at upload time will be resized to fit the width and height bounds using the nearest approximation.

Regardless of presets an original image is always stored and can be accessed via the size=original query. The default preset when served without a sized parameter can be set in the configuration file via default_serving_preset key.

Webp Optimisation

Lust supports automatic webp encoding, by default it encodes with lossless compression but this can be changed via the webp_quality key in the configuration file and should be a float from 0.0 to 100.0 with the quality of the image changing respectively.

Base64 Support

Lust will serve given images / gifs as Base64 data the encode query parameter (true/false) this will return a JSON response unlike the tradition raw response.

Data Efficiency

Lust's data storage efficiency is roughly the same as storing on a plain file system outside of any system the database backend employs when storing the data.

For example lets upload an image:

Medium image

This image is about 91KB in size as a single image, If we upload this and convert to the 3 base image formats with some presets:

{
  'data': {
    'file_id': 'ccbe2207-8629-4938-9da9-3f75706f9b4e',
    'formats': {
      'large': {     // Resized to 128px x 128px
        'jpeg': 3460,
        'png': 5292,
        'webp': 3006
      },
      'medium': {   // Resized to 64px x 64px
        'jpeg': 1543, 
        'png': 1738, 
        'webp': 1022
      },
      'original': {   
        'jpeg': 42846,
        'png': 103672, 
        'webp': 53982
      },
      'small': {    // Resized to 32px x 32px
        'jpeg': 912, 
        'png': 629, 
        'webp': 354
      }
  },
  'status': 200
}

We can see with the original size totals around 200KB which is is fairly reasonable with zero compression PNG encoding and lossless webp formats.

Comments
  • Optimise WebP encoding via custom encoder setup.

    Optimise WebP encoding via custom encoder setup.

    This PR adds the use of a custom WebP encoder which has an adjustable WebPConfig, this allows finer grain control over the WebP format encoding, e.g. method, quality and multi-threading support.

    This change is backward compatible with existing setups.

    enhancement backend 
    opened by ChillFish8 0
  • [ 🌠 Feat ] Dynamically load extensions

    [ 🌠 Feat ] Dynamically load extensions

    Currently, Lust is shipped as one big binary with some 500+ dependencies, this is rather large and leads to a lot of dependencies that most people using Lust for will never use if they only use one storage backend.

    A solution is to dynamically load backends from DLLs, this would allow a user to build/download their given backend(s) and load them from the main server rather than having to have all the other backends shipped to them.

    This would also allow a more pluggable experience for developing extensions etc...

    enhancement breaking change backend 
    opened by ChillFish8 0
  • CQL performance issues

    CQL performance issues

    Currently, Lust supports Cassandra via its scylla DB driver, while this system works logically it is currently prone to timeouts depending on the data and setup. This might be an issue with the testing database or more likely my less than perfect CQL knowledge leading to in-efficient queries.

    bug help wanted backend 
    opened by ChillFish8 0
  • [ 🐛 Bug ] Lust returns 500 for non-supported file formats and encoding but should return 400 or 422

    [ 🐛 Bug ] Lust returns 500 for non-supported file formats and encoding but should return 400 or 422

    Lust is currently returning a 5xx error when image formats are unknown and cannot be guessed, but also if it's unsupported. We should add a correct status code relating to this rather than an error.

    bug 
    opened by ChillFish8 0
  • [ 🌠 Feat ] Prometheus metrics support

    [ 🌠 Feat ] Prometheus metrics support

    At the moment the server has no real way of providing metrics to the user which may be an issue for some who want monitoring, or at least is a large inconvenience to do.

    A Prometheus endpoint would allow things like Grafana dashboards to make life much easier to produce monitoring for.

    enhancement help wanted 
    opened by ChillFish8 2
Releases(2.1.0)
  • 2.1.0(Apr 3, 2022)

    Version 2.1.0

    This version adds some more in-depth timing metrics around the image upload system, and also adds concurrent uploads to the primary upload endpoint.

    Source code(tar.gz)
    Source code(zip)
  • 2.0.0(Mar 31, 2022)

    Version 2.0

    Lust 2 is out! After several months of mostly just bug fixes and small bits of maintenance, I have completely reworked the system and it's better than ever!

    The Highlights ✨

    • High-performance Scylla DB backend
    • S3 compatible blob storage support
    • 100% documented API powered by Poem and is fully in line with the generated spec.
    • More adaptable caching
    • More customisations
    • Faster!

    What's changed ❤️

    New config file

    The config system has been completely reworked to create a more readable setup for developers and allows for more fine-tuning of how buckets are served and how the general global handler behaves. You can see an example of some of the new config here which I think is a massive improvement overall.

    Storage Backends

    Backends have been completely reworked and the SQL and Redis backends have been removed. This decision was made after running lust for several months and largely coming to the conclusion that they struggle to serve the image blobs as well as their wide column DB and blob store counterparts, it was also a lot of work maintaining them so, for now, I've made the decision to remove them. That being said adding a new backend is just the case of adding a new backend that implements the StorageBackend trait in the backends folder of the repo.

    S3 compatible blob storage added! This probably should have been added sooner but here it is anyway. This allows you to turn any blob store (s3 compatible) into your own CDN system potentially, isn't that cool!?

    Scylla DB backend: To be precise this does include Cassandra in its support bubble however, this is optimised for Scylla and even on a small machine 6 core machine I was able to serve around 12,000 images a second without caching, which I believe you could push even more with enough tuning.

    Caching

    Caching has been updated so now you can set both a local bucket cache and also a global cache allowing you to fine-tune what proportion of things get cached across buckets but also makes it simple if you just want a quick setup.

    You can also now limit by memory usage! This allows you to set a limit in Mega bytes and the system will aim to cache up to that many images' worth of data. Note: This is an approximation system, please do not use it as a hard cap as the system does not control how much the allocator may return rather than the minimum amount of bytes required

    OpenAPI Documentation

    I've moved Lust's backend over to poem-openapi (my beloved) which allows us to produce full documented OpenAPI schemas and intern documentation which you can find being served at the /ui endpoint of the server. This should be your main reference as it will be kept in line with each version change.

    Better Performance

    A lot's changed between the time I first started Lust and now, and after 12 months of additional learning around the performance areas of Rust I've been able to massively increase Lust's throughput by around 10x in some tests, although your milage will vary depending on your setup, so I advise you do your own benchmarking to see 😄

    Unit Tests

    There are now unit tests, this should hopefully help maintain the code quality but also prevent any accidental breaking changes from being brought in.

    Small but still noteworthy changes:

    • Webp encoders will no longer panic, this will be a welcome change to most people who have experienced Lust panicking with webp encoding if libwebp returns a bad code. (Man I hate C)

    • New logo 🎉

    • Resizing now maintains aspect ratio

    • Selectable resizing filter algorithms, the default is still the nearest neighbour (same as lust v1) so this shouldn't cause any unexpected difference in images produced.

    • Entity listing endpoints are gone - This was a massive pain to maintain compatibility with backends and also was a massive performance bottleneck.

    • Each sizing preset is tagged with an ID which intern allows for deterministic storage paths. Useful now that file listing endpoints no longer exist.

    Source code(tar.gz)
    Source code(zip)
  • 1.3.6(Dec 31, 2021)

  • 1.3.5(Dec 31, 2021)

  • 1.3.4(Dec 31, 2021)

  • 1.3.3(Sep 26, 2021)

    What's fixed?

    • Panicking when no compression value is given via the config but webp set to lossless mode.

    Other changes

    • Reformatted code base following the new rustfmt config.
    Source code(tar.gz)
    Source code(zip)
  • 1.3.1(Jul 4, 2021)

    Lust 1.3.1 Released!

    This version bump fixes the WebP in-backward compatible changes and fixes unreachable panics in WebP lib by converting un-supported types.

    Source code(tar.gz)
    Source code(zip)
  • 1.3.0(Jul 4, 2021)

    Lust 1.3.0 Released!

    This version adds the ability to see how long exactly each format takes to convert and allows parallel execution of format conversion, this should see significant performance improvements for multi-format conversion, if you have a single format setup this wont make any difference really.

    Source code(tar.gz)
    Source code(zip)
  • 1.2.0(Jul 3, 2021)

    Lust 1.2.0 Is released!

    This update brings some heavy optimizations to allow servers to make use of all their cores when encoding WebP, during testing, it was found that libwebp using its default single-threaded system was up to 10x slower than the png and JPEG encoders sometimes taking upwards of 800ms to encode a single 200KB image.

    What's new?

    This update brings a custom encoder that allows you to customize the WebPencoding for better finer grain control and most notably offers multi-threaded encoding which offers significant performance increases on lower frequency but larger core count servers.

    New WebP config options:

    • webp_quality Between 0 and 100, For lossy, 0 gives the smallest size and 100 the largest. If using lossless this does nothing (same as before).
    • webp_compression with lossless encoding is the ratio of compression to speed. If using lossy encoding this does nothing - (float: 0.0 - 100.0 inclusive)
    • webp_method The quality/speed trade-off (0=fast, 6=slower-better)
    • webp_threading A bool signaling if multi-threading encoding should be attempted (false=disabled, true=enabled)
    Source code(tar.gz)
    Source code(zip)
  • 1.1.0(Jun 5, 2021)

  • 1.0.0(Jun 3, 2021)

  • 0.1.0(May 28, 2021)

Owner
Harrison Burt
17yr/o Programmer in Python, Rust, Js and Go lang.
Harrison Burt
Takes a folder of images (as a palette), and an image, and figures out how to tile the palette to resemble the image!

Takes a folder of images (as a palette), and an image, and figures out how to tile the palette to resemble the image!

Jacob 258 Dec 30, 2022
Rust Lean Image Viewer - Fast and configurable image viewer inspired by JPEGView by David Kleiner

Rust Lean Image Viewer - Fast and configurable image viewer inspired by JPEGView by David Kleiner

3top1a 4 Apr 9, 2022
Convert and save photomode screenshots from Red Dead Redemption 2 to JPEG format.

RDR2 Screenshot converter Convert and save photomode screenshots from Red Dead Redemption 2 to JPEG format. QuickStart Just download the executable fi

Timofey Gelazoniya 12 Sep 29, 2022
Slideo: This tool uses OpenCV to automatically synchronize slides with videos that show these slides.

This tool matches video frames against PDF pages by using computer vision. It also ships a web app in which you can click on a PDF page to play the video from the first frame showing the page. Its primary use-case is to quickly play a recorded lecture from a given slide.

Henning Dieterichs 78 Oct 7, 2022
Convert your ascii diagram scribbles into happy little SVG

Svgbob Svgbob can create a nice graphical representation of your text diagrams. Svgbob provides a cli which takes text as an input and creates an svg

Jovansonlee Cesar 3.4k Dec 25, 2022
convert markdown headers to graph

Rust Markdown to graph This program converts a Markdown file into a graph. For now, it creates .dot file which graphviz uses to build graph. It transl

null 3 Sep 26, 2021
Convert Sketchbook Tiff Files to Open Raster Images

SketchbookTiffConverter Convert Sketchbook Tiff Files to Open Raster Images and retain layer information. This is a command line program that will con

Phil Spindler 3 Nov 2, 2021
Convert UFO .glif files to SVG, whether they're part of a font or not

Convert UFO glyph files (.glif) to SVG There exists already an svg2glif, but for some reason not the opposite operation. My MFEKglif editor treats .gl

Modular Font Editor K 3 Apr 26, 2022
Signed distance field font and image command line tool based on OpenCL.

SDFTool Signed distance field font and image command line tool based on OpenCL. Build Windows Run cargo build --release in Visual Studio developer x64

弦语蝶梦 7 Oct 16, 2022
A simple command-line utility (and Rust crate!) for converting from a conventional image file (e.g. a PNG file) into a pixel-art version constructed with emoji

EmojiPix This is a simple command-line utility (and Rust crate!) for converting from a conventional image file (e.g. a PNG file) into a pixel-art vers

Michael Milton 22 Dec 6, 2022
Rust library to get image size and format without loading/decoding

imageinfo-rs Rust library to get image size and format without loading/decoding. The imageinfo don't get image format by file ext name, but infer by f

xiaozhuai, Weihang Ding 47 Dec 30, 2022
Simple image metadata scrubber. Will remove EXIF, XMP and IPTC metadata.

Simple image metadata scrubber. Will remove EXIF, XMP and IPTC metadata.

Jae Lo Presti 12 Nov 29, 2022
Image processing proxy and API, created to allow faster media delivery for the Holaplex storefront.

Description imgopt is an image processing proxy with a very simple API, created to download and dynamically scaledown, convert, and cache different me

Holaplex 5 Nov 3, 2022
Fastest image quadtree stylization implementation to date, capable of hundreds of fps and avoiding ugly non-squares.

Quadim Fastest image quadtree stylization implementation to date, capable of hundreds of fps and avoiding ugly non-squares. 简体中文 如果你是从B站来的…… “Listen t

K--A______ 13 May 11, 2023
Image processing operations

imageproc An image processing library, based on the image library. There may initially be overlap between the functions in this library and those in i

image-rs 512 Jan 8, 2023
Image Compression Algorithm

Image Compression Algorithm ?? A new lossless image compression algorithm. In the newest version the algorithm performs rather good, but manages to su

Hannes 31 May 10, 2022
Artsy pixel image to vector graphics converter

inkdrop inkdrop is an artsy bitmap to vector converter. Command line interface The CLI binary is called inkdrop-cli and reads almost any image bitmap

Matthias Vogelgesang 62 Dec 26, 2022
Automated image compression for efficiently distributing images on the web.

Imager Apparently this project made it into the GitHub Archive Program. About Imager is a tool for automated image compression, and can competitively

Imager IO 487 Dec 25, 2022
Open Graphic Image Writer

Open Graphic Image Writer Documentation You can generate Open Graphic Image dynamically. A CSS-like API. You can generate image by using template imag

keiya sasaki 46 Dec 15, 2022