Reading BMPs in C++ And Hints on Reading them using the Arduino Fatma Faruq,Department of Mechatronics, College of Electrical and Mechanical Engineering , NUST Reading/Writing In C++ • Use fstream – File Stream • Input File stream – ifstream • Output File stream – ofstream • Functions: • • • • • • open(filename) – open particular file is_open() – check if the file is open close() – close the file eof() – reached the end of file write(char array, num_char) – ofstream , write a chunk of data to file read(char array/buffer, num_char) – ifstream, read a chunk of data from file Fatma Faruq,Department of Mechatronics, College of Electrical and Mechanical Engineering , NUST Writing ofstream myfile("example.bin",ios::binary); unsigned char abyte = 'T'; unsigned char byteArray[] = "A byte array"; if (myfile.is_open()) { myfile << "This is a line.\n"; myfile << abyte; myfile << byteArray; myfile.write((char*)byteArray, sizeof(byteArray)); myfile.close(); } else cout << "Unable to open file"; Fatma Faruq,Department of Mechatronics, College of Electrical and Mechanical Engineering , NUST Reading unsigned char byte; if (byte == '\n') unsigned char byteArray[17] = {}; {myfile.read((char*)byteArray, 17); ifstream myfile("example.bin",ios::binary); for (int i = 0; i < 17; i++) if (myfile.is_open()) }} { myfile >> noskipws;//do not skip whitespace myfile.close();} while (!myfile.eof()) {myfile >> byte; cout << byteArray[i]; else cout << "Unable to open file"; cout << byte; Fatma Faruq,Department of Mechatronics, College of Electrical and Mechanical Engineering , NUST Reading/Writing a BMP Image • Open it in binary mode: ifstream in("grayimage.bmp", ios::binary); • Check if its open in.is_open() • Read one character: • somechar= in.get() • Close: in.close() • Open it in binary mode: ofstream out("myimage1.bmp", ios::binary); • Check if its open out.is_open() • Write one character: • out.put(somechar); • Close: out.close() Fatma Faruq,Department of Mechatronics, College of Electrical and Mechanical Engineering , NUST Source: Dr. Javaid Iqbal’s slides Reading/Writing a BMP Image #include <iostream> #include <fstream> if (in.is_open() && out.is_open()) int main(){ { //Open an input and output stream while (!in.eof()) in binary mode { out.put(in.get());} } ifstream in("grayimage.bmp", ios::binary); //Close both files ofstream out("myimage1.jpg", ios::binary); out.close(); in.close(); return 0; } Fatma Faruq,Department of Mechatronics, College of Electrical and Mechanical Engineering , NUST Source: Dr. Javaid Iqbal’s slides Reading the Header • Header Size = 54 bytes (generally) • Create a structure/class to store the information • Read byte by byte and convert into numbers BYTEs FUNCTION CALCULATION REMARKS Byte0 Byte1 Indicates validity of a BMP file X=Byte0+Byte1*256 If X=19778(decimal) then it a valid BMP file (byte0=66;byte1=77) 0x42 0x4D (Hex code for B and M) Byte2 Byte3 Byte4 Byte5 Indicate file size SIZE=Byte2+Byte3*256 +Byte4*256*256+Byte5*256*256*256 SIZE indicates file size in bytes Byte6 Byte7 Byte8 Byte9 Reserved Byte10 Byte11 Byte12 Byte13 Image offset or start of Data SOD=Byte10+Byte11* SOD indicates the byte from where the actual 256+Byte11*256*256+Byte13*256*256*2 data of image started 56 Fatma Faruq,Department of Mechatronics, College of Electrical Source: Dr. and Mechanical Engineering , NUST Javaid Iqbal’s slides Header File - BMP BYTEs FUNCTION CALCULATION REMARKS Byte14 Byte15 Byte16 Byte17 Header Size from this point H=Byte14+Byte15*256 +Byte16*256*256+Byte17*256*256*256 H indicates the Total size of the header in Bytes in the BMP file from this point. Usually it is 40. Byte18 Byte19 Byte20 Byte21 Image Width WIDTH=Byte18+Byte19*256+Byte20*256*256+ Byte21*256*256*256 WIDTH indicates width of image in pixels Byte22 Byte23 Byte24 Byte25 Image Height HEIGHT=Byte22+Byte23*256+Byte24*256*256 +Byte25*256*256*256 HEIGHT indicates Width of image in pixels Byte26 Byte27 Color plane CP=Byte26+Byte27*256 No of color planes being used Byte28 Byte29 Bits per Pixel BPP=Byte28 + Byte29*256 if BPP=1then image is monochrome, if BPP=4 then image is 16 color, if BPP=8 then image is 256 color, if BPP=16 then image is 64K color, if BPP=24 then image is 16 million color, Fatma Faruq,Department of Mechatronics, College of Electrical Source: Dr. and Mechanical Engineering , NUST Javaid Iqbal’s slides Header File - BMP Byte30 Byte31 Byte32 Byte33 Compression method CM=Byte30+Byte31* 256+Byte32*256*256+Byte33*256*256* 256 Byte34 Byte35 Byte36 Byte37 Size of Image S=Byte34+Byte35*256 +Byte36*256*256+Byte37*256*256*256 Specifies size of image (excluding header) in bytes or it can be calculated (width x height) of image. Byte38 Byte39 Byte40 Byte41 Horizontal Pixels per meter HPM=Byte38+Byte39*256+Byte40*256 *256+Byte41*256*256*256 Specifies the horizontal resolution, in Pixels per meter. Byte42 Byte43 Byte44 Byte45 Vertical Pixels per meter VPM=Byte42+Byte43*256+Byte44*256 *256+Byte45*256*256*256 Specifies the vertical resolution, in Pixels per meter. Fatma Faruq,Department of Mechatronics, College of Electrical and Mechanical Engineering , NUST Source: Dr. Javaid Iqbal’s slides Header File - BMP Byte46 Byte47 Byte48 Byte49 No of colors used by color pallet CU=Byte46+Byte47*256+Byte48*256*256+Byt e49*256*256*256 If this value is zero, the bitmap uses the maximum number of colors corresponding to the value of the byte28,29 Byte50 Byte51 Byte52 Byte53 No of important colors ICU=Byte50+Byte51* 256+Byte52*256*256+Byte53*256*256*256 If ICU=0 then all color are important, generally ignored. Byte54 Byte55 Byte56 Byte57 *Palette Byte54 = Blue Byte55 = Green Byte56 =Red Byte 57 = Reserve If SOD (start of data) is not equal to 54then it is the start of Palette till 1078th byte (Byte 1078) If SOD is 54 then it is the start of data Fatma Faruq,Department of Mechatronics, College of Electrical and Mechanical Engineering , NUST Source: Dr. Javaid Iqbal’s slides Reading the header • Open the file in binary mode for reading • Two options: • Read byte by byte – create an unsigned char , read upto 54 • Read an entire chunk – create an unsigned char array of size 54, read entire chunk • Convert to information • You can also create a structure and read the entire structure using read – you may end up with garbage due to difference in compilers, padding etc. Fatma Faruq,Department of Mechatronics, College of Electrical and Mechanical Engineering , NUST Reading the header in a char array int headerSizeF = 54; unsigned char* data = new unsigned char[headerSizeF]; ifstream file1; file1.open(fileName.c_str()); cout << "Reading header info" << endl; cout << "Hex Header" << endl; for (int i = 0; i<headerSizeF; i++) { file1 >> data[i]; // write the data at the screen. cout << hex << (int)data[i] << " "; } file1.close(); cout << endl; Fatma Faruq,Department of Mechatronics, College of Electrical and Mechanical Engineering , NUST Converting parts of that char array //header information int var = 0; imHeaderInfo *imheader = new imHeaderInfo; imheader->isValid = convertToDword(data[var + 1], data[var]); var += 2; imheader->fileSizeBytes = convertToDDword(data[var + 3], data[var + 2], data[var + 1], data[var]); var += 4; imheader->reserved = convertToDDword(data[var + 3], data[var + 2], data[var + 1], data[var]); var += 4; imheader->offset = convertToDDword(data[var + 3], data[var + 2], data[var + 1], data[var]); var += 4; imheader->headerSize = convertToDDword(data[var + 3], data[var + 2], data[var + 1], data[var]); Fatma Faruq,Department of Mechatronics, College of Electrical and Mechanical Engineering , NUST Converting to Dword or Double Dword int convertToDword(int high, int low) {return (high * 256 + low);} int convertToDDword(int highhigh, int high, int low, int lowlow) { return (highhigh * 256 * 256 * 256 + high * 256 * 256 + low * 256 + lowlow);} Fatma Faruq,Department of Mechatronics, College of Electrical and Mechanical Engineering , NUST Reading a File From an SD card Please note that the pin numbers may be different for your hardware. Fatma Faruq,Department of Mechatronics, College of Electrical and Mechanical Engineering , NUST Source:http://arduino.cc/en/Tutorial/ReadWrite Arduino SD Card Library • SD Card Library has two classes • SD Card Class • used to acces card and manipulate files and directories • File Class • used to read, write files Fatma Faruq,Department of Mechatronics, College of Electrical and Mechanical Engineering , NUST Programming using the SD Card Library • Include • #include <SD.h> • Checking for an SD Card • SD.begin(CSPIN) • returns true or false • Opening a file • SD.open(filename) • returns a File object Fatma Faruq,Department of Mechatronics, College of Electrical and Mechanical Engineering , NUST Reading a File • Declare File object • File myfile • Get object using SD.open • Check if the file has something to read • myfile.available() • Read file byte by byte • myfile.read() • returns byte read • Close File object • myfile.close() Fatma Faruq,Department of Mechatronics, College of Electrical and Mechanical Engineering , NUST Putting it all together #include <SD.h> File myFile; void setup() { // Open serial communications and wait for port to open: Serial.begin(9600); while (!Serial) { ; // wait for serial port to connect. Needed for Leonardo only } Serial.print("Initializing SD card..."); // On the Ethernet Shield, CS is pin 4. It's set as an output by default. // Note that even if it's not used as the CS pin, the hardware SS pin // (10 on most Arduino boards, 53 on the Mega) must be left as an output // or the SD library functions will not work. pinMode(10, OUTPUT); Fatma Faruq,Department of Mechatronics, College of Electrical and Mechanical Engineering , NUST Source:http://arduino.cc/en/Tutorial/ReadWrite Putting it all together if (!SD.begin(4)) { Serial.println("initialization failed!"); return; } Serial.println("initialization done."); // open the file. note that only one file can be open at a time, // so you have to close this one before opening another. myFile = SD.open("test.txt", FILE_WRITE); // if the file opened okay, write to it: if (myFile) { Serial.print("Writing to test.txt..."); myFile.println("testing 1, 2, 3."); // close the file: myFile.close(); Serial.println("done."); } else { // if the file didn't open, print an error: Serial.println("error opening test.txt"); } Fatma Faruq,Department of Mechatronics, College of Electrical and Mechanical Engineering , NUST Source:http://arduino.cc/en/Tutorial/ReadWrite Putting it all together // re-open the file for reading: myFile = SD.open("test.txt"); if (myFile) { Serial.println("test.txt:"); } // read from the file until there's nothing else in it: while (myFile.available()) { Serial.write(myFile.read()); } // close the file: myFile.close(); } else { // if the file didn't open, print an error: Serial.println("error opening test.txt"); } void loop() { // nothing happens after setup } Fatma Faruq,Department of Mechatronics, College of Electrical and Mechanical Engineering , NUST Source:http://arduino.cc/en/Tutorial/ReadWrite Functions in the File Class • • • • • • • • • • • • • • available() close() flush() peek() position() print() println() seek() size() read() write() isDirectory() openNextFile() rewindDirectory() Note: A directory is also a File class object Fatma Faruq,Department of Mechatronics, College of Electrical and Mechanical Engineering , NUST Functions in the SD Class • begin() • exists() • mkdir() • open() • remove() • rmdir() Fatma Faruq,Department of Mechatronics, College of Electrical and Mechanical Engineering , NUST Reading an Image - Hints • What is an image? • An image is a series of bytes • It has a header that you can use to get information: height, width, start of the pixel data • What is a monochrome image? • Pixels have values 0 or 1 • Important: • Consider alignment and padding Fatma Faruq,Department of Mechatronics, College of Electrical and Mechanical Engineering , NUST Hints - Reading a bitmap • • • • char *filename = "pic_mc.bmp"; Open the file: File photoFile = SD.open(filename); Check to see if its open: if (photoFile) { Go to an address and read a byte: • photoFile.seek(0xa); • offset = photoFile.read(); //go to location for offset • Read more than a byte and convert to suitable number: • photoFile.seek(0x12); • width = 0; • for (i = 0; i<4; i++) • {width += (photoFile.read() << (8*i)); } // or width+= photoFile.read()*(pow(256,i)); Fatma Faruq,Department of Mechatronics, College of Electrical and Mechanical Engineering , NUST Hints - Reading a bitmap • After reading the width and height, skip to the pixel array and read the entire array in a char array • Display this array in binary. • Remember image data is stored upside down. • These are just hints, there could be many ways to achieve the same purpose (better or worse) Fatma Faruq,Department of Mechatronics, College of Electrical and Mechanical Engineering , NUST About the NERC Map • Open it up in paint – size 56 by 96 • Match the pixels to the arena • • • • Identify the walls of the arena Identify the obstacles Identify the free path Map the image to the actual arena Fatma Faruq,Department of Mechatronics, College of Electrical and Mechanical Engineering , NUST Debugging and other tips • • • • • • • Use the serial monitor extensively Maybe code in c++ first to understand Think about the space you need to allocate Try to use as little space as possible Remember padding!! You can use the new and delete operators Make sure you read the bmp correctly • • • • Open up a hex editor Load your bmp file in the hex editor Examine the contents to get a better understanding Match the output of your code Fatma Faruq,Department of Mechatronics, College of Electrical and Mechanical Engineering , NUST
© Copyright 2024