diff --git a/README.md b/README.md index 2ea804b..a2cd70f 100644 --- a/README.md +++ b/README.md @@ -16,15 +16,15 @@ go build 2. Run the command - ```bash - $ ./glitch_img - Usage: go run main.go - ``` +```bash +$ ./glitch_img +Usage: go run main.go +``` ### Example ```bash -./glitch*img img.jpeg 100 30 2 +./glitch_img img.jpeg 100 30 2 ``` Outputs 100 images into a destination folder _output_ with 30 random bytes of data, running through the file twice diff --git a/glitch.go b/glitch.go index 1cafb29..c4580f4 100644 --- a/glitch.go +++ b/glitch.go @@ -1,6 +1,7 @@ package main import ( + "fmt" "math/rand/v2" "os" "path/filepath" @@ -54,7 +55,47 @@ func glitchImage(inputFile string, outputFile string, shitSize int64, iterations _, err = destination.Write(shit) check(err, "failed to write shit data: %w") - // fmt.Printf("Successfully wrote %d bytes of shit at offset %d in file %s\n", shitSize, offset, outputFilePath) } return nil } + +func copyImage(inputFile string, outputFile string) error { + // Ensure the output directory exists + makeOutputDir() + + // Prepend the "output" directory to the output file + outputFilePath := filepath.Join("output", outputFile) + + // Open the source file for reading + source, err := os.Open(inputFile) + check(err, "failed to open source file: %w") + defer source.Close() + + // Create a new file for writing the copy + destination, err := os.Create(outputFilePath) + check(err, "failed to create output file: %w") + defer destination.Close() + + // Copy the contents of the source file to the destination + _, err = destination.ReadFrom(source) + check(err, "failed to copy file contents: %w") + + return nil +} + +func generateGlitchedSequence(inputFile string, totalImages int, shitSize int64, iterations int64) { + for i := 1; i <= totalImages; i++ { + outputFileName := fmt.Sprintf("img_glitched_%d.jpeg", i) // Generate unique filenames + + // Randomly decide whether to glitch or copy the image + if rand.Int32N(2) == 0 { + // Glitched image + err := glitchImage(inputFile, outputFileName, shitSize, iterations) + check(err, "failed to glitch image: %w") + } else { + // Normal image + err := copyImage(inputFile, outputFileName) + check(err, "failed to copy normal image: %w") + } + } +} diff --git a/glitch_img b/glitch_img index 7735a77..983c0f3 100755 Binary files a/glitch_img and b/glitch_img differ diff --git a/main.go b/main.go index 0962869..30643f4 100644 --- a/main.go +++ b/main.go @@ -2,13 +2,16 @@ package main import ( "fmt" + "math/rand" "os" "os/exec" - "path/filepath" "strconv" + "time" ) func main() { + rand.Seed(time.Now().UnixNano()) + if len(os.Args) < 5 { fmt.Println("Usage: go run main.go ") return @@ -29,23 +32,61 @@ func main() { iterations, err := strconv.ParseInt(os.Args[4], 10, 8) - for i := 1; i <= numCopies; i++ { - outputFile := fmt.Sprintf("%s_glitched_%d%s", - stripExtension(sourceFile), - i, - filepath.Ext(sourceFile), - ) + /* + for i := 1; i <= numCopies; i++ { + outputFile := fmt.Sprintf("%s_glitched_%d%s", + stripExtension(sourceFile), + i, + filepath.Ext(sourceFile), + ) - err := glitchImage(sourceFile, outputFile, shitSize, iterations) - if err != nil { - fmt.Printf("Error glitching file %d: %v\n", i, err) + err := glitchImage(sourceFile, outputFile, shitSize, iterations) + if err != nil { + fmt.Printf("Error glitching file %d: %v\n", i, err) + } } - } + */ + generateGlitchedSequence(sourceFile, numCopies, shitSize, iterations) + + inputPattern := "./output/img_glitched_%d.jpeg" + outputVideo := "output.mp4" + + cmd := exec.Command( + "ffmpeg", + "-y", + "-framerate", "30", + "-i", inputPattern, + "-vf", "scale=trunc(iw/2)*2:trunc(ih/2)*2,setpts=PTS*2.0", // Scale and slow down playback + "-vcodec", "libx264", // Use H.264 codec + "-pix_fmt", "yuv420p", + "-crf", "23", // Compression level: lower is higher quality (range: 18-28) + "-preset", "fast", + outputVideo, + ) - fmt.Println("GENREATING GIF YEAHH ") - // now run ffmpeg to make a gif! - cmd := exec.Command("ffmpeg", "-y", "-framerate 60", "-i", "./output/img_glitched_%d.jpeg output.gif") - err = cmd.Run() - check(err, "cannot run ffmpeg command!") + done := make(chan bool) + + go func() { + err := cmd.Run() + check(err, "cannot run ffmpeg command!") + done <- true + }() + + go func() { + msg := "Generating MP4" + c := 0 + for { + select { + case <-done: + return + default: + fmt.Printf("\r%s%s", msg, dots(c)) + c = (c + 1) + time.Sleep(500 * time.Millisecond) + } + } + }() + <-done + fmt.Println("\nGIF successfully created in ./output.mp4!") // } diff --git a/util.go b/util.go index 895ceba..e397a8a 100644 --- a/util.go +++ b/util.go @@ -11,6 +11,14 @@ func check(e error, s string) { } } +func dots(count int) string { + dotStr := "" + for i := 0; i < count; i++ { + dotStr += "." + } + return dotStr +} + func stripExtension(filename string) string { ext := filepath.Ext(filename) return filename[:len(filename)-len(ext)]