# Library: @cp949/web-image-util

## Overview
- Browser image processing library built on Canvas 2D API.
- Main workflow is async image processing through a chain returned by `processImage(...)`.
- Provides preset helpers and SVG/conversion utilities for browser-safe image workflows.

## Key APIs
- `processImage(source: ImageSource, options?: ProcessorOptions): InitialProcessor`
- `unsafe_processImage(source: ImageSource, options?: ProcessorOptions): InitialProcessor`
- `interface ProcessorOptions { crossOrigin?: string; defaultQuality?: number; defaultBackground?: ResizeBackground; timeout?: number; fetchTimeoutMs?: number; maxSourceBytes?: number; allowedProtocols?: string[]; abortSignal?: AbortSignal; svgSanitizer?: SvgSanitizerMode; }`
- `type SvgSanitizerMode = 'lightweight' | 'strict' | 'skip'`
- `type ResizeConfig = CoverConfig | ContainConfig | FillConfig | MaxFitConfig | MinFitConfig`
- `createThumbnail(source: ImageSource, options: ThumbnailOptions): Promise<ResultBlob>`
- `createAvatar(source: ImageSource, options?: AvatarOptions): Promise<ResultBlob>`
- `createSocialImage(source: ImageSource, options: SocialImageOptions): Promise<ResultBlob>`
- `blobToDataURL(blob: Blob): Promise<string>`
- `convertToBlob(source: ImageSource | HTMLCanvasElement, options?: ConvertToBlobOptions): Promise<Blob>`
- `convertToBlobDetailed(source: ImageSource | HTMLCanvasElement, options?: ConvertToBlobDetailedOptions): Promise<ResultBlob>`
- `convertToDataURL(source: ImageSource | HTMLCanvasElement, options?: ConvertToDataURLOptions): Promise<string>`
- `convertToDataURLDetailed(source: ImageSource | HTMLCanvasElement, options?: ConvertToDataURLDetailedOptions): Promise<ResultDataURL>`
- `convertToElement(source: ImageSource): Promise<HTMLImageElement>`
- `convertToFile(source: ImageSource | HTMLCanvasElement, filename: string, options?: ConvertToFileOptions): Promise<File>`
- `convertToFileDetailed(source: ImageSource | HTMLCanvasElement, filename: string, options?: ConvertToFileDetailedOptions): Promise<ResultFile>`
- `dataURLToBlob(dataURL: string): Blob`
- `decodeSvgDataURL(source: string): DecodedSvgDataURL`
- `detectBrowserCapabilities(options?: DetectionOptions): Promise<BrowserCapabilities>`
- `detectImageSourceInfo(source: ImageSource, options?: DetectImageSourceInfoOptions): Promise<ImageSourceInfo>`
- `detectImageSourceType(source: ImageSource): ImageSourceType`
- `detectImageStringSourceInfo(source: string): ImageStringSourceInfo`
- `detectImageStringSourceType(source: string): ImageStringSourceType`
- `enhanceBrowserCompatibility(svgString: string, options?: SvgCompatibilityOptions): { enhancedSvg: string; report: SvgCompatibilityReport; }`
- `enhanceSvgForBrowser(svgString: string): string`
- `ensureBlob(source: ImageSource | HTMLCanvasElement, options?: EnsureBlobOptions): Promise<Blob>`
- `ensureBlobDetailed(source: ImageSource | HTMLCanvasElement, options?: EnsureBlobDetailedOptions): Promise<ResultBlob>`
- `ensureDataURL(source: ImageSource | HTMLCanvasElement, options?: EnsureDataURLOptions): Promise<string>`
- `ensureDataURLDetailed(source: ImageSource | HTMLCanvasElement, options?: EnsureDataURLDetailedOptions): Promise<ResultDataURL>`
- `ensureFile(source: ImageSource | HTMLCanvasElement, filename: string, options?: EnsureFileOptions): Promise<File>`
- `ensureFileDetailed(source: ImageSource | HTMLCanvasElement, filename: string, options?: EnsureFileDetailedOptions): Promise<ResultFile>`
- `estimateDataURLPayloadByteLength(dataURL: string, options?: EstimateDataURLPayloadByteLengthOptions): number | null`
- `estimateDataURLSize(dataURL: string): number`
- `fetchImageFormat(source: string, options?: FetchImageFormatOptions): Promise<ImageInfo['format']>`
- `fetchImageSourceBlob(source: string, options?: FetchImageSourceBlobOptions): Promise<FetchImageSourceBlobResult>`
- `formatToMimeType(format: ImageFormat | OutputFormat): string`
- `getImageAspectRatio(source: ImageSource): Promise<number>`
- `getImageDimensions(source: ImageSource): Promise<ImageDimensions>`
- `getImageFormat(source: ImageSource): Promise<ImageInfo['format']>`
- `getImageInfo(source: ImageSource): Promise<ImageInfo>`
- `getImageOrientation(source: ImageSource): Promise<ImageOrientation>`
- `getOutputFilename(filename: string, options?: OutputFilenameOptions): string`
- `hasTransparency(source: ImageSource | HTMLCanvasElement, options?: TransparencyOptions): Promise<boolean>`
- `isDataURLString(value: unknown): value is string`
- `isInlineSvg(source: string): boolean`
- `isSupportedOutputFormat(format: unknown): format is OutputFormat`
- `mimeTypeToImageFormat(mimeType: string): ImageFormatOrUnknown`
- `mimeTypeToOutputFormat(mimeType: string): OutputFormat | undefined`
- `replaceImageExtension(filename: string, format: OutputFormat): string`
- `resolveOutputFormat(preferred: OutputFormat, options?: ResolveOutputFormatOptions): OutputFormat`
- `const sanitizeSvg: typeof sanitizeSvgForRendering`
- `sanitizeSvgForRendering(svgString: string, depth?: number): string`
- `class SvgOptimizer { static getDefaultOptions(): SvgOptimizationOptions; static optimize(svgString: string, options?: SvgOptimizationOptions): { optimizedSvg: string; result: OptimizationResult; }; }`
- `sanitizeSvgStrict(svg: string, options?: StrictSvgSanitizerOptions): string`
- `sanitizeSvgStrictDetailed(svg: string, options?: StrictSvgSanitizerOptions): SanitizeSvgStrictDetailedResult`

## Usage Patterns
- Use `processImage(...)` for resize and output generation.
- The processing chain is lazy until an output method such as `toBlob()`, `toCanvas()`, `toDataURL()`, or `toFile()` is called.
- The main processing flow is async.
- Preset helpers return `Promise<ResultBlob>` directly.
- Utility functions are better for conversion, Data URL handling, source detection, metadata lookup, format resolution, transparency checks, or SVG sanitizing.
- Use `processImage(source, { svgSanitizer: 'strict' })` when untrusted SVG input should be sanitized only after the source is confirmed as SVG.
- Use the `@cp949/web-image-util/svg-sanitizer` subpath when you need explicit strict SVG sanitizing before processing.

## Examples
- `const blob = await processImage(file).resize({ fit: 'cover', width: 300, height: 200 }).toBlob({ format: 'webp', quality: 0.85 });`
- `const avatar = await createAvatar(file, { size: 128, format: 'png' });`
- `const safeSvg = sanitizeSvg(svgString);`
- `const strictBlob = await processImage(untrustedSvg, { svgSanitizer: 'strict' }).toBlob();`
- `const strictSvg = sanitizeSvgStrict(svgString);`
- `const blob = await convertToBlob(canvas);`
- `const info = await detectImageSourceInfo(file);`
- `const format = await fetchImageFormat('https://example.com/image-without-extension');`
- `const format = resolveOutputFormat('avif', { supported: ['webp', 'png'] });`

## Constraints
- Only use exported public APIs from the package root or exported subpaths.
- `resize()` should be used as a single resize step in one processing chain.
- `maxFit` and `minFit` require at least one of `width` or `height`.
- SVG input uses `svgSanitizer: 'lightweight'` by default; choose `'strict'` for untrusted SVG or `'skip'` only after trusted prior sanitizing.
- `unsafe_processImage()` is a compatibility escape hatch and is not the same as `svgSanitizer: 'skip'`.
- Source detection helpers and `getImageFormat()` do not fetch remote URLs; use `fetchImageFormat()` when URL body sniffing is required.
- This library targets browser environments with Canvas 2D API support.

## Anti-Patterns
- Do not invent unsupported chain methods such as `crop()`, `rotate()`, or `sharpen()`.
- Do not call `resize()` multiple times in the same chain.
- Do not rely on internal `dist/chunk-*` files or non-exported symbols.
- Do not describe this package as a Node.js image pipeline.

## Notes
- `createAvatar()` defaults to PNG-oriented avatar output.
- `createSocialImage()` applies platform-oriented sizing rules through `SocialImageOptions`.
- `sanitizeSvg()` removes dangerous SVG content, it does not rasterize the image by itself.
