diff --git a/AGENTS.md b/AGENTS.md index cf787af..0790263 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -28,7 +28,7 @@ This is the main way people contribute. Add one shop end to end. } ``` -3. **Photo** — must be **under 300KB**, EXIF-stripped, longest side ~800px, named `{shopId}-001.jpg` (`-002`, … for more). Use the helper (macOS `sips` + `jpegtran`): +3. **Photo** — must be **under 300KB**, EXIF-stripped, longest side ~800px, named `{shopId}-001.jpg` (`-002`, … for more). Use the helper (macOS `swift` + `sips` + `jpegtran`; it also applies the EXIF orientation so photos stay upright): ```sh mkdir -p content/shops/{shopId} diff --git a/tools/resize.sh b/tools/resize.sh index e7803d0..1b94cf7 100755 --- a/tools/resize.sh +++ b/tools/resize.sh @@ -12,6 +12,6 @@ new_path=$2 echo "Move: $org_path to $new_path" mv $org_path $new_path echo "Resize and Optimize: $new_path" -sips -Z 800 $new_path +swift "$(dirname "$0")/resize.swift" $new_path $new_path jpegtran -copy none -optimize -outfile $new_path $new_path sips -g pixelHeight -g pixelWidth $new_path diff --git a/tools/resize.swift b/tools/resize.swift new file mode 100644 index 0000000..14e1405 --- /dev/null +++ b/tools/resize.swift @@ -0,0 +1,29 @@ +import Foundation +import ImageIO + +let args = CommandLine.arguments +guard args.count == 3 else { + FileHandle.standardError.write("Usage: swift resize.swift input.jpg output.jpg\n".data(using: .utf8)!) + exit(1) +} + +let options = [ + kCGImageSourceCreateThumbnailFromImageAlways: true, + kCGImageSourceCreateThumbnailWithTransform: true, + kCGImageSourceThumbnailMaxPixelSize: 800, +] as CFDictionary + +guard let source = CGImageSourceCreateWithURL(URL(fileURLWithPath: args[1]) as CFURL, nil), + let image = CGImageSourceCreateThumbnailAtIndex(source, 0, options), + let destination = CGImageDestinationCreateWithURL( + URL(fileURLWithPath: args[2]) as CFURL, "public.jpeg" as CFString, 1, nil) +else { + FileHandle.standardError.write("Failed to resize \(args[1])\n".data(using: .utf8)!) + exit(1) +} + +CGImageDestinationAddImage(destination, image, nil) +guard CGImageDestinationFinalize(destination) else { + FileHandle.standardError.write("Failed to write \(args[2])\n".data(using: .utf8)!) + exit(1) +}