Zeichnen des Inhalts von Speicher



  • Hallo,

    ich habe SPeicher allokiert, wo einfach ein Bild (Bitmap ohne Header) drin liegt (z.B. als 24bpp RGB oder 8bpp s/w). Das will ich einfach in einer WinAPI-Anwendung zeichnen:

    hdc = BeginPaint(hWnd, &ps); 
    
    	  unsigned char *mem=new unsigned char[100*100];
    	  // mem mit was füllen
    
    	  DrawMemory(hdc, ...); <--???
    
    	  EndPaint(hWnd, &ps); 
    	  return 0L;
    

    Mir schwirrt schon der Kopf mit den ganzen StechBltBit, CreateCompatibleDC, CreateBitmapIndirect und Konsorten. Ich packs aber einfach nicht. Wie macht man das am einfachsten?

    Danke!



  • Ich würde dir SetDIBitsToDevice oder DrawDibDraw empfehlen.

    Denen kannst du zwar auch nicht ein Bild in einem beliebigen Format geben. Dafür können beide ein Bild direkt aus dem RAM kopieren, und die "üblichen" Formate (8 Bit Graustufen, 8 Bit mit Palette, 24 Bit RGB etc.) werden alle unterstützt.

    Oder aber du suchst dir eine Library die dir ein einfacheres Interface zum Bilder Malen zur Verfügung stellt. z.B. OpenCV, Cinder, ...



  • Ich habs jetzt so gemacht:

    unsigned char *mem = new unsigned char[600*500*3];
    	BITMAPINFO *bmi = (BITMAPINFO *) malloc(sizeof(BITMAPINFOHEADER));
    	bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    	bmi->bmiHeader.biWidth = 600;
    	bmi->bmiHeader.biHeight = -500;
    	bmi->bmiHeader.biPlanes = 1;
    	bmi->bmiHeader.biBitCount = 24;
    	bmi->bmiHeader.biCompression = BI_RGB;
    	bmi->bmiHeader.biSizeImage = 0;
    	bmi->bmiHeader.biXPelsPerMeter = 1;
    	bmi->bmiHeader.biYPelsPerMeter = 1;
    	bmi->bmiHeader.biClrUsed = 0;
    	bmi->bmiHeader.biClrImportant = 0;
    
    	memset(mem, 250, 600*500*3);
    
    	switch (Msg)
    	{
    	case WM_PAINT:
    		printf(".");
    		hdc = BeginPaint(hWnd, &ps); 
    
    		SetDIBitsToDevice(
    			hdc,
    			0,
    			0,
    			600,
    			500,
    			0,
    			0,
    			0,
    			500,
    			mem,
    			bmi,
    			DIB_RGB_COLORS);
    
    		EndPaint(hWnd, &ps); 
    		return 0L;
    


  • Wozu verschiedene Speicher mit unterschiedlichen Verfahren besorgen ?

    a. Man kann das komplette BMP mit einem Zeiger verwalten inkl. Header

    b. Man spart doppelten Aufwand beim Freigeben.

    c. Nur new profitiert von Ausnahmebehandlung

    LONG width=600, height=500;
       BITMAPINFO *bmi = reinterpret_cast <BITMAPINFO *> (new unsigned char[sizeof(BITMAPINFOHEADER) + width*height*3]); 
    
        bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 
        bmi->bmiHeader.biWidth = width; 
        bmi->bmiHeader.biHeight = -height; 
        bmi->bmiHeader.biPlanes = 1; 
        bmi->bmiHeader.biBitCount = 24; 
        bmi->bmiHeader.biCompression = BI_RGB; 
        bmi->bmiHeader.biSizeImage = 0; 
        bmi->bmiHeader.biXPelsPerMeter = 1; 
        bmi->bmiHeader.biYPelsPerMeter = 1; 
        bmi->bmiHeader.biClrUsed = 0; 
        bmi->bmiHeader.biClrImportant = 0; 
    
        unsigned char *mem  = reinterpret_cast <unsigned char *> (bmi->bmiColors);
    
        memset(mem, 0, width*height*3);   // unwichtig
    
        // ...
    
        delete [] bmi;
    


  • unsigned char *mem  = reinterpret_cast <unsigned char *> (bmi->bmiColors);
    

    Kann man das wirklich so schreiben? Gibt's hier nen Array-To-Pointer Decay vor dem reinterpret_cast , oder wie geht das?

    Egal. Ich würde es auf jeden Fall so schreiben:

    unsigned char *mem  = reinterpret_cast <unsigned char *> (&bmi->bmiColors[0]);
    

    ps:
    Oder gleich

    unsigned char *mem  = reinterpret_cast <unsigned char *> (bmi) + sizeof(BITMAPINFOHEADER);
    

Anmelden zum Antworten