I have a float buffer with the data of the ppm file. The buffer[0][0] is the 1st element and the buffer[3*width*height][0] is the last element of the data.
Buffer has elements like this. 1st = 117 2st= 135 3st = 122. It's red, green and blue.
The point is to write this data into a binary file!
I try this, getHeight() returns the Height and getWidth() the width of the data.
ofstream output(filename, ios::out | ios::binary);
output.write((char *)buffer, img.getHeight() * img.getWidth() * 3);
Also i try this, for i=0 to i=3*height*width
fp = fopen(filename, "wb");
fwrite(reinterpret_cast<char*>(&buffer[i][0]), 1, 3*height*width, fp);
A float is 4 bytes each.
fwrite() doesn't know of the type you're writing, so for the size, you need to also multiply by the size of each element.
fwrite(reinterpret_cast<char*>(&buffer[i][0]), 1, 3*height*width * sizeof(float), fp);
#include <iostream>
#include <fstream>
#include <iomanip>
using namespace std;
int main() {
ofstream out("blah.txt");
float val = 10.0f;
out << fixed << setprecision(5) << val << endl;
out.close();
return 0;
}
Related
i am trying to read and write a bmp file in c++.output file is created but is not opening and it's size is 257kb whereas the input file is 258kb.i first read and write the 14 byte header file,40 byte imageheader file,then the 512*512 pixels,here's my code,can anyone help please
#include <iostream>
#include <fstream>
#include <cmath>
using namespace std;
int main()
{
ifstream iFile;
char ch;
iFile.open("lena.bmp",ios::binary);
ofstream oFile;
oFile.open("lena3.bmp",ios::binary);
//int headerImageHeader=54;
// int imageHeader=40;
int fs[54];
//int ihs[imageHeader];
int tfs[54];
int pixel[512][512];
if(iFile.is_open() && oFile.is_open())
{
for(int i=0;i<54;i++)
{
iFile.get(ch);
fs[i]=ch;
cout<<fs[i]<<" ";
char p;
p=fs[i];
oFile<<p;
}
for(int w=0;w<512;w++)
{
for(int h=0;h<512;h++)
{
iFile.get(ch);
pixel[w][h]=ch;
//cout<<pixel[w][h]<<;
char pi=pixel[w][h];
oFile<<pi;
}
}
oFile.close();
iFile.close();
}
else cout << "Unable to open file"<<endl;
return 0;
}
Your code has multiple problems. Basically, the pixel storage in BMP file is not that simple. It depends on the type of BMP (e.g. Monochrome Bitmap, 16 Color Bitmap, 256 Color Bitmap and 24-bit Bitmap etc).
There are two options to read one Bitmap file and write it in another Bitmap file.
a) Read each byte from the source file and write in destination file
b) Understand Bitmap storage format and write code accordingly.
For option b) good source is available at wiki.
In summary, the calculation of Pixel Array storage (size) is:
PixelArraySize = RowSize x ImageHeight
Where ImageHeight is height of image in pixel. The RowSize is calculated as:
RowSize = [(BitsPerPixelxImageWidth + 31) / 32 ]x4
I'm new to C++, so this should be a fairly basic question.
Assume I have bunny.voxel.ply file. This file is written out in binary, with the first 4 bytes corresponding to the (integer) sampling resolution, res, and the next 4 x res x res x res bytes corresponding to the (single precision) floating point values.
I want to read these values into 3D array voxel. My current code:
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
int main() {
FILE* fp = fopen( "bunny.voxel.ply" , "rb" );
if (fp==NULL) {fputs ("File error",stderr); exit (1);}
int res;
fread( &res , 1 , sizeof(int) , fp );
float *voxel = new float[res*res*res];
fread(voxel , res * res * res , sizeof(float) , fp );
fclose( fp );
std::cout << "Hello, World!" << std::endl;
return 0;
}
seems to only read the last value.
Any suggestions on how I can modify this read all values?
The Parameters of fread are
size_t fread(void *ptr, size_t size, size_t count, FILE *stream);
Thus you probably should exchange the order of your 2nd and 3rd parameter:
int count = res*res*res;
float *voxel = new float[count];
fread(voxel, sizeof(float), count, fp);
By accident the last value was in the correct memory position so that you could identify it.
I am having the matlab code to read binary data:
**nfft = 256;
navg = 1024;
nsamps = navg * nfft;
f_s = 8e6;
nblocks = floor(10 / (nsamps / f_s));
for i = 1:nblocks
nstart = 1 + (i - 1) * nsamps;
fid = fopen('data.dat'); % binary data and 320 MB
fseek(fid,4 * nstart,'bof');
y = fread(fid,[2,nsamps],'short');
x = complex(y(1,:),y(2,:));
end**
it will give me complex data with the length up to 8e6.
I am trying to write C++ to do the same function what matab does, but I could not get all the data or they are not the same original.
Can anyone help for ideals?
Here is my C++ code which I am working on.
Thank you so much.
#include <cstdio>
#include <cstring>
#include <iostream>
#include <complex>
#include <vector>
#include <stdlib.h>
struct myfunc{
char* name;
};
int main() {
FILE* r = fopen("data.bin", "rb");
fread( w, sizeof(int), 30, r);
fread(&c, sizeof(myfunc),1,r);
for(int i=0; i < 30; i++){
cout<< i << ". " << w[i] << endl;
}
return 0;
}
Based on comment
the c I called from the struct myfunc and the w is the vector. so they are will be : int w[40]; myfunc c;
fread(&c, sizeof(myfunc),1,r);
will read one pointer's worth of data from file stream r into c. This will not be particularly useful as whatever address myfunc.name pointed at when the file was written will almost certainly be invalid when the file is read back.
Solution: Serialize myfunc.name when writing to the file and deserialize it when reading. Insufficient information is in the question to suggest how best to do this. I would store the string Pascal style and prepend the length of myfunc.name to make reading it back easier:
int len = strlen(myfunc.name);
fwrite(&len, sizeof(len), 1, outfile); // write length
fwrite(myfunc.name, len, 1, outfile); // write string
and read it
int len;
fread(&len, sizeof(len), 1, infile); // read length
myfunc.name = new char[len+1]; // size string with space for terminator
fwrite(myfunc.name, len, 1, infile); // read string
myfunc.name[len] = '\0'; // terminate string
Note the above code completely ignores endian and error handling.
I am reading H.264 bitstream as Hex file in c++. I want to insert some string whenever some certain condition met.Like in the attached image if hex value of 00 00 00 01 occurs anywhere in the file i want to add some string like ABC before 00 00 00 01 in the file and save this as a new file. Write now my approach is to read h.264 file as hex. convert it into string and make a string comparison. if there is a way i can do a straight hex comparison? Here is my current code
#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <iomanip>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
unsigned char x;
string s1,s2,s3;
s2="Mushahid Hussain";
s3="0000000141";
std::ifstream input("d:\\Jm\\videos\\trying2.264", std::ios::binary);
input >> std::noskipws;
while (input >> x) {
long constant = 0x0000000168;
std::ostringstream buffer;
buffer << std::hex << std::setw(2) << std::setfill('0')
<< (int)x;
s1=buffer.str();
if (s1.find(s1) != std::string::npos) {
cout<<"hello";
s1+=s2;
}
std::ofstream outfile;
outfile.open("d:\\Jm\\bin\\trying5.264", std::ios_base::app);
outfile << s1;
}
return 0;
}
Edit 1
As answered by Tommylee2k i am able to append string . But problem is that at the end of file hex CD value is appending like shown in the attached image.
perhaps a better approach is to read the file binary into a memory buffer, and find the memcmp() instead.
When you found your pattern, you write the block ahead of the match, then your "ABC"-string, and continue searching the rest of the file
#include <stdio.h>
#include <string.h>
#include <memory.h>
#include <malloc.h>
char pattern[4]= { 0x00,0x00,0x01,0x67 };
char *memfind(char *s, int len, char *p, int plen) {
int n=0;
char *pos = s;
while ((pos-s)<(len-plen)) {
while ( *(pos+n) == *(p+n) && n<=plen) n++;
if (n==plen)
return pos;
pos++;n=0;
}
return NULL;
}
int main() {
FILE *in = fopen("in.vid", "r+");
FILE *out = fopen("out.vid", "wb");
// get Filesize
size_t size = 0;
fseek(in, 0L, SEEK_END);
size = ftell(in);
// read whole file in
char *buffer = malloc(size);
fseek (in, 0L, SEEK_SET);
fread (buffer, size, 1, in);
char *currentPos = buffer;
char *found;
if (buffer) {
while (1) {
found = memfind(currentPos, size-(currentPos-buffer), pattern, sizeof(pattern));
if (found==NULL) break;
fwrite(currentPos, 1, (size_t) (found-currentPos), out);
fwrite("ABC", sizeof("ABC"), 1, out);
fwrite(pattern, sizeof(pattern),1,out);
currentPos=found+4;
}
fwrite (currentPos, 1, (size_t) size - (currentPos-buffer), out);
free(buffer);
}
fclose (in);
fclose (out);
return 0;
}
I'm new to C++ and programming. I have the following flawed code to read from a BMP file and Write to another BMP file. I did not want to use any external libraries.
I have an 800kb 24bit bmp file. mybmp.bmp. Will try and upload it to dropbox.
`#include <iostream>
#include <conio.h>
#include <fstream>
#include<stdio.h>
#include<stdlib.h>
using namespace std;
unsigned char* editing(char* filename)
{
int i;
int j;
FILE* mybmpfilespointer;
mybmpfilespointer = fopen(filename, "rb");
unsigned char headerinfo[54];
fread(headerinfo, sizeof(unsigned char), 54, mybmpfilespointer); // read the 54-byte header size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );
// extract image height and width from header
int width = *(int*)&headerinfo[18];
int height = *(int*)&headerinfo[22];
int size = 3 * width * height;
unsigned char* imagesdata = new unsigned char[size]; // allocate 3 bytes per pixel
fread(imagesdata, sizeof(unsigned char), size, mybmpfilespointer); // read the rest of the imagesdata at once
// display image height and width from header
cout << " width:" << width << endl;
cout << " height:" << height << endl;
ofstream arrayfile("bmpofstream.bmp"); // File Creation
for(int a = 0; a < 53; a++) //bgr to rgb
{
arrayfile << headerinfo[a];
}
for(int k=0; k<size; k++)
{
arrayfile<<imagesdata[k]<<endl; //Outputs array to file
}
arrayfile.close();
delete[] mybmpfilespointer;
delete[] imagesdata;
fclose(mybmpfilespointer);
return imagesdata;
return headerinfo;
}
int main()
{
FILE* mybmpfilespointer = fopen("mybmp.bmp", "rb");
if (mybmpfilespointer)
{
editing("mybmp.bmp");
}
else
{
cout << "Cant Read File";
}
}`
As you can see I read from mybmp.bmp which is 819680bytes
and write to bmpofstream.bmp as it is.
But somehow the resulting file is exactly 3x times the size of the mybmp around 2460826bytes.
I read header from mybmp file as headerinfo.
and
data from mybmp as imagesdata.
When I write to bmpofstream.bmp these arrays it is a messed up bmp file.
1) I'm guessing the increase in filesize is related to reading individual pixels and writing them 3 times or something but couldnt figure out. Why do you think this would be?
2) Once I figure out how to read and write this file as it is, I wanted to modify it. So I might as well ask this now:
I wanted to modify this image so that I can increase the value of each pixel by 50, so this would end up in a darker image. Can I do this directly as:
for(j = 0; j < size; j++)
{
imagesdata[j]=imagesdata[j]+50;
}
thank you.
I suggest taking a look at some existing library, even if you want to code yourself you may learn a lot. See for example libbmp source code,
https://code.google.com/p/libbmp/
try this
#include <iostream>
#include <conio.h>
#include <fstream>
#include <vector>
#include <iterator>
void editing( char* filename )
{
std::ifstream input( filename, std::ios::binary );
if( !input.is_open() )
{
std::cout << "Can`t open file" << std::endl;
return;
}
// copies all data into buffer
std::vector<char> buffer( ( std::istreambuf_iterator<char>( input ) ), ( std::istreambuf_iterator<char>() ) );
input.close();
std::vector<char> headerinfo;
{
auto it = std::next( buffer.begin(), 54 );
std::move( buffer.begin(), it, std::back_inserter( headerinfo ) );
buffer.erase( buffer.begin(), it );
}
// extract image height and width from header
int width = *reinterpret_cast<int*>( (char*)headerinfo.data() + 18 );
int height = *reinterpret_cast<int*>( (char*)headerinfo.data() + 22 );
int size = 3 * width * height;
std::vector<char> imagesdata;
{
auto it = std::next( buffer.begin(), size );
std::move( buffer.begin(), it, std::back_inserter( imagesdata ) );
buffer.erase( buffer.begin(), it );
}
// display image height and width from header
std::cout << " width:" << width << std::endl;
std::cout << " height:" << height << std::endl;
// paste your code here
// ...
std::ofstream arrayfile( "bmpofstream.bmp" ); // File Creation
std::ostream_iterator<char> output_iterator( arrayfile );
std::copy( headerinfo.begin(), headerinfo.end(), output_iterator ); // write header to file
std::copy( imagesdata.begin(), imagesdata.end(), output_iterator ); // write image data to file
}
int main(int argc, char**argv)
{
editing( argv[1] );
}