Question
The goal of this lab is to load, manipulate, and save jpg image files. Instead of writing our own jpeg routines, we will use the
The goal of this lab is to load, manipulate, and save jpg image files. Instead of writing our own jpeg routines, we will use the single-file public domain libraries for C/C++ that provide basic image read/write functionality.
$ git clone https://github.com/nothings/stb.git
or you can also get it fromhere.
The following file showcases how you will be able to use these files to read/write jpeg file.
#include#include #define STB_IMAGE_IMPLEMENTATION #define STB_IMAGE_WRITE_IMPLEMENTATION #include "stb/stb_image.h" #include "stb/stb_image_resize.h" #include "stb/stb_image_write.h" using namespace std; int main() { int width, height, channels; unsigned char* img = stbi_load("apple.jpg", &width, &height, &channels, 0); if (img == 0) { cout << "Error loading image file" << endl; return -1; } cout << "Loading image "; cout << "\twidth = " << width << " "; cout << "\theight = " << height << " "; cout << "\tchannels = " << channels << " "; stbi_write_jpg("apple-copy.jpg", width, height, channels, img, 100); stbi_image_free(img); return 0; }
We can compile this file using
$ g++ main.cpp -o foo
It assumes that STB header files are available in the stb folder as seen below.
$ tree -L 1 . . apple.jpg bambi.jpg main.cpp stb LICENSE README.md data deprecated docs stb.h stb_c_lexer.h stb_connected_components.h stb_divide.h stb_ds.h stb_dxt.h stb_easy_font.h stb_herringbone_wang_tile.h stb_image.h stb_image_resize.h stb_image_write.h stb_include.h stb_leakcheck.h stb_perlin.h stb_rect_pack.h stb_sprintf.h stb_textedit.h stb_tilemap_editor.h stb_truetype.h stb_vorbis.c stb_voxel_render.h stretchy_buffer.h tests tools
Loading jpeg files
The following lines
int width, height, channels; unsigned char* img = stbi_load("apple.jpg", &width, &height, &channels, 0 /* desired number of channels = 0 */); if (img == 0) { cout << "Error loading image file" << endl; return -1; }
load image data int anunsigned char*buffer. The function also returns the width, height, and the number of channels of an image. Color images are typically stored as RedGreenBlue, so these have 3 channels. The total size of data iswidth*height*channels. The function returns a 0 if it is unable to read in the file.
Writing jpeg files
The following lines
stbi_write_jpg("apple-copy.jpg", width, height, channels, img, 100 /* quality = 100 */);
Save img data to a jpeg file. It requires the width, height, number of channels, plus the buffer containing image data.
Image buffer
Functionstbi_loadreturns a pointer to anunsigned char*buffer. The size of this buffer iswidth * height * channels. The image data is stored in the buffer in row order, i.e., the firstwidth * channelsbytes belong to the first row of image. The following code sets the first 10 rows of the input image to black.
// Lets set the first 10 rows to black for (unsigned char* p = img; p != img + 10*width*channels; p += channels) { *p = (uint8_t) 0; *(p+1) = (uint8_t) 0; *(p+2) = (uint8_t) 0; }
Image layout is illustrated below.
Tasks
Goal 1 [50%]
Complete the following code that creates a noisy image. Specifically, it sets 20% of image pixels to black. The pixels locations are randomly generated.
#include#include #define STB_IMAGE_IMPLEMENTATION #define STB_IMAGE_WRITE_IMPLEMENTATION #include "stb/stb_image.h" #include "stb/stb_image_resize.h" #include "stb/stb_image_write.h" using namespace std; void create_a_random_pixel_location(int width, int height, int& r, int &c) { // TO DO } // // Image structure // struct MyImg { unsigned char* data; int width; int channels; int height; std::string filename; }; void print_img_info(MyImg* img) { cout << "width = " << img->width << " " << "height = " << img->height << " " << "channels = " << img->channels << endl; } void delete_img(MyImg** img) { // Deletes img and sets it to NULL // // TO DO } // // Image read/write // MyImg* load_jpeg_file(const string& filename) { // Returns a MyImg pointer containing image data. // If the file loading is unsuccessful, it returns a 0 // // TO DO return 0; } void save_to_jpeg_file(const string& filename, MyImg* img) { // Saves to a jpeg file // // TO DO } // // Setters // void set_pixel_red(MyImg* img, int r, int c, uint8_t val) { // TO DO } void set_pixel_green(MyImg* img, int r, int c, uint8_t val) { // TO DO } void set_pixel_blue(MyImg* img, int r, int c, uint8_t val) { // TO DO } // // Getters // uint8_t get_pixel_red(MyImg* img, int r, int c) { // TO DO } uint8_t get_pixel_green(MyImg* img, int r, int c) { // TO DO } uint8_t get_pixel_blue(MyImg* img, int r, int c) { // TO DO } // // The main function // int main() { MyImg* img = load_jpeg_file("apple.jpg"); int total_pixels = img->width * img->height; // Set 20% of the total_pixels to black // Save results to apple-noisy.jpg // Memory cleanup return 0; }
The following images show the input image and the noisy image.
Goal 2 [35%]
A function that picks a subregion from the image. The function will have the following signature.
MyImg* get_subregion(MyImg* src, int top, int left, int bottom, int right)
When we use this function as follows
MyImg* img2 = get_subregion(img, 50, 5, 250, 250); save_to_jpeg_file("apple-resized.jpg", img2);
we get the following
You can allocate a new image of widthwand heighthusingmallocas seen below
unsigned char* data = malloc(w*h*3);
You can still usestbi_image_free(data)to release the allocated image data.
Goal 3 [15%]
A function that flips an image in place (i.e., the image passed to it is flipped).
void flip(MyImg* img, int dir);
If dir is 1, the image is flipped horizontally (left below), and if it is 0, the image is flipped vertically (right below).
main2.cppfile, for example, flips the image vertically
... MyImg* img = load_jpeg_file("apple.jpg"); flip(img, 0); save_to_jpeg_file("apple-up-down.jpg", img); ...
Similarly,main3.cppfile will flip the image horizontally
... MyImg* img = load_jpeg_file("apple.jpg"); flip(img, 1); save_to_jpeg_file("apple-left-right.jpg", img); ...
Step by Step Solution
There are 3 Steps involved in it
Step: 1
Get Instant Access to Expert-Tailored Solutions
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started