Skip to content

Instantly share code, notes, and snippets.

@mshafae
Last active December 13, 2023 23:19
Show Gist options
  • Save mshafae/80d95db3aeb0de7d181440ce47f32a36 to your computer and use it in GitHub Desktop.
Save mshafae/80d95db3aeb0de7d181440ce47f32a36 to your computer and use it in GitHub Desktop.
CPSC 120 Example of creating an animated gif using Graphics Magick.
// Gist https://gist.github.com/mshafae/80d95db3aeb0de7d181440ce47f32a36
// Filename cpsc120_animated_image.cc
// CompileCommand clang++ -std=c++17 -I /usr/include/GraphicsMagick cpsc120_animated_image.cc -lGraphicsMagick++ -lGraphicsMagick
// Create a simple, small image from a given filename. GraphicsMagick
// will figure out how to output to the given file format.
// Supported formats: http://www.graphicsmagick.org/formats.html
// Example:
// clang++ -std=c++17 -I /usr/include/GraphicsMagick cpsc120_animated_image.cc -lGraphicsMagick++ -lGraphicsMagick
// ./a.out my_image.jpg
// ./a.out my_image.png
#include <Magick++.h>
#include <cmath>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
bool HasMatchingFileExtension(const std::string& file_name,
const std::string& extension) {
return file_name.size() >= extension.size() &&
file_name.compare(file_name.size() - extension.size(),
extension.size(), extension) == 0;
}
int main(int argc, char* argv[]) {
// Set these to whatever dimensions you want the output image to be.
// Warning: don't make this too big or your program will take a long time
// to execute.
const int kImageWidth{512};
const int kImageHeight{512};
const int kNumberOfImages{7};
// This initializes the image library we are using.
Magick::InitializeMagick(*argv);
std::vector<std::string> args{argv, argv + argc};
if (args.size() < 2) {
std::cout << "Please provide a path to a file.\n";
std::cout << "For example: " << args.at(0) << " my_image.jpg\n";
return 1;
}
std::string output_file_name;
output_file_name = args.at(1);
// We must use the gif output format because we are making an animation.
std::string image_format{".gif"};
if (!HasMatchingFileExtension(output_file_name, image_format)) {
std::cout << output_file_name << " is missing the required file extension "
<< image_format << ".\n";
return 1;
}
// A vector to hold each image we generate.
std::vector<Magick::Image> images;
double blue_step = M_PI / double(kNumberOfImages);
double red_step = M_PI / double(kImageWidth);
int row_col_step = kImageWidth / kNumberOfImages;
for(int image_index = 0; image_index < kNumberOfImages; image_index++){
// Colors are defined with three channels: Red, Green, Blue.
// The value for each channel is a floating point number between 0 and 1.
// Black is all 0 values and white is all 1 values.
Magick::ColorRGB white(1, 1, 1);
Magick::Image current_image(Magick::Geometry(kImageWidth, kImageHeight), white);
double blue = sin(blue_step * image_index);
for (int row = 0; row < current_image.rows(); row++) {
for (int column = 0; column < current_image.columns(); column++) {
int current_step = (image_index * row_col_step);
double red{double(column) / double(current_image.columns() - 1)};
double green = cos(double(row + current_step) / double(current_image.rows() - 1));
Magick::ColorRGB color{red, green, blue};
// We set the pixel to the color we just created. The pixel
// is located at (column, row)
current_image.pixelColor(column, row, color);
}
}
images.push_back(current_image);
}
Magick::writeImages(images.begin(), images.end(), output_file_name);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment