All Projects → usercode → ImageWizard

usercode / ImageWizard

Licence: MIT license
Image processing webservice based on ASP.NET Core and ImageSharp / SkiaSharp / SvgNet / DocNET

Programming Languages

C#
18002 projects
HTML
75241 projects
Dockerfile
14818 projects

Projects that are alternatives of or similar to ImageWizard

imtool
🖼️ Client-side canvas-based image manipulation library.
Stars: ✭ 38 (+52%)
Mutual labels:  image-manipulation, thumbnail-generator
color-aware-style-transfer
Reference code for the paper CAMS: Color-Aware Multi-Style Transfer.
Stars: ✭ 36 (+44%)
Mutual labels:  image-manipulation
lamba-thumbnailer
AWS S3 Video Thumbnailer with Lambda
Stars: ✭ 21 (-16%)
Mutual labels:  thumbnail-generator
gocv-playground
This repo contains various https://gocv.io/ examples
Stars: ✭ 29 (+16%)
Mutual labels:  image-manipulation
cover-thumbnailer
Generates folder thumbnails for various file browser on Linux to display music album covers, preview of pictures which are in a folder and more.
Stars: ✭ 56 (+124%)
Mutual labels:  thumbnail-generator
Fourier-and-Images
Fourier and Images
Stars: ✭ 81 (+224%)
Mutual labels:  image-manipulation
idg
Document image generator
Stars: ✭ 40 (+60%)
Mutual labels:  image-manipulation
Python Computer Vision from Scratch
This repository explores the variety of techniques commonly used to analyze and interpret images. It also describes challenging real-world applications where vision is being successfully used, both for specialized applications such as medical imaging, and for fun, consumer-level tasks such as image editing and stitching, which students can apply…
Stars: ✭ 219 (+776%)
Mutual labels:  image-manipulation
texturize
🤖🖌️ Generate photo-realistic textures based on source images. Remix, remake, mashup! Useful if you want to create variations on a theme or elaborate on an existing texture.
Stars: ✭ 495 (+1880%)
Mutual labels:  image-manipulation
hermitage
Service that provides storage, delivery and modification of your images
Stars: ✭ 33 (+32%)
Mutual labels:  image-manipulation
dagpi
Dagpi is a powerful and fast api that does image manipulation as well as serves datasets. It is fast and written in rust and python. Perfect for discord bots, social media apps, camera apps and more.
Stars: ✭ 25 (+0%)
Mutual labels:  image-manipulation
imagekit-php
PHP SDK for ImageKit.io API.
Stars: ✭ 34 (+36%)
Mutual labels:  image-manipulation
casia2groundtruth
Groundtruth images of tampering dataset CASIA 2.0
Stars: ✭ 97 (+288%)
Mutual labels:  image-manipulation
picamo
A Node JS steganography tool for the tin foil hat revolution!
Stars: ✭ 15 (-40%)
Mutual labels:  image-manipulation
rgb-editor
Tool to mass modify R, G ,B values for .png files, useful for making Minecraft Texturepacks
Stars: ✭ 15 (-40%)
Mutual labels:  image-manipulation
Image-Processing-CLI-in-Rust
CLI for image processing with histograms, binary treshold and other functions
Stars: ✭ 25 (+0%)
Mutual labels:  image-manipulation
Nova-Bot
This bot was created using discord.js v12. This bot offers you many powerful commands ranging from moderation to economy.
Stars: ✭ 37 (+48%)
Mutual labels:  image-manipulation
FotoKilof
GUI for ImageMagick
Stars: ✭ 114 (+356%)
Mutual labels:  image-manipulation
QuadTreeAndroid
Library that helps to implement the QuadTree in android, by using splitting images
Stars: ✭ 30 (+20%)
Mutual labels:  image-manipulation
BusterNet
No description or website provided.
Stars: ✭ 49 (+96%)
Mutual labels:  image-manipulation

ImageWizard

A ASP.NET Core service / middleware to resize your images on the fly as alternative for thumbor.

License: MIT NuGet Docker

Demo: imagewizard.net

Features

  • loader:
    • Http (streaming mode)
    • File (use IFileProvider)
    • YouTube (get thumbnail)
    • Gravatar
    • OpenGraph
  • caches:
    • File
    • Distributed cache
    • MongoDB
  • image filters: resize, crop, rotate,..
  • common image effects like grayscale and blur are available
  • create your custom data filter
  • pdf filters: page-to-image for documents
  • url is protected by a HMACSHA256 signature to prevent DDoS attacks
  • can handle the device pixel ratio (DPR)
  • support for cache control and ETag
  • enable range processing by http request
  • use RecyclableMemoryStream for smarter memory management (IStreamPool)
  • cleanup service

Example

https://localhost/
image/
cGiAwFYGYWx0SzO0YyCidWIfkdlUYrVgBwbm7bcTOjE/
resize(200,200)/grayscale()/jpg(90)/
fetch/
https://upload.wikimedia.org/wikipedia/commons/b/b7/Europe_topography_map.png

Description Url segment
base path "image"
signature based on HMACSHA256 "cGiAwFYGYWx0SzO0YyCidWIfkdlUYrVgBwbm7bcTOjE" or "unsafe" (if enabled)
any filters "resize(200,200)/grayscale()/jpg(90)"
loader type "fetch"
loader source https://upload.wikimedia.org/wikipedia/commons/b/b7/Europe_topography_map.png

Loader

Name Loader type Loader source NuGet
Http loader fetch absolute or relative url NuGet
File loader file relative path to file NuGet
YouTube loader youtube video id NuGet
Gravatar loader gravatar encoded email address NuGet
OpenGraph loader opengraph absolute url NuGet
Azure loader azure relative path to file NuGet
PuppeteerSharp loader screenshot absolute url NuGet

Cache

Name Description NuGet
File cache Meta and blob file path based on cache id. NuGet
Distributed cache MS SQL, Redis NuGet
MongoDB cache Use GridFS NuGet

Pipeline

Name Mime type NuGet
ImageSharp image/jpeg, image/png, image/gif, image/bmp, image/webp, image/tga NuGet
SkiaSharp image/jpeg, image/png, image/gif, image/bmp, image/webp NuGet
SvgNet image/svg+xml NuGet
DocNET application/pdf NuGet

How to use it

services.AddImageWizard();

//or

services.AddImageWizard(options => 
                       {
                           options.AllowUnsafeUrl = true;
                           options.AllowedDPR = new double[] { 1.0, 1.5, 2.0, 3.0, 4.0 };
                           options.Key = new byte[64] { .. };
                           options.UseETag = true;                                                
                           options.CacheControl.IsEnabled = true;
                           options.CacheControl.MaxAge = TimeSpan.FromDays(365);
                           options.CacheControl.MustRevalidate = false;
                           options.CacheControl.Public = true;
                           options.CacheControl.NoCache = false;
                           options.CacheControl.NoStore = false;
                           //select automatically the compatible mime type by request header
                           options.UseAcceptHeader = true;
			   options.RefreshLastAccessInterval = TimeSpan.FromMinutes(1);
			   options.FallbackHandler = (state, url, cachedData) =>
			    {
				//use the existing cached data if available?
				if (cachedData != null)
				{
				    return cachedData;
				}

				//load fallback image
				FileInfo fallbackImage = state switch
				{
				    LoaderResultState.NotFound => new FileInfo(@"notfound.jpg"),
				    LoaderResultState.Failed => new FileInfo(@"failed.jpg"),
				   _ => throw new Exception()
				};

				if (fallbackImage.Exists == false)
				{
				    return null;
				}

				//convert FileInfo to CachedData
				return fallbackImage.ToCachedData();
			    };
                       })
            //registers ImageSharp pipeline for specified mime types
           .AddImageSharp(c => c
                .WithMimeTypes(MimeTypes.WebP, MimeTypes.Jpeg, MimeTypes.Png, MimeTypes.Gif)
                .WithOptions(x =>
                            {
                                x.ImageMaxHeight = 4000;
                                x.ImageMaxWidth = 4000;
                            })
                //Adds your custom filters
                .WithFilter<BlurFilter>()
		//Executes custom action before the pipeline is started.
                .WithPreProcessing(x =>
                            {
                                x.Image.Mutate(m => m.AutoOrient());
                            })
		//Executes custom action after the pipeline is finished.
                .WithPostProcessing(x =>
                            {
			    	//blurs all images
                                x.Image.Mutate(m => m.Blur());
                              
                                //overrides target format (Jpeg to WebP)
				if (x.ImageFormat is JpegFormat)
				{
                                    x.ImageFormat = new WebPFormat() { Lossless = false };
				}
				//overrides target format (Png to WebP)
				else if (x.ImageFormat is PngFormat)
				{
                                    x.ImageFormat = new WebPFormat() { Lossless = true };
				}
				
				//overrides metadata
				x.Image.Metadata.ExifProfile = new ExifProfile();
                        	x.Image.Metadata.ExifProfile.SetValue(ExifTag.Copyright, "ImageWizard");
                            }))
           //.AddSkiaSharp()
           .AddSvgNet()
	   .AddDocNET()
           //uses file cache (relative or absolute path)
           .SetFileCache(options => options.Folder = "FileCache") 
           //or MongoDB cache
           .SetMongoDBCache(options => options.Hostname = "localhost")
           //or distributed cache
           .SetDistributedCache()
           //adds some loaders
           .AddFileLoader(options => options.Folder = "FileStorage")
           .AddHttpLoader(options => 
          	{
		   //checks every time for a new version of the original image.
		   options.RefreshMode = LoaderRefreshMode.EveryTime;

		   //sets base url for relative urls
		   options.DefaultBaseUrl = "https://mydomain";

		   //allows only relative urls 
		   //(use base url from request or DefaultBaseUrl from options)
		   options.AllowAbsoluteUrls = false;

		   //allows only specified hosts
		   options.AllowedHosts = new [] { "mydomain" };

		   //adds custom http header like apikey to prevent 
		   //that user can download the original image
		   options.SetHeader("ApiKey", "123456");
     		})
           .AddYoutubeLoader()
           .AddGravatarLoader()
	   .AddOpenGraphLoader()
           .AddAnalytics()
	    //Adds a background service which removes cached data based on defined CleanupReason.
            //The cache needs to implements ICleanupCache.
            .AddCleanupService(x =>
		    {
			//Duration between the cleanup actions. (Default: 1 day)
			x.Interval = TimeSpan.FromMinutes(1);

			//Removes cached data which are older than defined duration. 
			x.OlderThan(TimeSpan.FromMinutes(2));

			//Removes cached data which are last used since defined duration. 
			x.LastUsedSince(TimeSpan.FromMinutes(2));

			//Removes cached data which are expired (based on the loader result).
			x.Expired();
		    })
           ;
//default path: /image
app.UseImageWizard(x =>
		{
			//default path: /analytics
			x.MapAnalytics();
		});

Internal services

  • ICacheKey
  • ICacheHash
  • ICacheLock
  • IUrlSignature
  • IStreamPool

Create custom filter

  • add a public method which is marked with the filter attribute
    • at url level are the following types possible for method overloading:
      • integer ("0")
      • floating-point number ("0.0")
      • bool ("True" or "False")
      • enum (value)
      • string ('Hello')
 public class BackgroundColorFilter : ImageSharpFilter
    {
        //use dependency injection
        public BackgroundColorFilter(ILogger<BackgroundColorFilter> logger)
        {
          //...
        }
        
        [Filter]
        public void BackgroundColor(byte r, byte g, byte b)
        {
            Context.Image.Mutate(m => m.BackgroundColor(new Rgba32(r, g, b)));
        }

        [Filter]
        public void BackgroundColor(float r, float g, float b)
        {
            Context.Image.Mutate(m => m.BackgroundColor(new Rgba32(r, g, b)));
        }
    }

Register filter:

services.AddImageWizard()
	.AddImageSharp(c => c.WithFilter<BackgroundColorFilter>());

URL segments:

"/backgroundcolor(255,255,255)/"
"/backgroundcolor(1.0,1.0,1.0)/"

How to use the DPR (device pixel ratio) attribute

  • use dpr filter to set the value or enable the client hints
  • all parameter with DPR attribute will be multiplied by the DPR factor
 public class ResizeFilter : ImageSharpFilter
 {
      [Filter]
      public void Resize([DPR]int width, [DPR]int height)
      {
          Context.Image.Mutate(m => m.Resize(width, height));
      }
 }

URL segment:

"/dpr(2.0)/resize(200,100)/"             //calls resize filter with the resolution 400 x 200
or 
"/resize(200,100)/" + client hints  

Response header:

Content-DPR: 2

How to use optional parameters

  • use rather method overloading if possible
  • if all parameter have default values you can set all parameters by name

Example:

 public class TextFilter : ImageSharpFilter
 {
      [Filter]
      public void DrawText(int x = 0, int y = 0, string text = "", int size = 12, string font = "Arial")
      {
          Context.Image.Mutate(m =>
          {
              m.DrawText(
                  text,
                  new Font(SystemFonts.Find(font), size),
                  Rgba32.Black,
                  new PointF(x, y));
          });
      }
 }

URL segment:

"/drawtext(text='Hello',x=10,y=20)/"

ASP.NET Core UrlBuilder

https://www.nuget.org/packages/ImageWizard.Client/

Example:

Add settings to the appsettings.json

 "ImageWizard": {
    "BaseUrl": "https://<your-domain>/image",
    "Key": "DEMO-KEY---PLEASE-CHANGE-THIS-KEY---PLEASE-CHANGE-THIS-KEY---PLEASE-CHANGE-THIS-KEY---==",
    "Enabled": true
  }

Register settings to services

services.Configure<ImageWizardClientSettings>(Configuration.GetSection("ImageWizard"));

services.AddImageWizardClient();

//or

services.AddImageWizardClient(options => 
{
    options.BaseUrl = "https://<your-domain>/image";
    options.Key = "..";
    options.Enabled = true;
    options.UseUnsafeUrl = false;
});

Create url with fluent api

@Url
.ImageWizard()
//use HTTP loader
.Fetch("https://<your-domain>/test/picture.jpg")
//fetch local file from wwwroot folder (with fingerprint)
.FetchLocal("picture.jpg")
//or file loader
.File("test/picture.jpg")
//or azure
.Azure("image.jpg")
.AsImage()
.Resize(160,140,ResizeMode.Max)
.Blur()
.Grayscale()
.Jpg(90)
.BuildUrl()

Use dependency injection

@IImageWizardUrlBuilder UrlBuilder

<img src="@UrlBuilder.FetchLocalFile("picture.jpg").AsImage().Resize(400, 200, ResizeMode.Max).Grayscale().BuildUrl()" />

Use IUrlHelper

<img src="@Url.ImageWizard().FetchLocalFile("picture.jpg").AsImage().Resize(400, 200, ResizeMode.Max).Grayscale().BuildUrl()" />

Processing pipelines

ImageSharp

Image transformations

  • resize(size)
  • resize(width,height)
  • resize(width,height,mode)
    • mode: min, max, crop, pad, stretch
  • resize(width,height,mode,anchor)
    • anchor: center, top, bottom, left, right, topleft, topright, bottomleft, bottomright
  • crop(width,height)
    • int for absolute values, 0.0 to 1.0 for relative values
  • crop(x,y,width,height)
    • int for absolute values, 0.0 to 1.0 for relative values
  • backgroundcolor(r,g,b)
    • int (0 to 255) or float (0.0 to 1.0)
  • backgroundcolor(r,g,b,a)
    • int (0 to 255) or float (0.0 to 1.0)
  • flip(type)
    • type: horizontal, vertical
  • rotate(value)
    • value: 90, 180 or 270
  • grayscale()
  • grayscale(amount)
    • amount: 0.0 to 1.0
  • blackwhite()
  • blur()
  • invert()
  • brightness(value)
  • contrast(value)
  • autoorient()
  • drawtext(text='Hello',size=24,x=0.5,y=0.5)
    • string: raw ('Hello') or base64url (SGVsbG8)

Output formats

  • jpg()
  • jpg(quality)
  • png()
  • gif()
  • tga()
  • bmp()
  • webp()
  • webp(quality)

Special options

  • dpr(value) //set allowed device pixel ratio

SkiaSharp

Image transformations

  • resize(width,height)
  • resize(width,height,mode)
    • mode: min, max, crop, pad, stretch
  • crop(width,height)
    • 0.0 to 1.0 for relative values
  • crop(x,y,width,height)
    • 0.0 to 1.0 for relative values
  • flip(type)
    • type: horizontal, vertical
  • rotate(value)
    • value: 0.0 to 360.0
  • grayscale()
  • blur()
  • blur(radius)
  • drawtext(text='Hello',size=24,x=0.5,y=0.5)
    • string: raw ('Hello') or base64url (SGVsbG8)

Output formats

  • jpg()
  • jpg(quality)
  • png()
  • gif()
  • bmp()
  • webp()

DocNET

DocNET transformations

  • pagetoimage(pageindex)
  • pagetoimage(pageindex,width,height)
  • subpages(pageFromIndex, pageToIndex)

SvgNet

SVG transformations

  • removesize()
  • blur()
  • blur(deviation)
    • value: float
  • rotate(angle)
    • value: float

Plugin for Piranha CMS 8.0

ImageWizard.Piranha NuGet

Useful to resize imagefields.

<img src="@Url.ImageWizard().Fetch(Model.Body).Resize(900,900).Grayscale().Blur().BuildUrl()">

Docker

Docker

static:
    image: usercode/imagewizard
    container_name: imagewizard
    restart: always
    networks:
      - default      
    volumes:
      - file_cache:/data
    environment:
      - General__Key=DEMO+KEY+++PLEASE+CHANGE+THIS+KEY+++PLEASE+CHANGE+THIS+KEY+++PLEASE+CHANGE+THIS+KEY+++==
      - General__AllowUnsafeUrl=false
      - General__UseAcceptHeader=false
      - General__UseETag=true
      - General__AllowedDPR__0=1.0
      - General__AllowedDPR__1=1.5
      - General__AllowedDPR__2=2.0
      - General__AllowedDPR__3=3.0
      - General__CacheControl__IsEnabled=true
      - General__CacheControl__Public=true
      - General__CacheControl__MaxAge=60
      - General__CacheControl__MustRevalidate=false
      - General__CacheControl__NoCache=true
      - General__CacheControl__NoStore=true      
      - FileCache__Folder=/data
      - HttpLoader__DefaultBaseUrl=https://domain.tld
      - HttpLoader__AllowAbsoluteUrls=false
      - HttpLoader__AllowedHosts__0=domain.tld
      - HttpLoader__Headers__0__Name=ApiKey
      - HttpLoader__Headers__0__Value=123      
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].