Skip to content

Commit

Permalink
[ADD CONTENT] : Image representation and its storing formats (SRA-VJT…
Browse files Browse the repository at this point in the history
…I#88)

* Added content for image storing formats

includes : 
- cpp file containing the code to read from bitmap image and then store it to display, using sdl2 library
- images
- readme file explaining the theory

* Delete Image_storing_formats directory

* changed name convention according to the file structure

* fixed errors

* Solve display bug in image_representation

* Update Makefile to remove redundant "SDL2_image" linker flag
* Add proper implementation of SDL2 library to display correct
  size of image

* Solve the inverted image display bug

* This commit resolves the bug wherein image was displayed inverted.
* Two seperate struct "BitMapFileHeader" and "BitMapInfoHeader" is
  created to store the file type data and image information data.
* README.md has been modified to include more info about the different
  blocks in the bitmap image namely file data type, image information
  data , color pallete and raw raster data.

* Correct formating in the README.md

* Correct compiling commands in README.md

* modified readme format

Changes made :
- Removed the unnecessary linebreak wherever required.
- Seperated types of images from "some important terminologies" topic

* modified file structure

* updated readme

- Added proper path to asset images
- added correct command for run without make

* Delete assets/1_image_representation directory

---------

Co-authored-by: gautam-dev-maker <gautamnagrawal@gmail.com>
  • Loading branch information
2 people authored and Alqama Shaikh committed Mar 23, 2023
1 parent c4b0211 commit 50cacf6
Show file tree
Hide file tree
Showing 17 changed files with 476 additions and 0 deletions.
Empty file.
Empty file.
17 changes: 17 additions & 0 deletions 4_cv_basics/1_image_representation/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
CC = g++
CFLAGS = -Wall -Wextra -pedantic -std=c++11
LIBS = -lSDL2

SRCS = image_representation.cpp
OBJS = $(SRCS:.cpp=.o)
TARGET = image
all: $(TARGET)

$(TARGET): $(OBJS)
$(CC) $(CFLAGS) $(OBJS) -o $(TARGET) $(LIBS)

.cpp.o:
$(CC) $(CFLAGS) -c $< -o $@

clean:
$(RM) $(OBJS) $(TARGET)
302 changes: 302 additions & 0 deletions 4_cv_basics/1_image_representation/README.md

Large diffs are not rendered by default.

Binary file added 4_cv_basics/1_image_representation/assets/add.PNG
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added 4_cv_basics/1_image_representation/image.bmp
Binary file not shown.
Binary file added 4_cv_basics/1_image_representation/image1.bmp
Binary file not shown.
157 changes: 157 additions & 0 deletions 4_cv_basics/1_image_representation/image_representation.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
#include <iostream>
#include <fstream>
#include <vector>
#include <cstdint>
#include <SDL2/SDL.h>

// Pragma directives are used to control allignment of the padding.
// When reading the binary file, it is necessary to allign struct members in a meomory to avoid any misinterpretation.
// That is why, push is used to set the packing to 1 byte, so that the BMPHeader struct is packed with no padding
// and the pop is used to restore the default packing setting after the BMPHeader struct is defined.
// More about data padding and alignment can be found here: https://www.geeksforgeeks.org/structure-member-alignment-padding-and-data-packing/
#pragma pack(push, 1)

// structure to store the file type data
struct BitMapFileHeader
{
char file_type[2]; // "BM" (0x42, 0x4D)
uint32_t file_size; // Total size of the BMP file in bytes
uint16_t reserved1; // Unused (0)
uint16_t reserved2; // Unused (0)
uint32_t pixel_data_offset; // Offset to the start of the pixel data
};

// structure to store image information data
struct BitMapInfoHeader
{
uint32_t header_size; // Size of this header (40 bytes)
int32_t width; // Width of the image in pixels
int32_t height; // Height of the image in pixels
uint16_t planes; // Number of color planes (1)
uint16_t bits_per_pixel; // Number of bits per pixel (8 for grayscale)
uint32_t compression; // Compression method (0 for uncompressed)
uint32_t image_size; // Size of the raw image data (0 for uncompressed)
int32_t x_pixels_per_meter; // Horizontal resolution in pixels per meter
int32_t y_pixels_per_meter; // Vertical resolution in pixels per meter
uint32_t colors_used; // Number of colors used in the image, 0 means all colors are used
uint32_t colors_important; // Number of important colors used, 0 means all colors are important
};

// Define the BMPImage structure that contains the File Type Data, Image Information data and the pixel data
struct BMPImage
{
BitMapFileHeader header; // File Type Data
BitMapInfoHeader info; // Image Information Data
std::vector<uint8_t> data; // Raw Pixel Data
};
#pragma pack(pop)

// Main function
int main(int argc, char *argv[])
{
if (argc != 2)
{ // Check if the user provided an input file and return error message if file not found
std::cerr << "Usage: " << argv[0] << " <input_file.bmp>" << std::endl;
return 1;
}

// Read the BMP image from file
// open the input file using the filename passed in as an argument (stored in argv[1]).
std::ifstream infile(argv[1], std::ios::binary);
if (!infile)
{
std::cerr << "Error: Could not open input file: " << argv[1] << std::endl;
return 1;
}

// create a BMPImage object to hold the image data.
BMPImage image;

// read the BMP image file and store the size of BitMapFileHeader (14 bytes) in image.header
infile.read(reinterpret_cast<char *>(&image.header), sizeof(BitMapFileHeader));

// check if the first two bytes of the BMP header indicate that this is a BMP image (the signature 'BM'). If not, print an error message which returns 1.
if (image.header.file_type[0] != 'B' || image.header.file_type[1] != 'M')
{
std::cerr << "Error: Input file is not a BMP image" << std::endl;
return 1;
}

// Output image file type data to the console
std::cout << "\n-------------------- Bit Map File Header --------------------" << std::endl;
std::cout << "File type: " << image.header.file_type << std::endl;
std::cout << "File Size: " << image.header.file_size << std::endl;
std::cout << "Pixel Data Offset: " << image.header.pixel_data_offset << std::endl;
std::cout << "-------------------------------------------------------------\n" << std::endl;

// read the BMP image file and store the size of BitMapInfoHeader (40 bytes) in image.info
infile.read(reinterpret_cast<char *>(&image.info), sizeof(BitMapInfoHeader));
if (image.info.bits_per_pixel != 8)
{
std::cerr << "Error: Input file is not an 8-bit BMP image" << std::endl;
return 1;
}

int h = image.info.height;
int w = image.info.width;

// Output image attributes to console
std::cout << "-------------------- Bit Map Info Header --------------------" << std::endl;
std::cout << "Header Size: " << image.info.header_size << std::endl;
std::cout << "Width: " << image.info.width << std::endl;
std::cout << "Height: " << image.info.height << std::endl;
std::cout << "Planes: " << image.info.planes << std::endl;
std::cout << "Bits per pixel: " << static_cast<int>(image.info.bits_per_pixel) << std::endl;
std::cout << "Compression type: " << image.info.compression << std::endl;
std::cout << "Image Size: " << image.info.image_size << std::endl;
std::cout << "X pixels per meter: " << image.info.x_pixels_per_meter << std::endl;
std::cout << "Y pixels per meter: " << image.info.y_pixels_per_meter << std::endl;
std::cout << "Number of Colors Used: " << image.info.colors_used << std::endl;
std::cout << "Number of important colors: " << image.info.colors_important << std::endl;
std::cout << "-------------------------------------------------------------\n" << std::endl;

// if valid, the code allocates memory for the image data (the pixel values) by resizing the image.data vector to hold width x height elements.
image.data.resize(w * h);

// read the image data from the input file into the image.data vector
infile.read(reinterpret_cast<char *>(image.data.data()), image.data.size());

// To plot the data of each grayscale pixel fetched from the bitmap file, SDL2 library is used
SDL_Event event;
SDL_Renderer *renderer;
SDL_Window *window;
SDL_Init(SDL_INIT_VIDEO);

// Create a Window and Renderer component to display on screen
SDL_CreateWindowAndRenderer(w, h, 0, &window, &renderer);
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 0);
SDL_RenderClear(renderer);

// Plot each pixel on the screen based on its location
for (int i = 0; i < h; i++)
{
for (int j = 0; j < w; j++)
{
uint8_t k = image.data[j + i * h];
SDL_SetRenderDrawColor(renderer, k, k, k, 255);

// It is to be noted that SDL library follows botton left as the origin of the image
SDL_RenderDrawPoint(renderer, j, h - i - 1);
}
}

SDL_RenderPresent(renderer);

// keeping the window active till the quit button is pressed
while (1)
{
if (SDL_PollEvent(&event) && event.type == SDL_QUIT)
break;
}

// Free up the resources
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return EXIT_SUCCESS;
}
Empty file.

0 comments on commit 50cacf6

Please sign in to comment.