{"version":3,"file":"ImageUtils.mjs","sources":["../src/ImageUtils.ts"],"sourcesContent":["/**\n * @module ImageUtils\n * @description A comprehensive collection of utility functions for image manipulation, processing, and analysis.\n * Supports image format conversion, resizing, cropping, compression, metadata extraction, and various image effects.\n * @example\n * ```typescript\n * import { ImageUtils } from 'houser-js-utils';\n *\n * // Convert base64 to file\n * const file = await ImageUtils.convertBase64ToFile(base64String, 'image.jpg');\n *\n * // Resize image with quality settings\n * const resized = await ImageUtils.resizeImage(file, { maxWidth: 800, quality: 0.8 });\n *\n * // Get image metadata\n * const metadata = await ImageUtils.getImageMetadata(file);\n * ```\n */\n\n/**\n * Regular expression for validating base64 image data URLs\n * Matches data URLs for PNG, JPG, JPEG, GIF, SVG, and WebP images\n */\nconst base64RegEx = /^data:image\\/(png|jpg|jpeg|gif|svg|webp);base64,/;\n\n/**\n * Supported image formats for conversion and processing\n */\ntype ImageFormat = \"jpeg\" | \"png\" | \"webp\" | \"gif\";\n\n/**\n * Options for image resizing operations\n */\ninterface ImageResizeOptions {\n  /** Maximum width of the resized image */\n  maxWidth?: number;\n  /** Maximum height of the resized image */\n  maxHeight?: number;\n  /** Quality of the output image (0-1) */\n  quality?: number;\n  /** Output format of the resized image */\n  format?: ImageFormat;\n}\n\n/**\n * Metadata about an image file\n */\ninterface ImageMetadata {\n  /** Width of the image in pixels */\n  width: number;\n  /** Height of the image in pixels */\n  height: number;\n  /** MIME type of the image */\n  type: string;\n  /** Size of the image file in bytes */\n  size: number;\n}\n\n/**\n * Dimensions for a scaled image\n */\ninterface ScaledDimensions {\n  /** Scaled width in pixels */\n  width: number;\n  /** Scaled height in pixels */\n  height: number;\n}\n\nexport const ImageUtils = {\n  /**\n   * Applies a grayscale filter to an image by converting all pixels to their average RGB value.\n   * @param file - The image file to convert to grayscale\n   * @returns Promise resolving to the grayscale image as a Blob\n   * @example\n   * ```typescript\n   * const grayscaleImage = await ImageUtils.applyGrayscale(imageFile);\n   * // Use the grayscale blob as needed\n   * ```\n   */\n  async applyGrayscale(file: File): Promise<Blob> {\n    return new Promise((resolve, reject) => {\n      const img = new Image();\n      img.onload = () => {\n        const canvas = document.createElement(\"canvas\");\n        const ctx = canvas.getContext(\"2d\");\n        if (!ctx) {\n          reject(new Error(\"Could not get canvas context\"));\n          return;\n        }\n\n        canvas.width = img.width;\n        canvas.height = img.height;\n        ctx.drawImage(img, 0, 0);\n\n        const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);\n        const data = imageData.data;\n\n        for (let i = 0; i < data.length; i += 4) {\n          const avg = (data[i] + data[i + 1] + data[i + 2]) / 3;\n          data[i] = avg; // red\n          data[i + 1] = avg; // green\n          data[i + 2] = avg; // blue\n        }\n\n        ctx.putImageData(imageData, 0, 0);\n        canvas.toBlob((blob) => {\n          if (blob) resolve(blob);\n          else reject(new Error(\"Failed to create blob\"));\n        }, file.type);\n      };\n      img.onerror = reject;\n      img.src = URL.createObjectURL(file);\n    });\n  },\n\n  /**\n   * Calculates the aspect ratio of an image from its dimensions.\n   * @param width - The width of the image in pixels\n   * @param height - The height of the image in pixels\n   * @returns The aspect ratio as a decimal number (width/height)\n   * @example\n   * ```typescript\n   * const ratio = ImageUtils.calculateAspectRatio(1920, 1080); // Returns 1.777...\n   * const isWidescreen = ratio > 1.5; // true for 16:9 ratio\n   * ```\n   */\n  calculateAspectRatio(width: number, height: number): number {\n    return width / height;\n  },\n\n  /**\n   * Converts a base64 string to a Blob object.\n   * @param base64 - The base64 string to convert (without data URL prefix)\n   * @param type - The MIME type of the image (default: \"image/jpeg\")\n   * @returns Promise resolving to a Blob object\n   * @example\n   * ```typescript\n   * const blob = await ImageUtils.base64ToBlob(base64String, 'image/png');\n   * const url = URL.createObjectURL(blob);\n   * ```\n   */\n  async base64ToBlob(\n    base64: string,\n    type: string = \"image/jpeg\"\n  ): Promise<Blob> {\n    const response = await fetch(`data:${type};base64,${base64}`);\n    return response.blob();\n  },\n\n  /**\n   * Converts a Blob to a base64 string (without data URL prefix).\n   * @param blob - The Blob to convert\n   * @returns Promise resolving to base64 string\n   * @example\n   * ```typescript\n   * const base64 = await ImageUtils.blobToBase64(imageBlob);\n   * console.log('data:image/jpeg;base64,' + base64); // Full data URL\n   * ```\n   */\n  async blobToBase64(blob: Blob): Promise<string> {\n    return new Promise((resolve, reject) => {\n      const reader = new FileReader();\n      reader.onload = () => {\n        const base64 = reader.result as string;\n        resolve(base64.split(\",\")[1]);\n      };\n      reader.onerror = reject;\n      reader.readAsDataURL(blob);\n    });\n  },\n\n  /**\n   * Compresses an image file by reducing its quality while maintaining dimensions.\n   * @param file - The image file to compress\n   * @param quality - Compression quality from 0 (lowest) to 1 (highest, default: 0.7)\n   * @returns Promise resolving to the compressed image as a Blob\n   * @example\n   * ```typescript\n   * const compressed = await ImageUtils.compressImage(largeImage, 0.5);\n   * console.log(`Original: ${largeImage.size} bytes, Compressed: ${compressed.size} bytes`);\n   * ```\n   */\n  async compressImage(file: File, quality: number = 0.7): Promise<Blob> {\n    return new Promise((resolve, reject) => {\n      const img = new Image();\n      img.onload = () => {\n        const canvas = document.createElement(\"canvas\");\n        const ctx = canvas.getContext(\"2d\");\n        if (!ctx) {\n          reject(new Error(\"Could not get canvas context\"));\n          return;\n        }\n\n        canvas.width = img.width;\n        canvas.height = img.height;\n        ctx.drawImage(img, 0, 0);\n\n        canvas.toBlob(\n          (blob) => {\n            if (blob) resolve(blob);\n            else reject(new Error(\"Failed to create blob\"));\n          },\n          file.type,\n          quality\n        );\n      };\n      img.onerror = reject;\n      img.src = URL.createObjectURL(file);\n    });\n  },\n\n  /**\n   * Converts a base64 data URL string to a File object.\n   * @param base64 - The base64 data URL string (must include data:image/... prefix)\n   * @param filename - The name for the resulting file\n   * @returns Promise resolving to File object, or null if base64 is invalid\n   * @example\n   * ```typescript\n   * const file = await ImageUtils.convertBase64ToFile(\n   *   'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8/5+hHgAHggJ/PchI7wAAAABJRU5ErkJggg==',\n   *   'pixel.png'\n   * );\n   * ```\n   */\n  convertBase64ToFile(base64: string, filename: string): Promise<File> | null {\n    if (!base64RegEx.test(base64)) return null;\n    return this.base64ToBlob(base64).then((blob) => new File([blob], filename));\n  },\n\n  /**\n   * Creates a thumbnail image with specified maximum dimensions.\n   * @param file - The image file to create a thumbnail from\n   * @param maxSize - Maximum size in pixels for the longest dimension (default: 200)\n   * @returns Promise resolving to thumbnail as base64 data URL string\n   * @example\n   * ```typescript\n   * const thumbnail = await ImageUtils.createThumbnail(imageFile, 150);\n   * document.getElementById('preview').src = thumbnail;\n   * ```\n   */\n  async createThumbnail(file: File, maxSize: number = 200): Promise<string> {\n    return new Promise((resolve, reject) => {\n      const img = new Image();\n      img.onload = () => {\n        const canvas = document.createElement(\"canvas\");\n        const ctx = canvas.getContext(\"2d\");\n        if (!ctx) {\n          reject(new Error(\"Could not get canvas context\"));\n          return;\n        }\n\n        let width = img.width;\n        let height = img.height;\n\n        if (width > height) {\n          if (width > maxSize) {\n            height = Math.round((height * maxSize) / width);\n            width = maxSize;\n          }\n        } else {\n          if (height > maxSize) {\n            width = Math.round((width * maxSize) / height);\n            height = maxSize;\n          }\n        }\n\n        canvas.width = width;\n        canvas.height = height;\n        ctx.drawImage(img, 0, 0, width, height);\n        resolve(canvas.toDataURL(\"image/jpeg\", 0.7));\n      };\n      img.onerror = reject;\n      img.src = URL.createObjectURL(file);\n    });\n  },\n\n  /**\n   * Crops an image to specified rectangular dimensions.\n   * @param file - The image file to crop\n   * @param x - Starting x coordinate for the crop (pixels from left)\n   * @param y - Starting y coordinate for the crop (pixels from top)\n   * @param width - Width of the crop area in pixels\n   * @param height - Height of the crop area in pixels\n   * @returns Promise resolving to the cropped image as a Blob\n   * @example\n   * ```typescript\n   * // Crop a 200x200 square from the center of the image\n   * const cropped = await ImageUtils.cropImage(imageFile, 100, 100, 200, 200);\n   * ```\n   */\n  async cropImage(\n    file: File,\n    x: number,\n    y: number,\n    width: number,\n    height: number\n  ): Promise<Blob> {\n    return new Promise((resolve, reject) => {\n      const img = new Image();\n      img.onload = () => {\n        const canvas = document.createElement(\"canvas\");\n        const ctx = canvas.getContext(\"2d\");\n        if (!ctx) {\n          reject(new Error(\"Could not get canvas context\"));\n          return;\n        }\n\n        canvas.width = width;\n        canvas.height = height;\n        ctx.drawImage(img, x, y, width, height, 0, 0, width, height);\n\n        canvas.toBlob((blob) => {\n          if (blob) resolve(blob);\n          else reject(new Error(\"Failed to create blob\"));\n        }, file.type);\n      };\n      img.onerror = reject;\n      img.src = URL.createObjectURL(file);\n    });\n  },\n\n  /**\n   * Extracts metadata information from an image file.\n   * @param file - The image file to analyze\n   * @returns Promise resolving to object containing width, height, type, and size\n   * @example\n   * ```typescript\n   * const metadata = await ImageUtils.getImageMetadata(imageFile);\n   * console.log(`Image: ${metadata.width}x${metadata.height}, ${metadata.type}, ${metadata.size} bytes`);\n   * ```\n   */\n  async getImageMetadata(file: File): Promise<ImageMetadata> {\n    return new Promise((resolve, reject) => {\n      const img = new Image();\n      img.onload = () => {\n        resolve({\n          width: img.width,\n          height: img.height,\n          type: file.type,\n          size: file.size,\n        });\n      };\n      img.onerror = reject;\n      img.src = URL.createObjectURL(file);\n    });\n  },\n\n  /**\n   * Analyzes an image to determine its most dominant color.\n   * @param file - The image file to analyze\n   * @returns Promise resolving to the dominant color as a hex string\n   * @example\n   * ```typescript\n   * const dominantColor = await ImageUtils.getDominantColor(imageFile);\n   * console.log(`Dominant color: ${dominantColor}`); // e.g., \"#ff5733\"\n   * document.body.style.backgroundColor = dominantColor;\n   * ```\n   */\n  async getDominantColor(file: File): Promise<string> {\n    return new Promise((resolve, reject) => {\n      const img = new Image();\n      img.onload = () => {\n        const canvas = document.createElement(\"canvas\");\n        const ctx = canvas.getContext(\"2d\");\n        if (!ctx) {\n          reject(new Error(\"Could not get canvas context\"));\n          return;\n        }\n\n        // Scale down image for faster processing\n        const scale = Math.min(1, 100 / Math.max(img.width, img.height));\n        canvas.width = img.width * scale;\n        canvas.height = img.height * scale;\n        ctx.drawImage(img, 0, 0, canvas.width, canvas.height);\n\n        const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);\n        const data = imageData.data;\n        const colorCounts: { [key: string]: number } = {};\n\n        // Sample pixels and count colors\n        for (let i = 0; i < data.length; i += 4) {\n          const r = data[i];\n          const g = data[i + 1];\n          const b = data[i + 2];\n          const color = `#${r.toString(16).padStart(2, \"0\")}${g\n            .toString(16)\n            .padStart(2, \"0\")}${b.toString(16).padStart(2, \"0\")}`;\n          colorCounts[color] = (colorCounts[color] || 0) + 1;\n        }\n\n        // Find most frequent color\n        let maxCount = 0;\n        let dominantColor = \"#000000\";\n        for (const color in colorCounts) {\n          if (colorCounts[color] > maxCount) {\n            maxCount = colorCounts[color];\n            dominantColor = color;\n          }\n        }\n\n        resolve(dominantColor);\n      };\n      img.onerror = reject;\n      img.src = URL.createObjectURL(file);\n    });\n  },\n\n  /**\n   * Calculates scaled dimensions for an image while maintaining aspect ratio.\n   * @param img - The HTML image element to scale\n   * @param maxWidth - Optional maximum width constraint\n   * @param maxHeight - Optional maximum height constraint\n   * @returns Object containing the calculated scaled width and height\n   * @example\n   * ```typescript\n   * const scaled = ImageUtils.getScaledDimensions(imageElement, 800, 600);\n   * console.log(`Scaled dimensions: ${scaled.width}x${scaled.height}`);\n   * ```\n   */\n  getScaledDimensions(\n    img: HTMLImageElement,\n    maxWidth?: number,\n    maxHeight?: number\n  ): ScaledDimensions {\n    const originalWidth = img.width;\n    const originalHeight = img.height;\n    let newWidth = originalWidth;\n    let newHeight = originalHeight;\n\n    if (maxWidth && maxHeight) {\n      const aspectRatio = originalWidth / originalHeight;\n      if (originalWidth > maxWidth || originalHeight > maxHeight) {\n        if (aspectRatio > 1) {\n          newWidth = maxWidth;\n          newHeight = maxWidth / aspectRatio;\n        } else {\n          newHeight = maxHeight;\n          newWidth = maxHeight * aspectRatio;\n        }\n      }\n    } else if (maxWidth) {\n      const aspectRatio = originalWidth / originalHeight;\n      if (originalWidth > maxWidth) {\n        newWidth = maxWidth;\n        newHeight = maxWidth / aspectRatio;\n      }\n    } else if (maxHeight) {\n      const aspectRatio = originalWidth / originalHeight;\n      if (originalHeight > maxHeight) {\n        newHeight = maxHeight;\n        newWidth = maxHeight * aspectRatio;\n      }\n    }\n\n    return {\n      width: Math.round(newWidth),\n      height: Math.round(newHeight),\n    };\n  },\n\n  /**\n   * Checks if an image exists and is accessible at the given URL.\n   * @param url - The URL to check for image availability\n   * @returns Promise resolving to true if the image exists and is accessible\n   * @example\n   * ```typescript\n   * const exists = await ImageUtils.imageExists('https://example.com/image.jpg');\n   * if (exists) {\n   *   console.log('Image is available');\n   * }\n   * ```\n   */\n  async imageExists(url: string): Promise<boolean> {\n    try {\n      const response = await fetch(url);\n      return response.ok;\n    } catch (e) {\n      return false;\n    }\n  },\n\n  /**\n   * Validates whether a file is an image based on its MIME type.\n   * @param file - The file to check\n   * @returns True if the file is an image, false otherwise\n   * @example\n   * ```typescript\n   * const isImage = ImageUtils.isImageFile(selectedFile);\n   * if (!isImage) {\n   *   alert('Please select an image file');\n   * }\n   * ```\n   */\n  isImageFile(file: File): boolean {\n    return file.type.startsWith(\"image/\");\n  },\n\n  /**\n   * Loads an image from a URL and returns the HTMLImageElement.\n   * @param url - The URL of the image to load\n   * @returns Promise resolving to HTMLImageElement when image loads successfully\n   * @throws {Error} If the image fails to load\n   * @example\n   * ```typescript\n   * try {\n   *   const img = await ImageUtils.loadImage('https://example.com/image.jpg');\n   *   console.log(`Loaded image: ${img.width}x${img.height}`);\n   * } catch (error) {\n   *   console.error('Failed to load image:', error);\n   * }\n   * ```\n   */\n  loadImage(url: string): Promise<HTMLImageElement> {\n    return new Promise((resolve, reject) => {\n      const img = new Image();\n      img.onload = () => resolve(img);\n      img.onerror = reject;\n      img.src = url;\n    });\n  },\n\n  /**\n   * Loads and decodes an image from a URL with error handling.\n   * @param url - The URL of the image to load\n   * @returns Promise resolving to HTMLImageElement or null if loading fails\n   * @example\n   * ```typescript\n   * const img = await ImageUtils.loadImageElement('https://example.com/image.jpg');\n   * if (img) {\n   *   document.body.appendChild(img);\n   * } else {\n   *   console.log('Failed to load image');\n   * }\n   * ```\n   */\n  async loadImageElement(url: string): Promise<HTMLImageElement | null> {\n    const img = new Image();\n    img.src = url;\n\n    try {\n      await img.decode();\n    } catch (e) {\n      console.error(e);\n      return null;\n    }\n\n    return img;\n  },\n\n  /**\n   * Resizes an image file to fit within specified dimensions while maintaining aspect ratio.\n   * @param file - The image file to resize\n   * @param options - Resize options including max dimensions, quality, and output format\n   * @returns Promise resolving to the resized image as a Blob\n   * @example\n   * ```typescript\n   * const resized = await ImageUtils.resizeImage(originalFile, {\n   *   maxWidth: 800,\n   *   maxHeight: 600,\n   *   quality: 0.9,\n   *   format: 'jpeg'\n   * });\n   * ```\n   */\n  async resizeImage(\n    file: File,\n    options: ImageResizeOptions = {}\n  ): Promise<Blob> {\n    const {\n      maxWidth = 1920,\n      maxHeight = 1080,\n      quality = 0.8,\n      format = \"jpeg\",\n    } = options;\n\n    return new Promise((resolve, reject) => {\n      const img = new Image();\n      img.onload = () => {\n        const canvas = document.createElement(\"canvas\");\n        const ctx = canvas.getContext(\"2d\");\n        if (!ctx) {\n          reject(new Error(\"Could not get canvas context\"));\n          return;\n        }\n\n        let width = img.width;\n        let height = img.height;\n\n        if (width > height) {\n          if (width > maxWidth) {\n            height = Math.round((height * maxWidth) / width);\n            width = maxWidth;\n          }\n        } else {\n          if (height > maxHeight) {\n            width = Math.round((width * maxHeight) / height);\n            height = maxHeight;\n          }\n        }\n\n        canvas.width = width;\n        canvas.height = height;\n        ctx.drawImage(img, 0, 0, width, height);\n\n        canvas.toBlob(\n          (blob) => {\n            if (blob) {\n              resolve(blob);\n            } else {\n              reject(new Error(\"Failed to create blob\"));\n            }\n          },\n          `image/${format}`,\n          quality\n        );\n      };\n      img.onerror = reject;\n      img.src = URL.createObjectURL(file);\n    });\n  },\n\n  /**\n   * Rotates an image by the specified number of degrees around its center.\n   * @param file - The image file to rotate\n   * @param degrees - Degrees to rotate (0-360, positive for clockwise)\n   * @returns Promise resolving to the rotated image as a Blob\n   * @example\n   * ```typescript\n   * const rotated90 = await ImageUtils.rotateImage(imageFile, 90);\n   * const rotatedMinus45 = await ImageUtils.rotateImage(imageFile, -45);\n   * ```\n   */\n  async rotateImage(file: File, degrees: number): Promise<Blob> {\n    return new Promise((resolve, reject) => {\n      const img = new Image();\n      img.onload = () => {\n        const canvas = document.createElement(\"canvas\");\n        const ctx = canvas.getContext(\"2d\");\n        if (!ctx) {\n          reject(new Error(\"Could not get canvas context\"));\n          return;\n        }\n\n        // Calculate new canvas dimensions\n        const rad = (degrees * Math.PI) / 180;\n        const sin = Math.abs(Math.sin(rad));\n        const cos = Math.abs(Math.cos(rad));\n        const newWidth = img.width * cos + img.height * sin;\n        const newHeight = img.width * sin + img.height * cos;\n\n        canvas.width = newWidth;\n        canvas.height = newHeight;\n\n        // Rotate and draw\n        ctx.translate(newWidth / 2, newHeight / 2);\n        ctx.rotate(rad);\n        ctx.drawImage(img, -img.width / 2, -img.height / 2);\n\n        canvas.toBlob((blob) => {\n          if (blob) resolve(blob);\n          else reject(new Error(\"Failed to create blob\"));\n        }, file.type);\n      };\n      img.onerror = reject;\n      img.src = URL.createObjectURL(file);\n    });\n  },\n\n  /**\n   * Converts a URL to a File object by downloading the content.\n   * @param url - The URL to convert to a file\n   * @param filename - The name for the resulting file\n   * @param mimeType - The MIME type for the file\n   * @returns Promise resolving to a File object\n   * @example\n   * ```typescript\n   * const file = await ImageUtils.urlToFile(\n   *   'https://example.com/image.jpg',\n   *   'downloaded-image.jpg',\n   *   'image/jpeg'\n   * );\n   * ```\n   */\n  async urlToFile(\n    url: string,\n    filename: string,\n    mimeType: string\n  ): Promise<File> {\n    const response = await fetch(url);\n    const blob = await response.blob();\n    return new File([blob], filename, { type: mimeType });\n  },\n\n  /**\n   * Validates that image dimensions are within specified limits.\n   * @param width - The width to validate\n   * @param height - The height to validate\n   * @param maxWidth - The maximum allowed width\n   * @param maxHeight - The maximum allowed height\n   * @returns True if dimensions are within limits, false otherwise\n   * @example\n   * ```typescript\n   * const isValid = ImageUtils.validateImageDimensions(1920, 1080, 2000, 2000);\n   * if (!isValid) {\n   *   console.log('Image is too large');\n   * }\n   * ```\n   */\n  validateImageDimensions(\n    width: number,\n    height: number,\n    maxWidth: number,\n    maxHeight: number\n  ): boolean {\n    return width <= maxWidth && height <= maxHeight;\n  },\n};\n"],"names":[],"mappings":"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"}