Skip to content

Instantly share code, notes, and snippets.

@BradB132
Created November 12, 2023 15:28
Show Gist options
  • Save BradB132/13c1ee364a75eb242730bdcdbde3b560 to your computer and use it in GitHub Desktop.
Save BradB132/13c1ee364a75eb242730bdcdbde3b560 to your computer and use it in GitHub Desktop.
#!/usr/bin/swift
/*
* Command line script that draws an evenly spaced grid over an image and labels each grid square.
*/
import Foundation
// Function to run a shell command and capture the output
func runShellCommand(_ command: String, printCommand: Bool) -> Int32 {
if (printCommand) {
print("RUNNING SHELL COMMAND:\n\(command)")
}
let process = Process()
process.launchPath = "/bin/zsh"
process.arguments = ["-c", command]
let pipe = Pipe()
process.standardOutput = pipe
process.launch()
_ = pipe.fileHandleForReading.readDataToEndOfFile()
return process.terminationStatus
}
func A1Z26(_ digit: Int) -> String {
guard digit >= 1 && digit <= 26 else {
return "?"
}
let asciiValue = UInt8(digit - 1) + UInt8(Character("A").asciiValue!)
return String(UnicodeScalar(asciiValue))
}
guard runShellCommand("which convert", printCommand: false) == 0 else {
print("This script is dependent on the `convert` tool. You can install this by running `brew install imagemagick`.")
exit(1)
}
guard CommandLine.arguments.count == 6 else {
print("Usage: \(CommandLine.arguments[0]) <inputImagePath> <imageWidth> <imageHeight> <horizontalSlices> <verticalSlices>")
exit(1)
}
let inputFileURL = URL(fileURLWithPath: CommandLine.arguments[1])
guard inputFileURL.isFileURL else {
print("Invalid input file path.")
exit(1)
}
guard let imageWidth = Int(CommandLine.arguments[2]), imageWidth > 0 else {
print("Invalid image width.")
exit(1)
}
guard let imageHeight = Int(CommandLine.arguments[3]), imageHeight > 0 else {
print("Invalid image height.")
exit(1)
}
guard let horizontalSlices = Int(CommandLine.arguments[4]), horizontalSlices > 0 else {
print("Invalid horizontal slices.")
exit(1)
}
guard let verticalSlices = Int(CommandLine.arguments[5]), verticalSlices > 0 else {
print("Invalid vertical slices.")
exit(1)
}
let outputFileNameWithSuffix = inputFileURL.deletingPathExtension().lastPathComponent + "_grid"
let outputFileURL = inputFileURL.deletingLastPathComponent().appendingPathComponent(outputFileNameWithSuffix).appendingPathExtension(inputFileURL.pathExtension)
let textSize = 24
var drawInstructions = ""
let horizontalSliceSize = Float(imageWidth) / Float(horizontalSlices)
let verticalSliceSize = Float(imageHeight) / Float(verticalSlices)
for i in 0..<horizontalSlices {
let x = Int(horizontalSliceSize * Float(i))
drawInstructions += "-draw 'line \(x),0 \(x),\(imageHeight)' "
for j in 0..<verticalSlices {
let y = Int(verticalSliceSize * Float(j))
drawInstructions += "-draw \"text \(x),\(y+textSize) '\(A1Z26(j+1))\(i+1)'\" "
}
}
for i in 1..<verticalSlices {
let y = Int(verticalSliceSize * Float(i))
drawInstructions += "-draw 'line 0,\(y) \(imageWidth),\(y)' "
}
_ = runShellCommand("convert \(inputFileURL.path) -fill none -stroke red -pointsize \(textSize) \(drawInstructions)\(outputFileURL.path)", printCommand: true)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment