Bitcoin Forum
December 11, 2016, 12:01:20 PM *
News: Latest stable version of Bitcoin Core: 0.13.1  [Torrent].
 
   Home   Help Search Donate Login Register  
Pages: [1]
  Print  
Author Topic: I would like to buy your C++ expertise  (Read 1185 times)
CatsLikeToStretch
Newbie
*
Offline Offline

Activity: 26


View Profile
March 25, 2012, 08:12:17 PM
 #1

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.
Advertised sites are not endorsed by the Bitcoin Forum. They may be unsafe, untrustworthy, or illegal in your jurisdiction. Advertise here.
notme
Legendary
*
Offline Offline

Activity: 1540


View Profile
March 25, 2012, 08:17:51 PM
 #2

http://en.wikipedia.org/wiki/BMP_file_format

https://www.bitcoin.org/bitcoin.pdf
While no idea is perfect, some ideas are useful.
12jh3odyAAaR2XedPKZNCR4X4sebuotQzN
CatsLikeToStretch
Newbie
*
Offline Offline

Activity: 26


View Profile
March 25, 2012, 08:19:59 PM
 #3

I've read that - but this is my first time programming anything and I not clear on a few things. 
yogi
Legendary
*
Offline Offline

Activity: 947


Hamster ate my bitcoin


View Profile
March 25, 2012, 08:27:42 PM
 #4

Have you looked at wxWidgets, it has a wxBitmap class.

notme
Legendary
*
Offline Offline

Activity: 1540


View Profile
March 25, 2012, 08:45:47 PM
 #5

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.

https://www.bitcoin.org/bitcoin.pdf
While no idea is perfect, some ideas are useful.
12jh3odyAAaR2XedPKZNCR4X4sebuotQzN
Hawkix
Hero Member
*****
Offline Offline

Activity: 517



View Profile WWW
March 25, 2012, 08:50:47 PM
 #6

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.

Donations: 1Hawkix7GHym6SM98ii5vSHHShA3FUgpV6
http://btcportal.net/ - All about Bitcoin - coming soon!
fuuka
Newbie
*
Offline Offline

Activity: 26



View Profile
March 26, 2012, 07:12:28 PM
 #7

This sounds like a school project  Grin

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 Offline

Activity: 1344


The Casascius 1oz 10BTC Silver Round (w/ Gold B)


View Profile WWW
March 26, 2012, 07:22:06 PM
 #8

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 wallets instead.
casascius
Mike Caldwell
VIP
Legendary
*
Offline Offline

Activity: 1344


The Casascius 1oz 10BTC Silver Round (w/ Gold B)


View Profile WWW
March 26, 2012, 07:57:02 PM
 #9

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 wallets instead.
realnowhereman
Hero Member
*****
Offline Offline

Activity: 504



View Profile
March 26, 2012, 11:08:11 PM
 #10

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:

Code:
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
Newbie
*
Offline Offline

Activity: 26


View Profile
March 30, 2012, 11:40:47 PM
 #11

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
Member
**
Offline Offline

Activity: 118



View Profile
March 31, 2012, 04:34:39 AM
 #12

I wrote a raytracer for a computer graphics class in college and needed to write to BMP format. Here's my code:

bmpwriter.h:
Code:
bool write_bitmap(const char *filename, const char *buffer, int width, int height);

bmpwriter.cpp:
Code:
#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
Newbie
*
Offline Offline

Activity: 26


View Profile
March 31, 2012, 10:27:16 PM
 #13

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
Hero Member
*****
Offline Offline

Activity: 504



View Profile
March 31, 2012, 10:54:33 PM
 #14

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:

Code:
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
Newbie
*
Offline Offline

Activity: 26


View Profile
March 31, 2012, 11:20:39 PM
 #15

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 Offline

Activity: 10



View Profile
April 01, 2012, 04:35:08 PM
 #16

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:

Code:
#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
Hero Member
*****
Offline Offline

Activity: 504



View Profile
April 01, 2012, 04:55:59 PM
 #17

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.
Code:
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
Code:
os.str("")
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
Pages: [1]
  Print  
 
Jump to:  

Sponsored by , a Bitcoin-accepting VPN.
Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!