A community based topic aggregation platform built on atproto
1package imageproxy
2
3// FitMode defines how an image should be fitted to the target dimensions.
4type FitMode string
5
6const (
7 // FitCover scales the image to cover the target dimensions, cropping if necessary.
8 FitCover FitMode = "cover"
9 // FitContain scales the image to fit within the target dimensions, preserving aspect ratio.
10 FitContain FitMode = "contain"
11)
12
13// String returns the string representation of the FitMode.
14func (f FitMode) String() string {
15 return string(f)
16}
17
18// Preset defines the configuration for an image transformation preset.
19type Preset struct {
20 Name string
21 Width int
22 Height int
23 Fit FitMode
24 Quality int
25}
26
27// Validate checks that the preset has valid configuration values.
28// Returns nil if valid, or an error describing what is wrong.
29func (p Preset) Validate() error {
30 if p.Name == "" {
31 return ErrInvalidPreset
32 }
33 if p.Width <= 0 {
34 return ErrInvalidPreset
35 }
36 // Height can be 0 for FitContain (proportional scaling)
37 if p.Fit == FitCover && p.Height <= 0 {
38 return ErrInvalidPreset
39 }
40 // Quality must be in JPEG range (1-100)
41 if p.Quality < 1 || p.Quality > 100 {
42 return ErrInvalidPreset
43 }
44 // Validate FitMode is a known value
45 if p.Fit != FitCover && p.Fit != FitContain {
46 return ErrInvalidPreset
47 }
48 return nil
49}
50
51// presets is the registry of all available image presets.
52var presets = map[string]Preset{
53 "avatar": {
54 Name: "avatar",
55 Width: 1000,
56 Height: 1000,
57 Fit: FitCover,
58 Quality: 85,
59 },
60 "avatar_small": {
61 Name: "avatar_small",
62 Width: 360,
63 Height: 360,
64 Fit: FitCover,
65 Quality: 80,
66 },
67 "banner": {
68 Name: "banner",
69 Width: 640,
70 Height: 300,
71 Fit: FitCover,
72 Quality: 85,
73 },
74 "content_preview": {
75 Name: "content_preview",
76 Width: 800,
77 Height: 0,
78 Fit: FitContain,
79 Quality: 80,
80 },
81 "content_full": {
82 Name: "content_full",
83 Width: 1600,
84 Height: 0,
85 Fit: FitContain,
86 Quality: 90,
87 },
88 "embed_thumbnail": {
89 Name: "embed_thumbnail",
90 Width: 720,
91 Height: 360,
92 Fit: FitCover,
93 Quality: 80,
94 },
95}
96
97// GetPreset returns the preset configuration for the given name.
98// Returns ErrInvalidPreset if the preset name is not found.
99func GetPreset(name string) (Preset, error) {
100 if name == "" {
101 return Preset{}, ErrInvalidPreset
102 }
103 preset, exists := presets[name]
104 if !exists {
105 return Preset{}, ErrInvalidPreset
106 }
107 return preset, nil
108}
109
110// ListPresets returns all available presets.
111func ListPresets() []Preset {
112 result := make([]Preset, 0, len(presets))
113 for _, p := range presets {
114 result = append(result, p)
115 }
116 return result
117}