<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Bitmap Laden]]></title><description><![CDATA[<p>Guten Abend,<br />
Ich habe mir heute einen Bitmap Loader geschrieben - und er treibt mich in die Verzweiflung - leider macht er nicht ganz, was er soll.<br />
nachdem ich e eine 150x200 Pixel große Bitmap geladen und gespeichert habe, ist die Differenz der Dateien am Ende knapp 1KB, ...<br />
Wenn ich das gespeicherte BMP mit Irfant View angucke, fehlt auch eine halbe Zeile - der Windows Interne Bildanzeiger streikt ganz. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f61e.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--disappointed_face"
      title=":("
      alt="😞"
    /></p>
<pre><code class="language-cpp">class Image
{
public:
	Image();
	Image(const Image&amp; other);
	~Image();
	Image&amp; operator =(const Image&amp; other);
	virtual void Release();
	bool IsEmpty() const;

	// Dreckig, da keine Datenkappslung
public:
	unsigned long width;
	unsigned long height;
	unsigned long bits_per_pixel;
	unsigned char* data;
};

////////////////////////////////////////////////////////////////////////////////
#include &quot;BMPLoader.hpp&quot;

BMPLoader::BMPLoader()
{
}

BMPLoader::~BMPLoader()
{

}

BMPLoader::BMPLoader(const std::string&amp; filename, Image&amp; image)
{
	LoadImage(filename, image);
}

bool BMPLoader::LoadImage(const std::string&amp; filename, Image&amp; image)
{
	if(filename.empty())
		return false;

	FILE* file = NULL;

	if((file = fopen(filename.c_str(), &quot;rb&quot;)) == NULL)
		return false;

	// Bitmap File Header auslesen
	BMPFileHeader bfh;
	fread((void*) &amp;bfh.bm_type[0],	1, 1, file);
	fread((void*) &amp;bfh.bm_type[1],	1, 1, file);
	fread((void*) &amp;bfh.file_size,	4, 1, file);
	fread((void*) &amp;bfh.reserved1,	2, 1, file);
	fread((void*) &amp;bfh.reserved2,	2, 1, file);
	fread((void*) &amp;bfh.offset_bits,	4, 1, file);

	if(bfh.bm_type[0] != 'B' &amp;&amp; bfh.bm_type[1] != 'M')
		return false;

	// Bitmap Infor Header auslesen
	BMPInfoHeader bih;
	fread((void*) &amp;bih.size_header,			4, 1, file);
	fread((void*) &amp;bih.width,				4, 1, file);
	fread((void*) &amp;bih.height,				4, 1, file);
	fread((void*) &amp;bih.planes,				2, 1, file);
	fread((void*) &amp;bih.bits_per_pixel,		2, 1, file);
	fread((void*) &amp;bih.compression,			4, 1, file);
	fread((void*) &amp;bih.size_image,			4, 1, file);
	fread((void*) &amp;bih.x_pels_per_meter,	4, 1, file);
	fread((void*) &amp;bih.y_pels_per_meter,	4, 1, file);
	fread((void*) &amp;bih.color_used,			4, 1, file);
	fread((void*) &amp;bih.color_important,		4, 1, file);

#if defined _DEBUG
	printf(&quot;magic number     %c\n&quot;, bfh.bm_type[0]);
	printf(&quot;magic number     %c\n&quot;, bfh.bm_type[1]);
	printf(&quot;file size        %u\n&quot;, bfh.file_size);
	printf(&quot;reserved1        %d\n&quot;, bfh.reserved1);
	printf(&quot;reserved2        %d\n&quot;, bfh.reserved2);
	printf(&quot;offset bits      %u\n&quot;, bfh.offset_bits);

	printf(&quot;size header      %u\n&quot;, bih.size_header);
	printf(&quot;widt             %d\n&quot;, bih.width);
	printf(&quot;height           %d\n&quot;, bih.height);
	printf(&quot;planes           %d\n&quot;, bih.planes);
	printf(&quot;bits per pixel   %d\n&quot;, bih.bits_per_pixel);
	printf(&quot;compression      %u\n&quot;, bih.compression);
	printf(&quot;size image       %u\n&quot;, bih.size_image);
	printf(&quot;x pels per meter %d\n&quot;, bih.x_pels_per_meter);
	printf(&quot;y pels per meter %d\n&quot;, bih.y_pels_per_meter);
	printf(&quot;color used       %u\n&quot;, bih.color_used);
	printf(&quot;color important  %u\n&quot;, bih.color_important);
#endif

	// TODO: Andere Kompressionsverfahren implementieren
	if(bih.compression != COMPRESSION_RGB)
		return false;

	// TODO: Andere Farbarten implementieren
	if(bih.bits_per_pixel != 24)
		return false;

	image.Release();

	image.width				= bih.width;
	image.height			= bih.height;
	image.bits_per_pixel	= bih.bits_per_pixel;

	// Speicher anlegen
	image.data				= new unsigned char[image.width * image.height * 3];

	// Farbwerte auslesen
	fread((void*) image.data, 3, image.width * image.height, file);
	fclose(file);

	return(true);
}

bool BMPLoader::SaveImage(const std::string&amp; filename, const Image&amp; image)
{
	if(filename.empty() || image.IsEmpty())
		return false;

	FILE* file = NULL;

	if((file = fopen(filename.c_str(), &quot;wb&quot;)) == NULL)
		return false;

	// TODO: Andere Farbarten implementieren
	if(image.bits_per_pixel != 24)
		return false;

	// Bitmap File Header erstellen
	BMPFileHeader bfh;
	bfh.bm_type[0]	= 'B';
	bfh.bm_type[1]	= 'M';
	// Breite x Höhe x Farbkanalanzahl (je 1 byte) + (Größe File Header + Größe Info Header?) oder offset?!
	bfh.file_size	= image.width * image.height * 3 + 54;
	bfh.reserved1	= 0;
	bfh.reserved2	= 0;
	bfh.offset_bits	= 54; // bei allen 24 Bit Bildern!

	// Bitmap File Header speichern
	fwrite((void*) &amp;bfh.bm_type[0],	1, 1, file);
	fwrite((void*) &amp;bfh.bm_type[1],	1, 1, file);
	fwrite((void*) &amp;bfh.file_size,	4, 1, file);
	fwrite((void*) &amp;bfh.reserved1,	2, 1, file);
	fwrite((void*) &amp;bfh.reserved2,	2, 1, file);
	fwrite((void*) &amp;bfh.offset_bits,4, 1, file);

	// Bitmap Info Header erstellen
	BMPInfoHeader bih;
	bih.size_header			= 40;
	bih.width				= image.width;
	bih.height				= image.height;
	bih.planes				= 1;
	bih.bits_per_pixel		= image.bits_per_pixel;
	bih.compression			= COMPRESSION_RGB;
	// Breite x Höhe x Farbkanalanzahl (je 1 byte) + Größe File Header + Größe Info Header
	bih.size_image			= image.width * image.height * 3;
	bih.x_pels_per_meter	= 0;
	bih.y_pels_per_meter	= 0;
	bih.color_used			= 0;
	bih.color_important		= 0;

	// Bitmap Info Header speichern
	fwrite((void*) &amp;bih.size_header,		4, 1, file);
	fwrite((void*) &amp;bih.width,				4, 1, file);
	fwrite((void*) &amp;bih.height,				4, 1, file);
	fwrite((void*) &amp;bih.planes,				2, 1, file);
	fwrite((void*) &amp;bih.bits_per_pixel,		2, 1, file);
	fwrite((void*) &amp;bih.compression,		4, 1, file);
	fwrite((void*) &amp;bih.size_image,			4, 1, file);
	fwrite((void*) &amp;bih.x_pels_per_meter,	4, 1, file);
	fwrite((void*) &amp;bih.y_pels_per_meter,	4, 1, file);
	fwrite((void*) &amp;bih.color_used,			4, 1, file);
	fwrite((void*) &amp;bih.color_important,	4, 1, file);

	// Farbwerte speichern
	fwrite((void*) image.data, 3, image.width * image.height, file);
	fclose(file);

	return true;
}

////////////////////////////////////////////////////////////////////////////////
class BMPLoader : public ImageLoader
{
public:
	BMPLoader();
	BMPLoader(const std::string&amp; filename, Image&amp; image);
	virtual ~BMPLoader();

public:
	virtual bool LoadImage(const std::string&amp; filename, Image&amp; image);
	virtual bool SaveImage(const std::string&amp; filename, const Image&amp; image);

public:
	struct BMPFileHeader
	{
		char			bm_type[2];
		unsigned long	file_size;
		short int		reserved1;
		short int		reserved2;
		unsigned long	offset_bits;
	};

	struct BMPInfoHeader
	{
		unsigned int	size_header;
		long			width;
		long			height;
		short int		planes;
		short int		bits_per_pixel;
		unsigned long	compression;
		unsigned long	size_image;
		long			x_pels_per_meter;
		long			y_pels_per_meter;
		unsigned long	color_used;
		unsigned long	color_important;
	};

	enum BitCompression
	{
		// keine Kompression
		COMPRESSION_RGB			= 0,
		COMPRESSION_RLE8,
		COMPRESSION_RLE4,
		COMPRESSION_BITFIELDS
	};
};
</code></pre>
<p>MfG Mandy</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/290016/bitmap-laden</link><generator>RSS for Node</generator><lastBuildDate>Tue, 18 Aug 2026 19:44:14 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/290016.rss" rel="self" type="application/rss+xml"/><pubDate>Sun, 17 Jul 2011 21:34:28 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Bitmap Laden on Sun, 17 Jul 2011 21:34:28 GMT]]></title><description><![CDATA[<p>Guten Abend,<br />
Ich habe mir heute einen Bitmap Loader geschrieben - und er treibt mich in die Verzweiflung - leider macht er nicht ganz, was er soll.<br />
nachdem ich e eine 150x200 Pixel große Bitmap geladen und gespeichert habe, ist die Differenz der Dateien am Ende knapp 1KB, ...<br />
Wenn ich das gespeicherte BMP mit Irfant View angucke, fehlt auch eine halbe Zeile - der Windows Interne Bildanzeiger streikt ganz. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f61e.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--disappointed_face"
      title=":("
      alt="😞"
    /></p>
<pre><code class="language-cpp">class Image
{
public:
	Image();
	Image(const Image&amp; other);
	~Image();
	Image&amp; operator =(const Image&amp; other);
	virtual void Release();
	bool IsEmpty() const;

	// Dreckig, da keine Datenkappslung
public:
	unsigned long width;
	unsigned long height;
	unsigned long bits_per_pixel;
	unsigned char* data;
};

////////////////////////////////////////////////////////////////////////////////
#include &quot;BMPLoader.hpp&quot;

BMPLoader::BMPLoader()
{
}

BMPLoader::~BMPLoader()
{

}

BMPLoader::BMPLoader(const std::string&amp; filename, Image&amp; image)
{
	LoadImage(filename, image);
}

bool BMPLoader::LoadImage(const std::string&amp; filename, Image&amp; image)
{
	if(filename.empty())
		return false;

	FILE* file = NULL;

	if((file = fopen(filename.c_str(), &quot;rb&quot;)) == NULL)
		return false;

	// Bitmap File Header auslesen
	BMPFileHeader bfh;
	fread((void*) &amp;bfh.bm_type[0],	1, 1, file);
	fread((void*) &amp;bfh.bm_type[1],	1, 1, file);
	fread((void*) &amp;bfh.file_size,	4, 1, file);
	fread((void*) &amp;bfh.reserved1,	2, 1, file);
	fread((void*) &amp;bfh.reserved2,	2, 1, file);
	fread((void*) &amp;bfh.offset_bits,	4, 1, file);

	if(bfh.bm_type[0] != 'B' &amp;&amp; bfh.bm_type[1] != 'M')
		return false;

	// Bitmap Infor Header auslesen
	BMPInfoHeader bih;
	fread((void*) &amp;bih.size_header,			4, 1, file);
	fread((void*) &amp;bih.width,				4, 1, file);
	fread((void*) &amp;bih.height,				4, 1, file);
	fread((void*) &amp;bih.planes,				2, 1, file);
	fread((void*) &amp;bih.bits_per_pixel,		2, 1, file);
	fread((void*) &amp;bih.compression,			4, 1, file);
	fread((void*) &amp;bih.size_image,			4, 1, file);
	fread((void*) &amp;bih.x_pels_per_meter,	4, 1, file);
	fread((void*) &amp;bih.y_pels_per_meter,	4, 1, file);
	fread((void*) &amp;bih.color_used,			4, 1, file);
	fread((void*) &amp;bih.color_important,		4, 1, file);

#if defined _DEBUG
	printf(&quot;magic number     %c\n&quot;, bfh.bm_type[0]);
	printf(&quot;magic number     %c\n&quot;, bfh.bm_type[1]);
	printf(&quot;file size        %u\n&quot;, bfh.file_size);
	printf(&quot;reserved1        %d\n&quot;, bfh.reserved1);
	printf(&quot;reserved2        %d\n&quot;, bfh.reserved2);
	printf(&quot;offset bits      %u\n&quot;, bfh.offset_bits);

	printf(&quot;size header      %u\n&quot;, bih.size_header);
	printf(&quot;widt             %d\n&quot;, bih.width);
	printf(&quot;height           %d\n&quot;, bih.height);
	printf(&quot;planes           %d\n&quot;, bih.planes);
	printf(&quot;bits per pixel   %d\n&quot;, bih.bits_per_pixel);
	printf(&quot;compression      %u\n&quot;, bih.compression);
	printf(&quot;size image       %u\n&quot;, bih.size_image);
	printf(&quot;x pels per meter %d\n&quot;, bih.x_pels_per_meter);
	printf(&quot;y pels per meter %d\n&quot;, bih.y_pels_per_meter);
	printf(&quot;color used       %u\n&quot;, bih.color_used);
	printf(&quot;color important  %u\n&quot;, bih.color_important);
#endif

	// TODO: Andere Kompressionsverfahren implementieren
	if(bih.compression != COMPRESSION_RGB)
		return false;

	// TODO: Andere Farbarten implementieren
	if(bih.bits_per_pixel != 24)
		return false;

	image.Release();

	image.width				= bih.width;
	image.height			= bih.height;
	image.bits_per_pixel	= bih.bits_per_pixel;

	// Speicher anlegen
	image.data				= new unsigned char[image.width * image.height * 3];

	// Farbwerte auslesen
	fread((void*) image.data, 3, image.width * image.height, file);
	fclose(file);

	return(true);
}

bool BMPLoader::SaveImage(const std::string&amp; filename, const Image&amp; image)
{
	if(filename.empty() || image.IsEmpty())
		return false;

	FILE* file = NULL;

	if((file = fopen(filename.c_str(), &quot;wb&quot;)) == NULL)
		return false;

	// TODO: Andere Farbarten implementieren
	if(image.bits_per_pixel != 24)
		return false;

	// Bitmap File Header erstellen
	BMPFileHeader bfh;
	bfh.bm_type[0]	= 'B';
	bfh.bm_type[1]	= 'M';
	// Breite x Höhe x Farbkanalanzahl (je 1 byte) + (Größe File Header + Größe Info Header?) oder offset?!
	bfh.file_size	= image.width * image.height * 3 + 54;
	bfh.reserved1	= 0;
	bfh.reserved2	= 0;
	bfh.offset_bits	= 54; // bei allen 24 Bit Bildern!

	// Bitmap File Header speichern
	fwrite((void*) &amp;bfh.bm_type[0],	1, 1, file);
	fwrite((void*) &amp;bfh.bm_type[1],	1, 1, file);
	fwrite((void*) &amp;bfh.file_size,	4, 1, file);
	fwrite((void*) &amp;bfh.reserved1,	2, 1, file);
	fwrite((void*) &amp;bfh.reserved2,	2, 1, file);
	fwrite((void*) &amp;bfh.offset_bits,4, 1, file);

	// Bitmap Info Header erstellen
	BMPInfoHeader bih;
	bih.size_header			= 40;
	bih.width				= image.width;
	bih.height				= image.height;
	bih.planes				= 1;
	bih.bits_per_pixel		= image.bits_per_pixel;
	bih.compression			= COMPRESSION_RGB;
	// Breite x Höhe x Farbkanalanzahl (je 1 byte) + Größe File Header + Größe Info Header
	bih.size_image			= image.width * image.height * 3;
	bih.x_pels_per_meter	= 0;
	bih.y_pels_per_meter	= 0;
	bih.color_used			= 0;
	bih.color_important		= 0;

	// Bitmap Info Header speichern
	fwrite((void*) &amp;bih.size_header,		4, 1, file);
	fwrite((void*) &amp;bih.width,				4, 1, file);
	fwrite((void*) &amp;bih.height,				4, 1, file);
	fwrite((void*) &amp;bih.planes,				2, 1, file);
	fwrite((void*) &amp;bih.bits_per_pixel,		2, 1, file);
	fwrite((void*) &amp;bih.compression,		4, 1, file);
	fwrite((void*) &amp;bih.size_image,			4, 1, file);
	fwrite((void*) &amp;bih.x_pels_per_meter,	4, 1, file);
	fwrite((void*) &amp;bih.y_pels_per_meter,	4, 1, file);
	fwrite((void*) &amp;bih.color_used,			4, 1, file);
	fwrite((void*) &amp;bih.color_important,	4, 1, file);

	// Farbwerte speichern
	fwrite((void*) image.data, 3, image.width * image.height, file);
	fclose(file);

	return true;
}

////////////////////////////////////////////////////////////////////////////////
class BMPLoader : public ImageLoader
{
public:
	BMPLoader();
	BMPLoader(const std::string&amp; filename, Image&amp; image);
	virtual ~BMPLoader();

public:
	virtual bool LoadImage(const std::string&amp; filename, Image&amp; image);
	virtual bool SaveImage(const std::string&amp; filename, const Image&amp; image);

public:
	struct BMPFileHeader
	{
		char			bm_type[2];
		unsigned long	file_size;
		short int		reserved1;
		short int		reserved2;
		unsigned long	offset_bits;
	};

	struct BMPInfoHeader
	{
		unsigned int	size_header;
		long			width;
		long			height;
		short int		planes;
		short int		bits_per_pixel;
		unsigned long	compression;
		unsigned long	size_image;
		long			x_pels_per_meter;
		long			y_pels_per_meter;
		unsigned long	color_used;
		unsigned long	color_important;
	};

	enum BitCompression
	{
		// keine Kompression
		COMPRESSION_RGB			= 0,
		COMPRESSION_RLE8,
		COMPRESSION_RLE4,
		COMPRESSION_BITFIELDS
	};
};
</code></pre>
<p>MfG Mandy</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2094059</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2094059</guid><dc:creator><![CDATA[mandy1988]]></dc:creator><pubDate>Sun, 17 Jul 2011 21:34:28 GMT</pubDate></item><item><title><![CDATA[Reply to Bitmap Laden on Sun, 17 Jul 2011 22:04:48 GMT]]></title><description><![CDATA[<p>Die einzelnen Zeilen eines Bitmaps liegen auf Doppelwort-Bereichen, also immer ohne Rest durch 4 teilbaren Adressen. Also werden maximal 3 Bytes (ich gehe jetzt mal nicht von einem exotischen System aus) hinzugefügt, die normalerweise auf 0 gesetzt werden (müssen sie aber nicht).</p>
<p>Und das ist denke ich das Problem, z.B. ist die Größe der Bilddaten nicht</p>
<pre><code>w*h*3 // wenn man von 24 bit ausgeht
// sondern
h*((w*(bitcount &gt;&gt; 3) + 3) &amp; ~3)
</code></pre>
<p>.<br />
Diese Größen müssen dann beim Laden und Speichern beachtet, und biSizeImage auch angepasst werden.</p>
<p>Edit: Klammern vergessen</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2094064</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2094064</guid><dc:creator><![CDATA[yahendrik]]></dc:creator><pubDate>Sun, 17 Jul 2011 22:04:48 GMT</pubDate></item><item><title><![CDATA[Reply to Bitmap Laden on Mon, 18 Jul 2011 07:10:01 GMT]]></title><description><![CDATA[<p>was du da machst ist echt schönes C...</p>
<p>...mit klassen.</p>
<p>mach das besser mit den stream operatoren, da kannst du am ende auch sicher sein, dass alles da ist</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2094104</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2094104</guid><dc:creator><![CDATA[Skym0sh0]]></dc:creator><pubDate>Mon, 18 Jul 2011 07:10:01 GMT</pubDate></item></channel></rss>