{"id":26116996,"url":"https://github.com/elchemista/fast_thumbnail","last_synced_at":"2026-06-10T09:31:34.517Z","repository":{"id":280859552,"uuid":"943418287","full_name":"elchemista/fast_thumbnail","owner":"elchemista","description":"Simple and fast Elixir library for creating thumbnail, perfect to use with liveview. Using rust under the hood.","archived":false,"fork":false,"pushed_at":"2025-05-01T03:44:23.000Z","size":5922,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-10-04T16:22:24.291Z","etag":null,"topics":["elixir","image","phoenix-framework","rustler","thumbnail"],"latest_commit_sha":null,"homepage":"https://hex.pm/packages/fast_thumbnail","language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/elchemista.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2025-03-05T17:15:05.000Z","updated_at":"2025-06-24T20:23:51.000Z","dependencies_parsed_at":"2025-03-05T18:31:02.593Z","dependency_job_id":"4e4061db-fc12-4ddc-b55f-72417ee0a7a2","html_url":"https://github.com/elchemista/fast_thumbnail","commit_stats":null,"previous_names":["elchemista/fast_thumbnail"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/elchemista/fast_thumbnail","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elchemista%2Ffast_thumbnail","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elchemista%2Ffast_thumbnail/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elchemista%2Ffast_thumbnail/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elchemista%2Ffast_thumbnail/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/elchemista","download_url":"https://codeload.github.com/elchemista/fast_thumbnail/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elchemista%2Ffast_thumbnail/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34146871,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-10T02:00:07.152Z","response_time":89,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["elixir","image","phoenix-framework","rustler","thumbnail"],"created_at":"2025-03-10T10:53:31.707Z","updated_at":"2026-06-10T09:31:34.484Z","avatar_url":"https://github.com/elchemista.png","language":"Elixir","funding_links":[],"categories":[],"sub_categories":[],"readme":"# FastThumbnail\n\nFastThumbnail is an Elixir library that uses a [Rust NIF](https://hexdocs.pm/rustler) under the hood to perform **fast, SIMD-optimized** image resizing. It leverages the excellent [fast_image_resize](https://github.com/Cykooz/fast_image_resize) crate to crop and resize images efficiently.\n\n### Why?\n\n- **Fast**: SIMD-accelerated resizing is blazingly fast.\n\nI just wanted stupidly simple image resizing that do just one thing: crop and resize an image to a given width.\nThere is already good libraries for this [image](https://github.com/elixir-image/image), but they all seem to be too complex for my needs. Also I like small dependencies.\n\n## Features\n\n- **Center-crop** images to a square, then resize (all in a single pass).\n- **Multiple output modes**:  \n  - Overwrite the original file with the same format (JPEG stays JPEG, PNG stays PNG, etc.).  \n  - Save a **new** file in WebP format (`\"path.webp\"`).  \n  - Return the resized image as a **base64-encoded** WebP string (no file writing).\n- Backed by **SIMD** operations for maximum performance, thanks to the [fast_image_resize](https://github.com/Cykooz/fast_image_resize) library.\n\n## Installation\n\nAdd `fast_thumbnail` to your dependencies in `mix.exs`:\n\n```elixir\ndef deps do\n  [\n    {:fast_thumbnail, \"~\u003e 0.1.5\"}\n  ]\nend\n```\n\nThen run:\n\n```bash\nmix deps.get\nmix compile\n```\n\n## Usage\n\n```elixir\n# 1) Overwrite file in its original format (JPEG→JPEG, PNG→PNG, etc.)\niex\u003e FastThumbnail.create(\"images/photo.jpg\", 300, :overwrite)\n{:ok, \"images/photo.jpg\"}\n\n# 2) Create a new file in WebP format:\niex\u003e FastThumbnail.create(\"images/photo.jpg\", 300, :webp)\n{:ok, \"images/photo.jpg.webp\"}\n\n# 3) Return a base64-encoded WebP (no file writing):\niex\u003e FastThumbnail.create(\"images/photo.jpg\", 300, :base64)\n{:ok, \"data:image/webp;base64,UklGRrwAAABXRUJQVlA4T...\"}\n\n```\n\n## Example Liveview\n\nBelow is a **LiveView**:\n\n```elixir\ndefmodule MyAppWeb.UploadLive do\n  use MyAppWeb, :live_view\n\n  @impl true\n  def mount(_params, _session, socket) do\n    socket =\n      socket\n      # Limit to .jpg, .jpeg for this example\n      |\u003e allow_upload(:avatar, accept: ~w(.jpg .jpeg), max_entries: 1)\n\n    {:ok, socket}\n  end\n\n  @impl true\n  def handle_event(\"validate\", _params, socket) do\n    {:noreply, socket}\n  end\n\n  def handle_event(\"cancel-upload\", %{\"ref\" =\u003e ref}, socket) do\n    {:noreply, cancel_upload(socket, :avatar, ref)}\n  end\n\n  def handle_event(\"save\", _params, socket) do\n    uploaded_files =\n      consume_uploaded_entries(socket, entry, fn %{path: tmp_path} -\u003e\n          upload_to_s3(tmp_path, entry.client_name)\n\n          # handle errors here\n      end)\n\n    {:noreply, update(socket, :uploaded_files, \u0026(\u00261 ++ uploaded_files))}\n  end\n\n  defp upload_to_s3(file_path, name_for_s3) do\n    with {:ok, thumb_base64} \u003c- FastThumbnail.create(file_path, 200, :base64) do\n\n    access_key = System.get_env(\"AWS_ACCESS_KEY\")\n    secret_key = System.get_env(\"AWS_SECRET_KEY\")\n    region     = System.get_env(\"AWS_REGION\")\n    bucket     = System.get_env(\"AWS_BUCKET_NAME\") || \"my-bucket\"\n    client     = AWS.Client.create(access_key, secret_key, region) \n\n    folder = \"thumbnails\"\n    key = \"#{folder}/#{name_for_s3}\"\n\n    # S3 `put_object` params\n    put_params = %{\n      \"Body\" =\u003e thumb_base64,\n      \"ContentType\" =\u003e \"image/webp\",\n      \"ContentEncoding\" =\u003e \"base64\",\n      \"Metadata\" =\u003e %{\"OriginalName\" =\u003e name_for_s3}\n    }\n\n    AWS.S3.put_object(client, bucket, key, put_params)\n  end\nend\n```\n\nWith this, you have a **LiveView** flow that:\n\n1. Accepts user uploads,  \n2. Creates a **resized** webp thumbnail,  \n3. Uploads it to S3,  \n4. Returns the final S3 URL or a local URL.\n\nUnder the hood, the Elixir function calls a Rust NIF which performs a **single-pass** crop+resize operation using [fast_image_resize](https://crates.io/crates/fast_image_resize). The resized bytes are either:\n\n- Written back to disk in the same or different format, **or**\n- Returned to Elixir as a base64 string.\n\n## Credits\n\n- **[fast_image_resize](https://github.com/Cykooz/fast_image_resize)** – the Rust crate that powers the SIMD-accelerated resizing. See also:\n  - [Crates.io](https://crates.io/crates/fast_image_resize)\n  - [Docs.rs](https://docs.rs/fast_image_resize)\n- **[Thumbp](https://github.com/ryochin/thumbp)** - Another excellent Elixir library that provides a fast and efficient way to generate thumbnails from images.\n- **[rustler](https://github.com/rusterlium/rustler)** – used for building the native Rust code as an Elixir NIF.\n\n## License\n\nFastThumbnail is licensed under the [Apache License, Version 2.0](LICENSE).\n\n*fast_image_resize* is distributed under its own license. Please refer to its repository for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Felchemista%2Ffast_thumbnail","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Felchemista%2Ffast_thumbnail","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Felchemista%2Ffast_thumbnail/lists"}