Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C++: BMP-tiedoston lukeminen

Sivun loppuun

Touho [21.07.2007 18:53:44]

#

Olen tekemässä level makeria peliini. Se lukee bmp tiedostosta pikselin kirkkauden ja tekee siitä arvon maaston korkeudeksi. Ohjelmani on kuitenkin buginen ja tarvitsen apua.

Jossain vaiheessa dataa generoidut tiedostot rupeavat kirjoittamaan vain tavua 255. Kohta riippuu kuvan koosta, ei siitä, mitä tiedostossa on sisällä. Esim 50*50 kuvassa ei ole bugia. Mistä tämä johtuu ja miten tämän voi korjata?

Exe tiedostot ja esimerkki levelit: http://zux.sjr.fi/touho/levelmaker.zip

bmp_to_lvl.exe tekee level tiedoston bmp tiedostosta.
bmp_to_txt.exe tekee txt tiedoston, jossa tavut on numeroina.
lvl_to_txt.exe tekee txt tiedoston, jossa tavut on numeroina.

Laitoin zippiin kaksi kuvaa mukaan. Valitsin yksilöt, joista aiheutuu bugi.


Pelini level tiedoston formaatti:

leveys (2 tavua) (leveys = ensimmäinen + 256*toinen)
korkeus (2 tavua)
data (leveys*korkeus tavua) vasemmalta alhaalta lähtien oikealle kerroksittain

Bittikartan formaatti: http://en.wikipedia.org/wiki/Windows_and_OS/2_bitmap

bmp_to_txt.exe (ja lvl_to_txt.exe, vain eri tiedostonnimet)

#include <fstream>
using namespace std;

int main()
{
	int c;

	ifstream bmp;
	ofstream log;

	bmp.open("level.bmp");
	log.open("level.txt");

	if(bmp.good() && log.good())
	{
		while(bmp.good())
		{
			c = bmp.get();
			log << c << "\n";
		}
	}
	bmp.close();
	log.close();

    return 0;
}

bmp_to_lvl.exe

#include <fstream>
using namespace std;

int main()
{
	int c, i;
	int width=0;
	int height=0;
	int x, y;
	int start;

	ifstream bmp;
	ofstream log;

	bmp.open("level.bmp");
	log.open("level");

	if(bmp.good() && log.good())
	{
		for(i=0;i<10;i++) bmp.get();
		start = bmp.get();
		for(i=0;i<7;i++) bmp.get();

		width = bmp.get() + bmp.get()*256;
		for(i=0;i<2;i++) bmp.get();


		log.put(width%256);

		log.put((width/256)%256);

		height = bmp.get() + bmp.get()*256;
		for(i=0;i<2;i++) bmp.get();

		log.put(height%256);

		log.put((height/256)%256);

		for(i=0;i<start-18-8;i++) bmp.get();

		for(y=0;y<height;y++)
		{
			for(x=0;x<width;x++)
			{
				c = (bmp.get() + bmp.get() + bmp.get())/3;
				log.put(c);
			}
			for(i=0;i<(4-(3*width)%4)%4;i++) bmp.get();
		}
	}
	bmp.close();
	log.close();

    return 0;
}

Touho [23.07.2007 14:06:46]

#

Ongelma ratkesi niin, että muutin kuvan skaalan tästä: 0-255 tähän: 1-255. Ohjelmani jostain syystä ei pystynyt lukemaan 0-tavuja.

Metabolix [23.07.2007 15:33:26]

#

Kokeilepa avata streamit binaarina eli ios::bin-lipulla. Ja kuinka käy \r- ja \n-tavuille, lukeutuvatko oikein? Windowsissa voivat kummatkin muuttua \r\n-pariksi.

Touho [23.07.2007 23:50:03]

#

\n toimii hyvin. \r tavun yli ohjelma hyppää. Tavuun 26 ohjelma lopettaa kokonaan lukemisen.

EDIT: kääntäjä sanoo, että: `bin' is not a member of `std::ios'.

Pekka Karjalainen [24.07.2007 10:01:48]

#

http://www.cppreference.com/io_flags.html­#mode_flags

kertoo, että se on binary, eikä bin.

Touho [24.07.2007 14:57:01]

#

Laitoin tuon flagin. Nyt se muuttaa tavun 13 tavuksi 14 ja tavun 26 tavuksi 27. Tämä jo kelpaa, mutta onko mahdollista saada myös tavut 13 ja 26 käyttöön?

koo [24.07.2007 15:40:41]

#

Ettet vain itse jotenkin muuttele noita tavuja? Sinulla kun taisi aiemminkin olla jokin viritys nollatavujen käsittelyyn...

Touho [24.07.2007 23:02:44]

#

Ei. Käytin ihan samaa koodia.

	ifstream bmp;
	ofstream log;

	bmp.open("height.bmp", ios::binary);
	log.open("out.txt", ios::binary);

      int c;

...

        while(bmp.good())
        {
            c = bmp.get();
            log << c << "\n";
        }

koo [25.07.2007 10:48:07]

#

Voisiko olla niin, että luettavassa tiedostossa ei olekaan ihan sitä, mitä kuvittelet siellä olevan? Oletko tutkinut asiaa millään hexdump-ohjelmalla?

Kun tiedosto avataan binary-moodissa ja sitä luetaan get-funktiolla, minkäänlaisia muunnoksia ei kuulu tapahtua, korkeintaan tiedoston lopusta voi tulla ylimääräisiä nollia. Ja standardikirjaston toteutuksissa on yleensä vähemmän bugeja kuin käyttäjien koodissa, joten... Mutta mitä kääntäjää ja kirjastoa muuten käytät?

Touho [25.07.2007 12:31:03]

#

Tein juuri testin, missä oli korkeutta 26 ja 27 sekä 13 ja 14 vierekkäin. Korkeuseroja näkyi, joten minusta tuntuu, että kaikki on sittenkin ok. Kiitos paljon avusta.


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta