Generate srcset images for a variety of resolutions from OCaml
at main 122 lines 4.9 kB view raw
1(* Copyright (c) 2024, Anil Madhavapeddy <anil@recoil.org> 2 3 Permission to use, copy, modify, and/or distribute this software for 4 any purpose with or without fee is hereby granted, provided that the 5 above copyright notice and this permission notice appear in all 6 copies. 7 8 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 9 WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 10 WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 11 AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 12 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA 13 OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 14 TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 15 PERFORMANCE OF THIS SOFTWARE. *) 16 17(** Command-line image processing operations for srcsetter. 18 19 This module provides the core image processing pipeline including 20 file discovery, image conversion, and progress reporting. 21 22 {1 High-Level Pipeline} 23 24 The simplest way to use this module is via {!run}, which executes 25 the complete pipeline: 26 27 {[ 28 Srcsetter_cmd.run 29 ~proc_mgr:(Eio.Stdenv.process_mgr env) 30 ~src_dir:Eio.Path.(fs / "images/originals") 31 ~dst_dir:Eio.Path.(fs / "images/output") 32 () 33 ]} 34 35 {1 Configuration} *) 36 37(** Configuration for the image processing pipeline. *) 38type ('a, 'b) config = { 39 dummy : bool; (** When true, skip actual image conversion (dry run) *) 40 preserve : bool; (** When true, skip conversion if destination exists *) 41 proc_mgr : 'a Eio.Process.mgr; (** Eio process manager for running ImageMagick *) 42 src_dir : 'b Eio.Path.t; (** Source directory containing original images *) 43 dst_dir : 'b Eio.Path.t; (** Destination directory for generated images *) 44 img_widths : int list; (** List of target widths for responsive variants *) 45 img_exts : string list; (** File extensions to process (e.g., ["jpg"; "png"]) *) 46 idx_file : string; (** Name of the JSON index file to generate *) 47 max_fibers : int; (** Maximum concurrent conversion operations *) 48} 49 50(** {1 File Operations} *) 51 52val file_seq : 53 filter:(string -> bool) -> 54 ([> Eio.Fs.dir_ty ] as 'a) Eio.Path.t -> 55 'a Eio.Path.t Seq.t 56(** [file_seq ~filter path] recursively enumerates files in [path]. 57 58 Returns a sequence of file paths where [filter filename] is true. 59 Directories are traversed depth-first. *) 60 61val iter_seq_p : ?max_fibers:int -> ('a -> unit) -> 'a Seq.t -> unit 62(** [iter_seq_p ?max_fibers fn seq] iterates [fn] over [seq] in parallel. 63 64 @param max_fibers Optional limit on concurrent fibers. Must be positive. 65 @raise Invalid_argument if [max_fibers] is not positive. *) 66 67(** {1 Image Operations} *) 68 69val dims : ('a, 'b) config -> 'b Eio.Path.t -> int * int 70(** [dims cfg path] returns the [(width, height)] dimensions of an image. 71 72 Uses ImageMagick's [identify] command to read image metadata. *) 73 74val convert : ('a, 'b) config -> string * string * int -> unit 75(** [convert cfg (src, dst, size)] converts an image to WebP format. 76 77 Creates the destination directory if needed, then uses ImageMagick 78 to resize and convert the image with auto-orientation. 79 80 @param src Source filename relative to [cfg.src_dir] 81 @param dst Destination filename relative to [cfg.dst_dir] 82 @param size Target width in pixels *) 83 84val convert_pdf : 85 ('a, 'b) config -> 86 size:string -> 87 dst:'b Eio.Path.t -> 88 src:'b Eio.Path.t -> 89 unit 90(** [convert_pdf cfg ~size ~dst ~src] converts a PDF's first page to an image. 91 92 Renders at 300 DPI, crops the top half, and resizes to the target width. *) 93 94(** {1 Pipeline Execution} *) 95 96val run : 97 proc_mgr:'a Eio.Process.mgr -> 98 src_dir:'b Eio.Path.t -> 99 dst_dir:'b Eio.Path.t -> 100 ?idx_file:string -> 101 ?img_widths:int list -> 102 ?img_exts:string list -> 103 ?max_fibers:int -> 104 ?dummy:bool -> 105 ?preserve:bool -> 106 unit -> 107 Srcsetter.t list 108(** [run ~proc_mgr ~src_dir ~dst_dir ()] runs the full srcsetter pipeline. 109 110 Scans [src_dir] for images, converts them to WebP format at multiple 111 responsive sizes, and writes an index file to [dst_dir]. 112 113 @param proc_mgr Eio process manager for running ImageMagick 114 @param src_dir Source directory containing original images 115 @param dst_dir Destination directory for generated images 116 @param idx_file Name of the index file (default ["index.json"]) 117 @param img_widths List of target widths (default common responsive breakpoints) 118 @param img_exts List of extensions to process (default common image formats) 119 @param max_fibers Maximum concurrent operations (default 8) 120 @param dummy When true, skip actual conversions (default false) 121 @param preserve When true, skip existing files (default true) 122 @return List of {!Srcsetter.t} entries describing generated images *)