|
| 1 | +/* |
| 2 | + * COPYRIGHT: See COPYING in the top level directory |
| 3 | + * PROJECT: Imaging |
| 4 | + * FILE: ImagingFacade.cs |
| 5 | + * PURPOSE: Official public entry point for the Imaging engine |
| 6 | + * PROGRAMER: Peter Geinitz (Wayfarer) |
| 7 | + */ |
| 8 | + |
| 9 | +using System; |
| 10 | +using System.Collections.Generic; |
| 11 | +using System.Drawing; |
| 12 | +using System.Drawing.Imaging; |
| 13 | +using System.Threading.Tasks; |
| 14 | +using System.Windows.Media.Imaging; |
| 15 | +using Imaging.Enums; |
| 16 | + |
| 17 | +namespace Imaging |
| 18 | +{ |
| 19 | + /// <summary> |
| 20 | + /// Unified facade for the Imaging engine. |
| 21 | + /// This class provides a stable public API for common image processing tasks, |
| 22 | + /// including loading, saving, conversion, resizing, filtering, pixel manipulation, |
| 23 | + /// GIF handling, blending, and texture generation. |
| 24 | + /// All internal classes like <see cref="ImageRender"/> or <see cref="TextureGenerator"/> |
| 25 | + /// are hidden behind this façade. |
| 26 | + /// </summary> |
| 27 | + public static class ImagingFacade |
| 28 | + { |
| 29 | + |
| 30 | + #region Register |
| 31 | + /// <summary> |
| 32 | + /// Gets the singleton instance of the <see cref="ImageRegister"/>. |
| 33 | + /// Allows querying and modifying filter and texture settings globally. |
| 34 | + /// </summary> |
| 35 | + public static ImageRegister Register => ImageRegister.Instance; |
| 36 | + |
| 37 | + /// <summary> |
| 38 | + /// Retrieves the configuration for a specific filter type. |
| 39 | + /// </summary> |
| 40 | + /// <param name="filter">The filter type.</param> |
| 41 | + /// <returns>The current <see cref="FiltersConfig"/> for the filter.</returns> |
| 42 | + public static FiltersConfig GetFilterSettings(FiltersType filter) => Register.GetSettings(filter); |
| 43 | + |
| 44 | + /// <summary> |
| 45 | + /// Updates the configuration for a specific filter type. |
| 46 | + /// </summary> |
| 47 | + /// <param name="filter">The filter type.</param> |
| 48 | + /// <param name="config">The new filter configuration.</param> |
| 49 | + public static void SetFilterSettings(FiltersType filter, FiltersConfig config) => Register.SetSettings(filter, config); |
| 50 | + |
| 51 | + /// <summary> |
| 52 | + /// Retrieves all available filters. |
| 53 | + /// </summary> |
| 54 | + /// <returns>An enumerable of available <see cref="FiltersType"/>.</returns> |
| 55 | + public static IEnumerable<FiltersType> GetAvailableFilters() => Register.GetAvailableFilters(); |
| 56 | + |
| 57 | + /// <summary> |
| 58 | + /// Gets the property names used by a specific filter type. |
| 59 | + /// </summary> |
| 60 | + /// <param name="filter">The filter type.</param> |
| 61 | + /// <returns>A set of property names relevant to the filter.</returns> |
| 62 | + public static HashSet<string> GetFilterProperties(FiltersType filter) => Register.GetUsedProperties(filter); |
| 63 | + |
| 64 | + /// <summary> |
| 65 | + /// Retrieves the configuration for a specific texture type. |
| 66 | + /// </summary> |
| 67 | + /// <param name="texture">The texture type.</param> |
| 68 | + /// <returns>The current <see cref="TextureConfiguration"/> for the texture.</returns> |
| 69 | + public static TextureConfiguration GetTextureSettings(TextureType texture) => Register.GetSettings(texture); |
| 70 | + |
| 71 | + /// <summary> |
| 72 | + /// Updates the configuration for a specific texture type. |
| 73 | + /// </summary> |
| 74 | + /// <param name="texture">The texture type.</param> |
| 75 | + /// <param name="config">The new texture configuration.</param> |
| 76 | + public static void SetTextureSettings(TextureType texture, TextureConfiguration config) => Register.SetSettings(texture, config); |
| 77 | + |
| 78 | + /// <summary> |
| 79 | + /// Gets the property names used by a specific texture type. |
| 80 | + /// </summary> |
| 81 | + /// <param name="texture">The texture type.</param> |
| 82 | + /// <returns>A set of property names relevant to the texture.</returns> |
| 83 | + public static HashSet<string> GetTextureProperties(TextureType texture) => Register.GetUsedProperties(texture); |
| 84 | + |
| 85 | + /// <summary> |
| 86 | + /// Loads filter and texture settings from a JSON string. |
| 87 | + /// </summary> |
| 88 | + /// <param name="json">The JSON string containing settings.</param> |
| 89 | + public static void LoadSettingsFromJson(string json) => Register.LoadSettingsFromJson(json); |
| 90 | + |
| 91 | + /// <summary> |
| 92 | + /// Retrieves the current filter and texture settings as a JSON string. |
| 93 | + /// </summary> |
| 94 | + /// <returns>A JSON representation of the current settings.</returns> |
| 95 | + public static string GetSettingsAsJson() => Register.GetSettingsAsJson(); |
| 96 | + |
| 97 | + /// <summary> |
| 98 | + /// Adds an error to the global Imaging error log. |
| 99 | + /// </summary> |
| 100 | + /// <param name="ex">The exception to log.</param> |
| 101 | + public static void LogError(Exception ex) => Register.SetError(ex); |
| 102 | + |
| 103 | + /// <summary> |
| 104 | + /// Gets the last error message recorded by the Imaging engine. |
| 105 | + /// </summary> |
| 106 | + public static string? LastError => Register.LastError; |
| 107 | + #endregion |
| 108 | + |
| 109 | + #region Load / Save |
| 110 | + |
| 111 | + /// <summary> |
| 112 | + /// Loads a bitmap from the specified file path. |
| 113 | + /// </summary> |
| 114 | + /// <param name="path">The file path to the image.</param> |
| 115 | + /// <returns>A <see cref="Bitmap"/> representing the loaded image.</returns> |
| 116 | + public static Bitmap Load(string path) |
| 117 | + => new ImageRender().GetOriginalBitmap(path); |
| 118 | + |
| 119 | + /// <summary> |
| 120 | + /// Saves a bitmap to the specified path in the given format. |
| 121 | + /// </summary> |
| 122 | + /// <param name="bitmap">The bitmap to save.</param> |
| 123 | + /// <param name="path">The target file path.</param> |
| 124 | + /// <param name="format">The <see cref="ImageFormat"/> to save as.</param> |
| 125 | + public static void Save(Bitmap bitmap, string path, ImageFormat format) |
| 126 | + => new ImageRender().SaveBitmap(bitmap, path, format); |
| 127 | + |
| 128 | + #endregion |
| 129 | + |
| 130 | + #region Conversion |
| 131 | + |
| 132 | + /// <summary> |
| 133 | + /// Converts a <see cref="Bitmap"/> to a WPF <see cref="BitmapImage"/>. |
| 134 | + /// </summary> |
| 135 | + /// <param name="bitmap">The source bitmap.</param> |
| 136 | + /// <param name="lossless">Whether to preserve lossless conversion (default true).</param> |
| 137 | + /// <returns>The converted <see cref="BitmapImage"/>.</returns> |
| 138 | + public static BitmapImage ToBitmapImage(Bitmap bitmap, bool lossless = true) |
| 139 | + => new ImageRender().BitmapToBitmapImage(bitmap, lossless); |
| 140 | + |
| 141 | + /// <summary> |
| 142 | + /// Converts a WPF <see cref="BitmapImage"/> to a <see cref="Bitmap"/>. |
| 143 | + /// </summary> |
| 144 | + /// <param name="bitmapImage">The source bitmap image.</param> |
| 145 | + /// <returns>The converted <see cref="Bitmap"/>.</returns> |
| 146 | + public static Bitmap ToBitmap(BitmapImage bitmapImage) |
| 147 | + => new ImageRender().BitmapImageToBitmap(bitmapImage); |
| 148 | + |
| 149 | + #endregion |
| 150 | + |
| 151 | + #region Resize / Crop |
| 152 | + |
| 153 | + /// <summary> |
| 154 | + /// Resizes the specified bitmap to the target width and height. |
| 155 | + /// </summary> |
| 156 | + /// <param name="image">The source bitmap.</param> |
| 157 | + /// <param name="width">The target width.</param> |
| 158 | + /// <param name="height">The target height.</param> |
| 159 | + /// <returns>A resized <see cref="Bitmap"/>.</returns> |
| 160 | + public static Bitmap Resize(Bitmap image, int width, int height) |
| 161 | + => new ImageRender().BitmapScaling(image, width, height); |
| 162 | + |
| 163 | + /// <summary> |
| 164 | + /// Resizes the specified bitmap by a scaling factor. |
| 165 | + /// </summary> |
| 166 | + /// <param name="image">The source bitmap.</param> |
| 167 | + /// <param name="scaling">Scaling factor (1.0 = original size).</param> |
| 168 | + /// <returns>A resized <see cref="Bitmap"/>.</returns> |
| 169 | + public static Bitmap Resize(Bitmap image, float scaling) |
| 170 | + => new ImageRender().BitmapScaling(image, scaling); |
| 171 | + |
| 172 | + /// <summary> |
| 173 | + /// Crops the bitmap to the specified rectangle. |
| 174 | + /// </summary> |
| 175 | + /// <param name="image">The source bitmap.</param> |
| 176 | + /// <param name="x">The X-coordinate of the crop origin.</param> |
| 177 | + /// <param name="y">The Y-coordinate of the crop origin.</param> |
| 178 | + /// <param name="width">The width of the cropped area.</param> |
| 179 | + /// <param name="height">The height of the cropped area.</param> |
| 180 | + /// <returns>The cropped <see cref="Bitmap"/>.</returns> |
| 181 | + public static Bitmap Crop(Bitmap image, int x, int y, int width, int height) |
| 182 | + => new ImageRender().CutBitmap(image, x, y, height, width); |
| 183 | + |
| 184 | + #endregion |
| 185 | + |
| 186 | + #region Filters |
| 187 | + |
| 188 | + /// <summary> |
| 189 | + /// Applies a global filter to the bitmap. |
| 190 | + /// </summary> |
| 191 | + /// <param name="image">The source bitmap.</param> |
| 192 | + /// <param name="filter">The filter type to apply.</param> |
| 193 | + /// <returns>The filtered <see cref="Bitmap"/>.</returns> |
| 194 | + public static Bitmap ApplyFilter(Bitmap image, FiltersType filter) |
| 195 | + => new ImageRender().FilterImage(image, filter); |
| 196 | + |
| 197 | + /// <summary> |
| 198 | + /// Applies a filter to a specified area of the bitmap with optional shape masking. |
| 199 | + /// </summary> |
| 200 | + /// <param name="image">The source bitmap.</param> |
| 201 | + /// <param name="filter">The filter type.</param> |
| 202 | + /// <param name="shape">The mask shape.</param> |
| 203 | + /// <param name="shapeParams">Optional parameters for the mask shape.</param> |
| 204 | + /// <param name="startPoint">Optional start point for the filter.</param> |
| 205 | + /// <returns>The filtered <see cref="Bitmap"/>.</returns> |
| 206 | + public static Bitmap ApplyFilterArea(Bitmap image, FiltersType filter, MaskShape shape, object shapeParams, System.Drawing.Point? startPoint = null) |
| 207 | + => new ImageRender().FilterImageArea(image, null, null, filter, shape, shapeParams, startPoint); |
| 208 | + |
| 209 | + #endregion |
| 210 | + |
| 211 | + #region Drawing / Pixels |
| 212 | + |
| 213 | + /// <summary> |
| 214 | + /// Gets the color of a pixel at the specified point. |
| 215 | + /// </summary> |
| 216 | + /// <param name="image">The bitmap.</param> |
| 217 | + /// <param name="p">The pixel location.</param> |
| 218 | + /// <returns>The <see cref="Color"/> of the pixel.</returns> |
| 219 | + public static Color GetPixel(Bitmap image, System.Drawing.Point p) |
| 220 | + => new ImageRender().GetPixel(image, p); |
| 221 | + |
| 222 | + /// <summary> |
| 223 | + /// Sets the color of a pixel at the specified point. |
| 224 | + /// </summary> |
| 225 | + /// <param name="image">The bitmap.</param> |
| 226 | + /// <param name="p">The pixel location.</param> |
| 227 | + /// <param name="color">The color to set.</param> |
| 228 | + public static void SetPixel(Bitmap image, System.Drawing.Point p, Color color) |
| 229 | + => new ImageRender().SetPixel(image, p, color); |
| 230 | + |
| 231 | + /// <summary> |
| 232 | + /// Performs a flood-fill operation starting from the specified pixel. |
| 233 | + /// </summary> |
| 234 | + /// <param name="image">The bitmap.</param> |
| 235 | + /// <param name="x">X-coordinate of start point.</param> |
| 236 | + /// <param name="y">Y-coordinate of start point.</param> |
| 237 | + /// <param name="newColor">The fill color.</param> |
| 238 | + public static void FloodFill(Bitmap image, int x, int y, Color newColor) |
| 239 | + => new ImageRender().FloodFillScanLineStack(image, x, y, newColor); |
| 240 | + |
| 241 | + #endregion |
| 242 | + |
| 243 | + #region Blending |
| 244 | + |
| 245 | + /// <summary> |
| 246 | + /// Combines two bitmaps by overlaying the second bitmap onto the first at the specified position. |
| 247 | + /// </summary> |
| 248 | + /// <param name="baseImage">The base bitmap.</param> |
| 249 | + /// <param name="overlay">The overlay bitmap.</param> |
| 250 | + /// <param name="x">X-coordinate for overlay placement.</param> |
| 251 | + /// <param name="y">Y-coordinate for overlay placement.</param> |
| 252 | + /// <returns>The combined <see cref="Bitmap"/>.</returns> |
| 253 | + public static Bitmap Combine(Bitmap baseImage, Bitmap overlay, int x, int y) |
| 254 | + => new ImageRender().CombineBitmap(baseImage, overlay, x, y); |
| 255 | + |
| 256 | + /// <summary> |
| 257 | + /// Blends two images by averaging pixel values. |
| 258 | + /// </summary> |
| 259 | + /// <param name="a">The first bitmap.</param> |
| 260 | + /// <param name="b">The second bitmap.</param> |
| 261 | + /// <returns>The blended <see cref="Bitmap"/>.</returns> |
| 262 | + public static Bitmap Blend(Bitmap a, Bitmap b) |
| 263 | + => new ImageRender().AverageImages(a, b); |
| 264 | + |
| 265 | + #endregion |
| 266 | + |
| 267 | + #region Adjustments |
| 268 | + |
| 269 | + /// <summary> |
| 270 | + /// Adjusts the brightness of the bitmap. |
| 271 | + /// </summary> |
| 272 | + /// <param name="image">The bitmap.</param> |
| 273 | + /// <param name="factor">Brightness factor.</param> |
| 274 | + /// <returns>The adjusted <see cref="Bitmap"/>.</returns> |
| 275 | + public static Bitmap AdjustBrightness(Bitmap image, double factor) |
| 276 | + => new ImageRender().AdjustBrightness(image, factor); |
| 277 | + |
| 278 | + /// <summary> |
| 279 | + /// Adjusts the hue of the bitmap. |
| 280 | + /// </summary> |
| 281 | + /// <param name="image">The bitmap.</param> |
| 282 | + /// <param name="shift">Hue shift value.</param> |
| 283 | + /// <returns>The adjusted <see cref="Bitmap"/>.</returns> |
| 284 | + public static Bitmap AdjustHue(Bitmap image, double shift) |
| 285 | + => new ImageRender().AdjustHue(image, shift); |
| 286 | + |
| 287 | + /// <summary> |
| 288 | + /// Adjusts the saturation of the bitmap. |
| 289 | + /// </summary> |
| 290 | + /// <param name="image">The bitmap.</param> |
| 291 | + /// <param name="factor">Saturation factor.</param> |
| 292 | + /// <returns>The adjusted <see cref="Bitmap"/>.</returns> |
| 293 | + public static Bitmap AdjustSaturation(Bitmap image, double factor) |
| 294 | + => new ImageRender().AdjustSaturation(image, factor); |
| 295 | + |
| 296 | + /// <summary> |
| 297 | + /// Applies gamma correction to the bitmap. |
| 298 | + /// </summary> |
| 299 | + /// <param name="image">The bitmap.</param> |
| 300 | + /// <param name="gamma">Gamma value.</param> |
| 301 | + /// <returns>The gamma-corrected <see cref="Bitmap"/>.</returns> |
| 302 | + public static Bitmap ApplyGamma(Bitmap image, double gamma) |
| 303 | + => new ImageRender().ApplyGammaCorrection(image, gamma); |
| 304 | + |
| 305 | + #endregion |
| 306 | + |
| 307 | + #region GIF |
| 308 | + |
| 309 | + /// <summary> |
| 310 | + /// Loads a GIF asynchronously and returns all frames as <see cref="Bitmap"/> objects. |
| 311 | + /// </summary> |
| 312 | + /// <param name="path">Path to the GIF file.</param> |
| 313 | + /// <returns>A task that represents the asynchronous operation, containing a read-only list of frames.</returns> |
| 314 | + public static async Task<IReadOnlyList<Bitmap>> LoadGifAsync(string path) |
| 315 | + { |
| 316 | + var sources = await new ImageRender().LoadGifAsync(path); |
| 317 | + |
| 318 | + var frames = new List<Bitmap>(sources.Count); |
| 319 | + foreach (var src in sources) |
| 320 | + frames.Add(ImageExtension.ToBitmap((BitmapImage)src)); |
| 321 | + |
| 322 | + return frames; |
| 323 | + } |
| 324 | + |
| 325 | + /// <summary> |
| 326 | + /// Creates a GIF from a sequence of frames. |
| 327 | + /// </summary> |
| 328 | + /// <param name="frames">The frames to include in the GIF.</param> |
| 329 | + /// <param name="target">The output file path.</param> |
| 330 | + public static void CreateGif(IEnumerable<FrameInfo> frames, string target) |
| 331 | + => new ImageRender().CreateGif(frames, target); |
| 332 | + |
| 333 | + #endregion |
| 334 | + |
| 335 | + #region Textures |
| 336 | + |
| 337 | + /// <summary> |
| 338 | + /// Generates a procedural texture using the specified type, mask shape, and parameters. |
| 339 | + /// </summary> |
| 340 | + /// <param name="width">Width of the texture.</param> |
| 341 | + /// <param name="height">Height of the texture.</param> |
| 342 | + /// <param name="type">Type of texture (<see cref="TextureType"/>).</param> |
| 343 | + /// <param name="shape">Mask shape (<see cref="MaskShape"/>).</param> |
| 344 | + /// <param name="shapeParams">Optional parameters for the shape.</param> |
| 345 | + /// <param name="startPoint">Optional starting point.</param> |
| 346 | + /// <returns>The generated texture as a <see cref="Bitmap"/>.</returns> |
| 347 | + public static Bitmap GenerateTexture(int width, int height, TextureType type, MaskShape shape, object shapeParams, System.Drawing.Point? startPoint = null) |
| 348 | + => new TextureGenerator().GenerateTexture(width, height, type, shape, startPoint, shapeParams); |
| 349 | + |
| 350 | + #endregion |
| 351 | + } |
| 352 | +} |
0 commit comments