Last active
December 13, 2023 23:19
-
-
Save mshafae/80d95db3aeb0de7d181440ce47f32a36 to your computer and use it in GitHub Desktop.
CPSC 120 Example of creating an animated gif using Graphics Magick.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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