1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
|
#include <fstream>
#include "bitmap.h"
#include "bitmapInfoHeader.H"
#include "bitmapFileHeader.H"
#include <iostream>
#include <cstdint> // For unsigned
using namespace std;
namespace caveofprogramming
{// Curly brackets at the end of m_pixels initiallizes it to all zero
Bitmap::Bitmap(int width, int height) : m_width(width), m_height(height), m_pixels(new uint8_t[height * width * 3]{}) // Every pixel has 3 bytes
{
}
// We're creating a bitmap, setting pixels in it and writing to it with this function.
// Writing to files is errror prone, so we'll make it bool to return false if it does'nt work.
bool Bitmap::write(string fileName)
{
BitmapFileHeader fileHeader;
BitmapInfoHeader infoHeader;
fileHeader.fileSize = sizeof(BitmapFileHeader) + sizeof(BitmapInfoHeader) + m_width * m_height * 3;
// Distance from beginning of file to where data actually starts.
fileHeader.dataOffSet = sizeof(BitmapFileHeader) + sizeof(BitmapInfoHeader);
infoHeader.width = m_width;
infoHeader.height = m_height;
ofstream file;
file.open(fileName, ios::out | ios::binary);
if (!file) {
cout << "File not open." << endl;
return false;
}
// First arg always has to be a char star ptr to the address of the struct (or class).
file.write((char*)&fileHeader, sizeof(fileHeader));
file.write((char*)&infoHeader, sizeof(infoHeader));
// Can't cast a unique ptr (m_pixels) to a char * so need the get() method to return it as a regular ptr.
file.write((char*)m_pixels.get(), m_width*m_height*3);
file.close();
if (!file) {
return false;
}
return true;
}
Bitmap::~Bitmap()
{
}
// Allows us to set pixels in a bitmap to specify colors. There is one byte of info for each pixel.
// x and y are used to specify a particular pixel.
void Bitmap::setPixel(int x, int y, uint8_t red, uint8_t green, uint8_t blue) // Unsigned 8 bit char 0 - 255.
{
// Pointer to a particular pixel specified by x and y.
uint8_t* pixel = m_pixels.get(); //Can't assign a unique pointer to a regualr pointer, but we can with the get() method.
// y * m_width is th number of pixels in each byte (if each pixel is one byte) in all the rows before the
// one we are intersted in as specified by y. Once we get it in the right row, we then move it forward
// to the correct column with x. Since each pixel is taking up 3 bytes we have to mult x and y by 3.
// If we add the value one to this ptr that would move it forward by one byte.
pixel += (y * 3) * m_width + (x * 3);
// We can now use the array subscipts to reference the red, blue, and green bytes following the one
// that ptr "pixel" points at.
pixel[0] = blue;
pixel[1] = green;
pixel[2] = red;
// Hexadecimal number: FF for red, 88 for blue, 33 for green. Takes exactly 3 bytes; 3 digits for each number.
// The last digits in a hexadecimal number represent the first area in memory.
0xFF8833;
}
}
| |