Bmp



  • Ich schreibe grade einen Steganographen. ICh habe nun aber schon mein erstes Problem... wenn ich die geöffnete(unveränderte) BMP speichere, hat sie einen nuen Farbton... Wieso?
    [Quellcode hat noch nichts mit meinem Projekt zu tun, dient nur zur Problembehandlung]

    /*****************************************************************************//
    #include <windows.h>
    #include <string>
    #include <fstream>
    
    #pragma  pack(1)
    struct BMFH // BitmapFileHeader
    {
    	char         bmtype[2];     // 2 bytes - 'B' 'M'
    	unsigned int iFileSize;     // 4 bytes
    	short int    reserved1;     // 2 bytes
    	short int    reserved2;     // 2 bytes
    	unsigned int iOffsetBits;   // 4 bytes
    
    };// End of stBMFH structure - size of 18 bytes
    #pragma pack()
    
    #pragma pack(1)
    struct BMIF // BitmapInfoHeader
    {
    	unsigned int iSizeHeader;    // 4 bytes - 40
    	unsigned int iWidth;         // 4 bytes
    	unsigned int iHeight;        // 4 bytes
    	short int    iPlanes;        // 2 bytes
    	short int    iBitCount;      // 2 bytes
    	unsigned int Compression;    // 4 bytes
    	unsigned int iSizeImage;     // 4 bytes
    	unsigned int iXPelsPerMeter; // 4 bytes
    	unsigned int iYPelsPerMeter; // 4 bytes
    	unsigned int iClrUsed;       // 4 bytes
    	unsigned int iClrImportant;  // 4 bytes
    };// End of stBMIF structure - size 40 bytes
    #pragma pack()
    
    struct Image
    {
    	unsigned int iWidth;
    	unsigned int iHeight;
    	unsigned int* pARGB; // Alpha Red Green Blue
    };
    //*****************************************************************************//
    LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
    
    HWND g_hWnd;
    
    //*****************************************************************************//
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
    {
    	WNDCLASSEX	WndClassEx;
    	wchar_t		*classname = L"Application";
    	MSG			msg;
    
    	ZeroMemory(&WndClassEx, sizeof(WNDCLASSEX));
    	ZeroMemory(&msg,		sizeof(MSG));
    
    	WndClassEx.cbClsExtra		= NULL;
    	WndClassEx.cbSize			= sizeof(WNDCLASSEX);
    	WndClassEx.cbWndExtra		= NULL;
    	WndClassEx.hbrBackground	= (HBRUSH) (COLOR_BTNFACE + 1);
    	WndClassEx.hCursor			= LoadCursor(NULL, IDC_ARROW);
    	WndClassEx.hIcon			= LoadIcon(NULL, IDI_APPLICATION);
    	WndClassEx.hIconSm			= NULL;
    	WndClassEx.hInstance		= hInstance;
    	WndClassEx.lpfnWndProc		= WndProc;
    	WndClassEx.lpszClassName	= classname;
    	WndClassEx.style			= CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
    
    	RegisterClassEx(&WndClassEx);
    
    	g_hWnd = CreateWindowEx(NULL,
    						  classname,
    						  L"Own Control",
    						  WS_OVERLAPPEDWINDOW,
    						  CW_USEDEFAULT,
    						  CW_USEDEFAULT,
    						  800,
    						  300,
    						  NULL,
    						  NULL,
    						  hInstance,
    						  NULL);
    
    	ShowWindow(g_hWnd, SW_SHOWNORMAL);
    	UpdateWindow(g_hWnd);
    
    	while(GetMessage(&msg, NULL, 0, 0))
    	{
    		TranslateMessage(&msg);
    		DispatchMessage(&msg);
    	}
    
    	return 0;
    }
    //*****************************************************************************//
    LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
    	static HDC hDC;
    	switch(uMsg)
    	{
    	case WM_CREATE:
    		hDC = GetDC(hWnd);
    		return 0;
    
    	case WM_PAINT:
    		{
    			std::basic_fstream<char> in("test1.bmp", std::ios_base::in | std::ios_base::binary);
    			if(!in)
    				return -1;
    
    			BMFH bMFH;
    			BMIF bMIF;
    
    			in.read((char*) &bMFH, sizeof(BMFH));
    			in.read((char*) &bMIF, sizeof(BMIF));
    
    			Image img;
    			img.iWidth  = bMIF.iWidth;
    			img.iHeight = bMIF.iHeight;
    			img.pARGB	= new(unsigned int[img.iWidth * img.iHeight]);
    
    			int iNumPaddedBytes = (img.iWidth * 3) % 4;
    
    			in.seekp(bMFH.iOffsetBits);
    			for(unsigned int h = 0; h < img.iHeight; h ++)
    			{
    				for(unsigned int w = 0; w < img.iWidth; w ++)
    				{
    					unsigned char r, g, b;
    
    					in.read((char*) &b, sizeof(char));
    					in.read((char*) &g, sizeof(char));
    					in.read((char*) &r, sizeof(char));
    					SetPixel(hDC, w, img.iHeight - h, RGB(r, g, b));
    
    					img.pARGB[w + h * img.iWidth] = (r << 16 | g << 8 | b);
    				}
    
    				if(iNumPaddedBytes != 0)
    				{
    					unsigned char skip[4];
    					in.read((char*) &skip, sizeof(skip));
    				}
    			}
    
    			std::basic_fstream<char> out("test3.bmp", std::ios_base::out | std::ios_base::binary);
    			out.write((char*) &bMFH, sizeof(BMFH));
    			out.write((char*) &bMIF, sizeof(BMIF));
    
    			unsigned char r, g, b;
    			for(unsigned int h = 0; h < img.iHeight; h ++)
    			{
    				for(unsigned int w = 0; w < img.iWidth; w ++)
    				{		
    					r  = img.pARGB[w + h * img.iWidth] = GetRValue(img.pARGB[w + h * img.iWidth]);
    					g  = img.pARGB[w + h * img.iWidth] = GetGValue(img.pARGB[w + h * img.iWidth]);
    					b  = img.pARGB[w + h * img.iWidth] = GetBValue(img.pARGB[w + h * img.iWidth]);
    
    					SetPixel(hDC, w + img.iWidth, img.iHeight - h, RGB(r, g, b));
    
    					out.write((char*) &r, sizeof(char));
    					out.write((char*) &g, sizeof(char));
    					out.write((char*) &b, sizeof(char));
    				}
    			}
    
    			delete[](img.pARGB);
    
    			ValidateRect(hWnd, NULL);
    
    			return 0;
    		}
    
    	case WM_DESTROY:
    		DeleteDC(hDC);
    		PostQuitMessage(0);
    		return 0;
    
    	default:
    		break;
    	}
    
    	return(DefWindowProc(hWnd, uMsg, wParam, lParam));
    }
    


  • Benutze bitte Code-Tags, dann kann man den Code besser lesen/kopieren.

    Es liegt an folgenden drei Zeilen:

    r = img.pARGB[w + h * img.iWidth] = GetRValue(img.pARGB[w + h * img.iWidth]);
    g = img.pARGB[w + h * img.iWidth] = GetGValue(img.pARGB[w + h * img.iWidth]);
    b = img.pARGB[w + h * img.iWidth] = GetBValue(img.pARGB[w + h * img.iWidth]);
    

    Was machst du da? Wofür zwei Zuweisungen?? Versuch es mal so:

    r = GetRValue(img.pARGB[w + h * img.iWidth]);
    g = GetGValue(img.pARGB[w + h * img.iWidth]);
    b = GetBValue(img.pARGB[w + h * img.iWidth]);
    

    Dann klappt's bei mir.

    mfg.



  • Man, das ich diesen dummen Fehler nicht selbst erkannt habe...
    😃


Anmelden zum Antworten