images

package
v0.0.0-...-1e0776f Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 20, 2026 License: MIT Imports: 28 Imported by: 0

Documentation

Overview

Package images provides image processing and caching services.

Index

Constants

This section is empty.

Variables

View Source
var ImagePresets = map[images.ImageType][]ImagePreset{

	images.ImageTypePoster: {
		{Name: "thumb", Width: 200, Height: 300, Quality: 100},
		{Name: "medium", Width: 400, Height: 600, Quality: 100},
		{Name: "large", Width: 600, Height: 900, Quality: 100},
		{Name: "xlarge", Width: 800, Height: 1200, Quality: 100},
	},

	images.ImageTypeFanart: {
		{Name: "thumb", Width: 320, Height: 180, Quality: 100},
		{Name: "medium", Width: 854, Height: 480, Quality: 100},
		{Name: "large", Width: 1280, Height: 720, Quality: 100},
		{Name: "xlarge", Width: 1920, Height: 1080, Quality: 100},
	},
	images.ImageTypeBackdrop: {
		{Name: "thumb", Width: 320, Height: 180, Quality: 100},
		{Name: "medium", Width: 854, Height: 480, Quality: 100},
		{Name: "large", Width: 1280, Height: 720, Quality: 100},
		{Name: "xlarge", Width: 1920, Height: 1080, Quality: 100},
	},
	images.ImageTypeExtraFanart: {
		{Name: "thumb", Width: 320, Height: 180, Quality: 100},
		{Name: "medium", Width: 854, Height: 480, Quality: 100},
		{Name: "large", Width: 1280, Height: 720, Quality: 100},
		{Name: "xlarge", Width: 1920, Height: 1080, Quality: 100},
	},

	images.ImageTypeThumb: {
		{Name: "thumb", Width: 320, Height: 180, Quality: 100},
		{Name: "medium", Width: 640, Height: 360, Quality: 100},
		{Name: "large", Width: 854, Height: 480, Quality: 100},
	},

	images.ImageTypeLandscape: {
		{Name: "thumb", Width: 320, Height: 180, Quality: 100},
		{Name: "medium", Width: 640, Height: 360, Quality: 100},
		{Name: "large", Width: 1280, Height: 720, Quality: 100},
	},

	images.ImageTypeBanner: {
		{Name: "medium", Width: 758, Height: 140, Quality: 100},
		{Name: "large", Width: 1000, Height: 185, Quality: 100},
	},

	images.ImageTypeClearLogo: {
		{Name: "medium", Width: 400, Height: 0, Quality: 100},
		{Name: "large", Width: 800, Height: 0, Quality: 100},
	},
	images.ImageTypeLogo: {
		{Name: "medium", Width: 400, Height: 0, Quality: 100},
		{Name: "large", Width: 800, Height: 0, Quality: 100},
	},

	images.ImageTypeClearArt: {
		{Name: "medium", Width: 500, Height: 0, Quality: 100},
		{Name: "large", Width: 1000, Height: 0, Quality: 100},
	},
	images.ImageTypeCharacterArt: {
		{Name: "medium", Width: 500, Height: 0, Quality: 100},
		{Name: "large", Width: 1000, Height: 0, Quality: 100},
	},

	images.ImageTypeActor: {
		{Name: "thumb", Width: 100, Height: 150, Quality: 100},
		{Name: "medium", Width: 200, Height: 300, Quality: 100},
		{Name: "large", Width: 300, Height: 450, Quality: 100},
	},

	images.ImageTypeCover: {
		{Name: "thumb", Width: 150, Height: 150, Quality: 100},
		{Name: "medium", Width: 300, Height: 300, Quality: 100},
		{Name: "large", Width: 500, Height: 500, Quality: 100},
		{Name: "xlarge", Width: 1000, Height: 1000, Quality: 100},
	},
	images.ImageTypeFolder: {
		{Name: "thumb", Width: 150, Height: 150, Quality: 100},
		{Name: "medium", Width: 300, Height: 300, Quality: 100},
		{Name: "large", Width: 500, Height: 500, Quality: 100},
	},

	images.ImageTypeDiscArt: {
		{Name: "medium", Width: 300, Height: 300, Quality: 100},
		{Name: "large", Width: 500, Height: 500, Quality: 100},
	},
}

ImagePresets defines all size variants to pre-generate during scan This eliminates on-demand transformation overhead

Functions

func IsImageFile

func IsImageFile(filename string) bool

IsImageFile checks if a file is a supported image format

func IsSVG

func IsSVG(path string) bool

IsSVG checks if a file path or URL points to an SVG file.

Types

type CacheService

type CacheService struct {
	// contains filtered or unexported fields
}

CacheService handles copying images to cache directory and managing cached files

func NewCacheService

func NewCacheService(cacheDir string) *CacheService

NewCacheService creates a new cache service

func (*CacheService) ComputeFileHash

func (s *CacheService) ComputeFileHash(filePath string) (string, error)

ComputeFileHash computes XXH3-128 hash of a file (50x faster than SHA256, zero collision risk) This is a utility function in case we need to recompute hashes

func (*CacheService) CopyToCache

func (s *CacheService) CopyToCache(sourcePath, fileHash string) (string, error)

CopyToCache copies an image file to the cache directory using its hash as the filename Returns the cache path relative to the cache directory Format: {first2chars}/{next2chars}/{hash}_original.{ext} Example: 04/c3/04c38ff5542c1d931ab7d0830d314a2a03acf1c11b01d52e9deec7a31f0bdcf5_original.jpg

func (*CacheService) DeleteCachedFile

func (s *CacheService) DeleteCachedFile(relativePath string) error

DeleteCachedFile removes a file from the cache

func (*CacheService) EnsureCacheDir

func (s *CacheService) EnsureCacheDir() error

EnsureCacheDir creates the cache directory if it doesn't exist

func (*CacheService) FileExists

func (s *CacheService) FileExists(relativePath string) bool

FileExists checks if a cached file exists

func (*CacheService) GetCacheSize

func (s *CacheService) GetCacheSize() (int64, error)

GetCacheSize returns the total size of all cached files in bytes

func (*CacheService) GetCachedPath

func (s *CacheService) GetCachedPath(relativePath string) string

GetCachedPath returns the full path to a cached file given its relative cache path

func (*CacheService) GetPresetPath

func (s *CacheService) GetPresetPath(hash, imageType, preset string) (string, error)

GetPresetPath returns the full path to a preset image file. Format: {cacheDir}/{first2}/{next2}/{hash}_{imageType}_{preset}.webp Returns empty string and error if hash is too short.

func (*CacheService) ListCachedFiles

func (s *CacheService) ListCachedFiles() ([]string, error)

ListCachedFiles returns all files in the cache directory

type Downloader

type Downloader struct {
	// contains filtered or unexported fields
}

Downloader handles downloading remote images to local cache.

func NewDownloader

func NewDownloader(cfg DownloaderConfig) *Downloader

NewDownloader creates a new image downloader.

func (*Downloader) Download

func (d *Downloader) Download(ctx context.Context, url string) (string, error)

Download fetches a remote image and stores it locally. Returns the local file path.

type DownloaderConfig

type DownloaderConfig struct {
	// CacheDir is the directory to store downloaded images.
	CacheDir string

	// Timeout for HTTP requests.
	Timeout time.Duration

	// RateLimit is requests per second (0 = unlimited).
	RateLimit float64

	// RateBurst is the maximum burst size for the rate limiter.
	// Defaults to 10 if not set.
	RateBurst int

	// Logger for structured logging.
	Logger *slog.Logger
}

DownloaderConfig configures the image downloader.

type EmbeddedExtractor

type EmbeddedExtractor struct{}

EmbeddedExtractor handles extraction of artwork embedded in audio files (ID3/APIC tags)

func NewEmbeddedExtractor

func NewEmbeddedExtractor() *EmbeddedExtractor

NewEmbeddedExtractor creates a new embedded artwork extractor

func (*EmbeddedExtractor) ExtractAlbumArtFromFirstTrack

func (e *EmbeddedExtractor) ExtractAlbumArtFromFirstTrack(albumDir string) (*ImageInfo, error)

ExtractAlbumArtFromFirstTrack extracts album artwork from the first audio file in a directory This is used as a fallback when no folder.jpg/cover.jpg is found

func (*EmbeddedExtractor) ExtractAlbumArtFromTrack

func (e *EmbeddedExtractor) ExtractAlbumArtFromTrack(trackFile string) (*ImageInfo, error)

ExtractAlbumArtFromTrack extracts album artwork from a specific audio file This is used for track-level image extraction

func (*EmbeddedExtractor) ExtractArtistArtFromFirstTrack

func (e *EmbeddedExtractor) ExtractArtistArtFromFirstTrack(artistDir string) (*ImageInfo, error)

ExtractArtistArtFromFirstTrack extracts artist artwork from the first audio file in any album This is used as a fallback when no artist-level folder.jpg is found

func (*EmbeddedExtractor) ExtractFromAudioFile

func (e *EmbeddedExtractor) ExtractFromAudioFile(audioFilePath string, imageType images.ImageType) (*ImageInfo, error)

ExtractFromAudioFile extracts embedded artwork from an audio file's ID3 tags Returns nil if no embedded artwork is found

type ExtractedImages

type ExtractedImages struct {
	// All discovered images
	Images []ImageInfo
}

ExtractedImages contains all images found for a media item

type Extractor

type Extractor struct {
	// contains filtered or unexported fields
}

Extractor discovers and catalogs image files for media items

func NewExtractor

func NewExtractor() *Extractor

NewExtractor creates a new image extractor

func (*Extractor) ExtractMovieImages

func (e *Extractor) ExtractMovieImages(movieFilePath string) (*ExtractedImages, error)

ExtractMovieImages discovers all images for a movie file Supports standard media server naming conventions: - poster.jpg, movie-poster.jpg, folder.jpg (poster) - fanart.jpg, movie-fanart.jpg (fanart) - clearlogo.png (clearlogo) - landscape.jpg (landscape) - actor/*.jpg (actors) - extrathumbs/*.jpg (extra backdrops)

func (*Extractor) ExtractMusicAlbumImages

func (e *Extractor) ExtractMusicAlbumImages(albumDir string) (*ExtractedImages, error)

ExtractMusicAlbumImages discovers album-level images Priority: Filesystem images first, then embedded artwork as fallback

func (*Extractor) ExtractMusicArtistImages

func (e *Extractor) ExtractMusicArtistImages(artistDir string) (*ExtractedImages, error)

ExtractMusicArtistImages discovers artist-level images Priority: Filesystem images first, then embedded artwork as fallback

func (*Extractor) ExtractMusicTrackImages

func (e *Extractor) ExtractMusicTrackImages(trackFile string) (*ExtractedImages, error)

ExtractMusicTrackImages extracts embedded album art from a specific music track file

func (*Extractor) ExtractTVEpisodeImages

func (e *Extractor) ExtractTVEpisodeImages(episodeFilePath string) (*ExtractedImages, error)

ExtractTVEpisodeImages discovers episode-level images (thumbnails)

func (*Extractor) ExtractTVSeasonImages

func (e *Extractor) ExtractTVSeasonImages(showDir string, seasonNumber int) (*ExtractedImages, error)

ExtractTVSeasonImages discovers season-level images

func (*Extractor) ExtractTVShowImages

func (e *Extractor) ExtractTVShowImages(showDir string) (*ExtractedImages, error)

ExtractTVShowImages discovers show-level images

type GenerateOptions

type GenerateOptions struct {
	// Duration of the video in seconds (used to calculate timestamp)
	Duration int
	// TimestampPercent is the percentage into the video to extract (default 10%)
	TimestampPercent float64
}

GenerateOptions configures thumbnail generation.

type GenerateResult

type GenerateResult struct {
	// FileHash is the hash of the extracted frame (used as cache key)
	FileHash string
	// Presets maps preset names to their cache paths
	Presets map[string]string
}

GenerateResult contains the result of thumbnail generation.

type ImageInfo

type ImageInfo struct {
	// File path (absolute or relative to media file)
	Path string

	// Image type (poster, fanart, etc.)
	Type images.ImageType

	// Priority (0 = highest) for multiple images of same type
	Priority int

	// Language code (if applicable, e.g., "en", "fr")
	Language *string

	// Metadata (populated after extraction)
	Width         *int
	Height        *int
	FileSizeBytes *int64
	MimeType      *string
	FileHash      *string
}

ImageInfo represents extracted image information

type ImagePreset

type ImagePreset struct {
	Name    string // e.g., "thumb", "medium", "large"
	Width   int
	Height  int
	Quality int
}

ImagePreset defines a specific size/quality variant to generate

type MetadataExtractor

type MetadataExtractor struct{}

MetadataExtractor extracts metadata from image files

func NewMetadataExtractor

func NewMetadataExtractor() *MetadataExtractor

NewMetadataExtractor creates a new metadata extractor

func (*MetadataExtractor) ExtractMetadata

func (e *MetadataExtractor) ExtractMetadata(imagePath string) (*ImageInfo, error)

ExtractMetadata extracts complete metadata from an image file

type SVGRasterizer

type SVGRasterizer struct {
	// DefaultDPI is the resolution used for rasterization.
	// Higher values produce larger, more detailed images.
	DefaultDPI float64
}

SVGRasterizer converts SVG files to raster images.

func NewSVGRasterizer

func NewSVGRasterizer() *SVGRasterizer

NewSVGRasterizer creates a new SVG rasterizer with default settings.

func (*SVGRasterizer) Rasterize

func (r *SVGRasterizer) Rasterize(reader io.Reader) (*image.RGBA, error)

Rasterize converts SVG data from a reader to an RGBA image.

func (*SVGRasterizer) RasterizeBytes

func (r *SVGRasterizer) RasterizeBytes(data []byte) (*image.RGBA, error)

RasterizeBytes converts SVG bytes to an RGBA image.

func (*SVGRasterizer) RasterizeFile

func (r *SVGRasterizer) RasterizeFile(svgPath string) (*image.RGBA, error)

RasterizeFile converts an SVG file to an RGBA image.

func (*SVGRasterizer) RasterizeWithSize

func (r *SVGRasterizer) RasterizeWithSize(reader io.Reader, maxWidth, maxHeight int) (*image.RGBA, error)

RasterizeWithSize converts SVG data to an RGBA image with a target size. The image is scaled to fit within maxWidth x maxHeight while preserving aspect ratio.

type TransformOptions

type TransformOptions struct {
	Width   int
	Height  int
	Quality int // 1-100 for WebP quality
}

TransformOptions contains parameters for image transformation All images are converted to WebP format

func ParseTransformOptions

func ParseTransformOptions(width, height, quality string) (TransformOptions, error)

ParseTransformOptions parses transform options from query parameters All images are converted to WebP format

type Transformer

type Transformer struct {
	// contains filtered or unexported fields
}

Transformer handles image transformations (resizing, format conversion)

func NewTransformer

func NewTransformer(cacheService *CacheService) *Transformer

NewTransformer creates a new image transformer

func (*Transformer) Transform

func (t *Transformer) Transform(sourcePath, fileHash string, opts TransformOptions) (string, error)

Transform resizes and/or converts an image format Returns the path to the transformed image (cached)

func (*Transformer) TransformAllPresets

func (t *Transformer) TransformAllPresets(sourcePath, fileHash string, imageType images.ImageType) (map[string]string, error)

TransformAllPresets generates all preset sizes for a given image type Returns a map of preset names to cache paths

type VideoThumbnailService

type VideoThumbnailService struct {
	// contains filtered or unexported fields
}

VideoThumbnailService extracts thumbnails from video files and stores them in the image cache with all preset sizes generated.

func NewVideoThumbnailService

func NewVideoThumbnailService(
	thumbClient *thumbnail.Client,
	cacheService *CacheService,
	transformer *Transformer,
	tempDir string,
) *VideoThumbnailService

NewVideoThumbnailService creates a new video thumbnail service.

func (*VideoThumbnailService) Generate

func (s *VideoThumbnailService) Generate(
	ctx context.Context,
	videoPath string,
	fileHash string,
	opts GenerateOptions,
) (*GenerateResult, error)

Generate extracts a thumbnail from a video and generates all preset sizes. Returns nil if thumbnails already exist in cache. The fileHash parameter is used as the cache key for deduplication.

func (*VideoThumbnailService) GetThumbnailPath

func (s *VideoThumbnailService) GetThumbnailPath(fileHash, preset string) (string, error)

GetThumbnailPath returns the cache path for a specific preset. Preset names are: "thumb", "medium", "large"

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL