CatsLikeToStretch (OP)
Newbie
Offline
Activity: 31
Merit: 0
|
|
March 25, 2012, 08:12:17 PM |
|
Long story short - I am writing a program to create fractals. I am not having any trouble with that part of it, but I am finding it impossible to find somewhere on the interenet that will explain how to output to a .bmp (bitmap) file. I dont want to output to screen and screen cap it, or anything like that - I want to be able to create and write directly to a bitmap. If you think you can help me with this, please contact me and we will negotiate how much I should pay you. BTC only.
|
|
|
|
|
|
|
You get merit points when someone likes your post enough to give you some. And for every 2 merit points you receive, you can send 1 merit point to someone else!
|
|
|
Advertised sites are not endorsed by the Bitcoin Forum. They may be unsafe, untrustworthy, or illegal in your jurisdiction.
|
|
notme
Legendary
Offline
Activity: 1904
Merit: 1002
|
|
March 25, 2012, 08:17:51 PM |
|
|
|
|
|
CatsLikeToStretch (OP)
Newbie
Offline
Activity: 31
Merit: 0
|
|
March 25, 2012, 08:19:59 PM |
|
I've read that - but this is my first time programming anything and I not clear on a few things.
|
|
|
|
yogi
Legendary
Offline
Activity: 947
Merit: 1042
Hamster ate my bitcoin
|
|
March 25, 2012, 08:27:42 PM |
|
Have you looked at wxWidgets, it has a wxBitmap class.
|
|
|
|
notme
Legendary
Offline
Activity: 1904
Merit: 1002
|
|
March 25, 2012, 08:45:47 PM |
|
I've read that - but this is my first time programming anything and I not clear on a few things.
I'd hack it together for you for a few bitcoins, but I'm on vacation. In the absence of spec-reading skills, I would suggest you look at this: http://www.cplusplus.com/forum/beginner/4307/, or as yogi suggested, use a library that does the heavy lifting for you. I've not used wxBitmap, so I can't speak to it, but OpenCV has really easy image file writing APIs. If you are using OpenGL, this link has code to write out a BMP from the buffer returned by glReadPixels: http://dave.thehorners.com/tech-talk/programming/124-opengl-writing-the-framebuffer-to-disk. If you appreciate my google-fu, any bitcents sent to my signature address will be met with a corresponding level of gratitude.
|
|
|
|
Hawkix
|
|
March 25, 2012, 08:50:47 PM |
|
BMP is very easy format - its just some header and then the pixels, rows by rows. For fractals, you definitely will use 24bit RGB BMP format. I do not know what presentation API you use to show the fractals (GDI? OpenGL? DirectX? OtherWidgets?), but if you can recalculate the fractal image into memory matrix (or long array), you basically are done, just open binary file, write header (there are some gotchas, but most of them are well documented), then feed the whole pixels, done. In case of questions, contact me.
|
|
|
|
fuuka
Newbie
Offline
Activity: 26
Merit: 0
|
|
March 26, 2012, 07:12:28 PM |
|
This sounds like a school project I don't think it would take much effort to do the whole thing yourself, as said by others, just look at the BMP spec to get what headers you need and just output the image to file. I'm tempted to try this myself now just for personal interest...
|
|
|
|
casascius
Mike Caldwell
VIP
Legendary
Offline
Activity: 1386
Merit: 1136
The Casascius 1oz 10BTC Silver Round (w/ Gold B)
|
|
March 26, 2012, 07:22:06 PM |
|
I too think this is drop dead simple. Just figure out what the headers are for a BMP for the image size of your choice, and stick them in an array as constant bytes. When you want to write the BMP file, write out the constant bytes and then the pixels. Need not even mess with building a header - just save a BMP file in a paint program for the dimensions and color depth you want, and use the spec to figure out which bytes are the header and which are the pixels.
|
Companies claiming they got hacked and lost your coins sounds like fraud so perfect it could be called fashionable. I never believe them. If I ever experience the misfortune of a real intrusion, I declare I have been honest about the way I have managed the keys in Casascius Coins. I maintain no ability to recover or reproduce the keys, not even under limitless duress or total intrusion. Remember that trusting strangers with your coins without any recourse is, as a matter of principle, not a best practice. Don't keep coins online. Use paper or hardware wallets instead.
|
|
|
casascius
Mike Caldwell
VIP
Legendary
Offline
Activity: 1386
Merit: 1136
The Casascius 1oz 10BTC Silver Round (w/ Gold B)
|
|
March 26, 2012, 07:57:02 PM |
|
I too think this is drop dead simple. Just figure out what the headers are for a BMP for the image size of your choice, and stick them in an array as constant bytes. When you want to write the BMP file, write out the constant bytes and then the pixels. Need not even mess with building a header - just save a BMP file in a paint program for the dimensions and color depth you want, and use the spec to figure out which bytes are the header and which are the pixels.
And that, of course, would be endian-neutral code, right ? Yes because it would be an array of bytes (specifically chars in C++) which don't have endianness problems. If he needed to change the array (e.g. to accommodate a different height or width for the image) then he'd need to make sure he puts the height and width into the header with proper respect for endianness. But in the simplest case, he'd be using a fixed size image using a canned height and width. Then when he gets to actually putting out the pixels, he puts 3 bytes (one for R, one for G, and one for B). I recall the BMP format also requiring each row to start on a 32-bit boundary, so at the end of each row, up to three null bytes must be added for padding to accommodate this (the number of bytes needed depends on the image width).
|
Companies claiming they got hacked and lost your coins sounds like fraud so perfect it could be called fashionable. I never believe them. If I ever experience the misfortune of a real intrusion, I declare I have been honest about the way I have managed the keys in Casascius Coins. I maintain no ability to recover or reproduce the keys, not even under limitless duress or total intrusion. Remember that trusting strangers with your coins without any recourse is, as a matter of principle, not a best practice. Don't keep coins online. Use paper or hardware wallets instead.
|
|
|
realnowhereman
|
|
March 26, 2012, 11:08:11 PM |
|
As general practical advice for C++ file format writing; I suggest the following. - Make child classes for elements off a streamable base class. By "streamable" I mean make a virtual write() member function that accepts an "ostream &" as its parameter.
- Build these elements as members of higher level streamable classes
- The higher level classes then call the write() member in the more elemental class members
An example: class TStreamable { public: ostream &write( ostream & ) = 0; };
class TUint16LE : public TStreamable { public: ostream &write( ostream &s ) { s.put((Value>>0)&0xff); s.put((Value>>8)&0xff); return s;} uint16_t Value; };
class TImageSize : public TStreamable { public: ostream &write( ostream &s ) { Width.write(s); Height.write(s); return s; }
TUint16LE Width, Height; };
Eventually you will have one top level class that writes the entire file; but it will call simpler writers, and they will call simpler writers, etc. You can give that top-level class whatever more convenient member functions you want to set the data; and then leave the complicated writing to take care of itself. Hope that helps.
|
1AAZ4xBHbiCr96nsZJ8jtPkSzsg1CqhwDa
|
|
|
CatsLikeToStretch (OP)
Newbie
Offline
Activity: 31
Merit: 0
|
|
March 30, 2012, 11:40:47 PM |
|
Thanks for all of the replies - I should have prefaced my question with the statement that I am a rank newbie at C++ programming and most of your responses were well over my head. Hawkix suggested that I output Netpbm format instead of BMP and that worked out quite well. I have donated a small sum him for his suggestion.
Once I get out of the newbie forum I plan on starting a thread where I will buy pointers on C++ and linux. I have been using linux for well over a year, but have yet to dip my toe in the nuts and bolts of things. I have learned a lot reading forums and books, but I have also wasted a lot of time because of getting hung up on small issues that a very frustrating. Hopefully offering small bounties, on the order of 1 or 2 BTC, will encourage people to give me well thought out help. If any of you are interested, keep an eye on the marketplace board soon.
|
|
|
|
whitslack
|
|
March 31, 2012, 04:34:39 AM |
|
I wrote a raytracer for a computer graphics class in college and needed to write to BMP format. Here's my code: bmpwriter.h: bool write_bitmap(const char *filename, const char *buffer, int width, int height); bmpwriter.cpp: #include <stdio.h> #include "bmpwriter.h"
// stuff from wingdi.h typedef unsigned short WORD; typedef unsigned int DWORD; #define FAR #pragma pack(push, 2) typedef struct tagBITMAPFILEHEADER { WORD bfType; DWORD bfSize; WORD bfReserved1; WORD bfReserved2; DWORD bfOffBits; } BITMAPFILEHEADER, FAR *LPBITMAPFILEHEADER, *PBITMAPFILEHEADER; typedef struct tagBITMAPCOREHEADER { DWORD bcSize; /* used to get to color table */ WORD bcWidth; WORD bcHeight; WORD bcPlanes; WORD bcBitCount; } BITMAPCOREHEADER, FAR *LPBITMAPCOREHEADER, *PBITMAPCOREHEADER; #pragma pack(pop)
bool write_bitmap(const char *filename, const char *buffer, int width, int height) { BITMAPFILEHEADER bfh = { 0x4D42, sizeof(BITMAPFILEHEADER) + sizeof(BITMAPCOREHEADER) + width * height * 3, 0, 0, sizeof(BITMAPFILEHEADER) + sizeof(BITMAPCOREHEADER) }; BITMAPCOREHEADER bch = { sizeof(BITMAPCOREHEADER), width, height, 1, 24 }; FILE *pf = fopen(filename, "wb"); if (pf == NULL) { return false; } else { fwrite(&bfh, sizeof(BITMAPFILEHEADER), 1, pf); fwrite(&bch, sizeof(BITMAPCOREHEADER), 1, pf); fwrite(buffer, 3 * width, height, pf); fclose(pf); return true; } } The buffer is an array of (3 × width × height) 8-bit samples, which are the RGB colors at each pixel in the image. I don't remember whether BMP uses RGB or BGR ordering, so just play with it until you get it right.
|
|
|
|
CatsLikeToStretch (OP)
Newbie
Offline
Activity: 31
Merit: 0
|
|
March 31, 2012, 10:27:16 PM |
|
Hey, I have another one for you guys. I have been writing to a .pbm file, thats working fine. I am doing it this way
int main () { ofstream myfile ("picture.pbm"); myfile << "255" myfile.close(); return 0; }
It's working fine - but now I want to have to have the output file be named to whatever the value of an integer variable is. Say I have an integer variable called... filename. If filename = 156 then I want to output to a file called 156.pbm.. I cant figure out how to do it. Thanks in advance for any help.
|
|
|
|
realnowhereman
|
|
March 31, 2012, 10:54:33 PM |
|
It's working fine - but now I want to have to have the output file be named to whatever the value of an integer variable is. Say I have an integer variable called... filename. If filename = 156 then I want to output to a file called 156.pbm.. I cant figure out how to do it. Thanks in advance for any help.
Simplest is probably this: int main () { unsigned int filenumber = 156; ostringstream os; os << filenumber << ".pbm";
ofstream myfile (os.str()); myfile << "255" myfile.close(); return 0; }
If you're going to reuse 'os' you should call 'os.str("")' after using it.
|
1AAZ4xBHbiCr96nsZJ8jtPkSzsg1CqhwDa
|
|
|
CatsLikeToStretch (OP)
Newbie
Offline
Activity: 31
Merit: 0
|
|
March 31, 2012, 11:20:39 PM |
|
Thanks for your help - can you elaborate on this a bit? If you're going to reuse 'os' you should call 'os.str("")' after using it.
Also, when I compiled the code I got the following: testbed1.cpp:21:28: error: no matching function for call to ‘std::basic_ofstream<char>::basic_ofstream(std::basic_ostringstream<char>::__string_type)’
|
|
|
|
9c5207677
Newbie
Offline
Activity: 10
Merit: 0
|
|
April 01, 2012, 04:35:08 PM |
|
os.str() returns an object of type std::string, but ofstream does not have a constructor that takes a std::string argument. That's why you must call the c_str() function to return a pointer to a char array from the std::string object. Try this: #include <fstream> #include <sstream>
int main() { unsigned int filenum = 100; std::ostringstream os; os << filenum << ".pbm";
std::ofstream file(os.str().c_str()); file << "hello"; file.close();
return 0; }
|
|
|
|
realnowhereman
|
|
April 01, 2012, 04:55:59 PM |
|
Thanks for your help - can you elaborate on this a bit? If you're going to reuse 'os' you should call 'os.str("")' after using it.
Because ostringstream is alway streaming in an append mode; if you want to reuse the same one to convert the next number in a sequence then you have to clear it between each use. ostringstream os;
for(unsigned int filenum = 0; filenum < 100; filenum++ ) { os << filenum << ".pbm"; ofstream file( os.str().c_str() ); YourFunctionThatWritesToAStream( file ); os.str(""); }
If you didn't have the then os would have "0", "01", "012", "0123", "01234", "012345", etc, as the next number gets appended. Also, when I compiled the code I got the following:
testbed1.cpp:21:28: error: no matching function for call to ‘std::basic_ofstream<char>::basic_ofstream(std::basic_ostringstream<char>::__string_type)’
Oops, wrote without compiling to catch errors. 9c5207677's correction is all you need -- os.str().c_str() will sort this error out.
|
1AAZ4xBHbiCr96nsZJ8jtPkSzsg1CqhwDa
|
|
|
|