RAW nach jpg oder bmp konfertieren



  • Hi

    Ich benutze folgtende Klasse (Beispiel) um von einer Webcam ein Bild zu erstellen und dieses abzuspeichern.
    http://www.codeproject.com/audio/DXCapture.asp
    Leider ist es mit dieser Klasse nur möglich ein 32 RAW-Bild zu erstellen.
    Hat jemand ein Beispiel wie ich dieses Bild in ein JPG verwandeln kann?

    Vielen Dank!



  • Verwende z.B. die DevIL oder die FreeImage.
    Dort erzeugst du dir ein Bild mit passender Grösse und Farbformat (RGB32), kopierst dann das RAW Bild rein, und speicherst das Bild einfach mit den DevIL/FreeImage Funktionen als BMP/JPG/TIFF/TGA/PNG/...



  • Ich benutze bereits freeimage für die Sofware!
    Wie kriege ich jedoch das RAW-Bild in die Freeimage klasse? (Konnte es nicht aus der Datei öffnen... (Bild wurde nicht erkannt resp. es war keinen brauchbaren Informationen darin...)



  • Ein RAW Bild ist ein Bild ohne Header, d.h. du musst selbst wissen wie gross es ist und welches Farbformat verwendet wird.
    Dann machst du ein leeres entsprechend grosses fipImage, lädst die Datei in den Speicher (einfach in irgendeinen Puffer), und kopierst die Daten ins Bild rein (fipImage::accessPixels).

    p.S.: wenn es sich um ein "RAW" Fromat einer Kamera handelt (was eben nicht "RAW" ist sondern ein Custom Format), dann viel Glück: http://en.wikipedia.org/wiki/RAW_image_format



  • Das Bild kommt ab einer Webcam und kann z.B im Photoshop ohne Probleme geöffnet werden.
    Hast du mir ein konkretes Beispiel wie ich die Datei öffnen und in einen Speicher lesen kann?
    Das Bild ist 320x240pix gross und hat eine Farbtiefe von 32Bit ich möchte es am Schluss in der FreeImage-Klasse nutzen können... Leider werde ich aus (fipImage::accessPixels) nicht so schlau... 😞



  • Ok, sorry, hatte das mit dem DXCapture bereits wieder vergessen (ich=Siebhirn).
    Wenn du das Bild schonmal im Speicher vorliegen hast, wieso speicherst du es dann nicht gleich über die fipImage Klasse?

    Mit fipImage::accessPixels bekommst du einfach einen Zeiger auf die Pixeldaten des Bildes welches von fipImage verwaltet wird. Wenn du vorher dafür sorgst dass das fipImage die richtige Grösse und Auflösung hat, dann kannst du schätze ich die Pixeldaten die du von DXCapture erhältst direkt reinkopieren (memcpy).

    Ich müsste mir aber erstmal dieses DXCapture Dings ansehen (hatte noch keine Zeit und meinen Codeproject Account vergessen *g*)



  • hi
    Ich habe nun 3 Tage versucht das Ding hinzubekommen leider ohne grossen Erfolg!

    Ich lege zuerst ein neues Bild in der FreeImage-Klasse an:

    FIBITMAP *bitmap = FreeImage_Allocate(320, 240, 32);
    

    Ich finde jedoch den Ort nicht in der DXCapture-Klasse wo das Bild ist??!?!?
    Zudem kapiere ich nicht wirklich wie ich dies dann kopieren kann???

    Vielen Dank für die Hilfe!!!!



  • Wenn du dir ImageCapture, GrabFrame und GetFrame ansiehst wird schnell klar wie das ganze funktioniert.

    Zum "grabben" wird IVMRWindowlessControl9::GetCurrentImage verwendet. Dann wird der Zeiger auf die Bilddaten (DIB - Device Independant Bitmap) so modifiziert dass er direkt auf die "rohen" Bilddaten zeigt -- also direkt auf das erste Pixel. Die Daten werden nochdazu nach 24 Bit konvertiert. (Der Code ist ziemlich grauselig und nicht sehr robust, aber darauf will ich hier nicht wieter eingehen, sonst werden wir nie fertig.)

    Um das Bild mit der C-API der FreeImage in ein FIBITMAP zu bekommen kannst du folgendes versuchen:

    DWORD rc = vmrCapture.GrabFrame(); // Frame "grabben"
    if (rc == DWORD(-1))
        fehler();
    
    FIBITMAP* bitmap = FreeImage_Allocate(320, 240, 24); // Neues FIBITMAP anlegen (24 Bit, nicht 32!)
    if (!bitmap)
        fehler();
    
    void* fibData = FreeImage_GetBits(bitmap); // Zeiger auf die Bilddaten in der FIBITMAP holen
    DWORD fibSize = FreeImage_GetPitch(bitmap) * FreeImage_GetHeight(bitmap); // grösse der Bilddaten im FIBITMAP holen
    
    BYTE* vmrFrameData;
    DWORD vmrFrameSize = vmrCapture.GetFrame(&vmrFrameData); // Zeiger und Grösse der Daten im CVMR_Capture Objekt holen
    
    if (vmrFrameSize != fibSize) // die Grössen müssen übereinstimmen, sonst muss irgendwo ein BUG sein
        fehler();
    
    memcpy(fibData, vmrFrameData, fibSize); // Bild aus CVMR_Capture nach FIBITMAP kopieren
    
    // Bild mit FreeImage Funktionen in das gewünschte Format bringen
    // Bild mit FreeImage Funktionen speichern
    
    FreeImage_Unload(bitmap); // FIBITMAP wieder freigeben
    

    Sollte so funktionieren. Garantie übernehme ich keine weil ich das nichtmal durch nen Compiler laufen lassen hab' geschweige denn ausprobiert - müsste aber hinkommen.



  • Vielen Dank!!!

    Hat super funktioniert!
    Einziger Fehler war, dass das Bild auf dem Kopf stand...
    Habe dies noch mit folgendem Code "korrigiert"

    FIBITMAP* bitmap_New = FreeImage_Allocate(320, 240, 24); // Neues FIBITMAP anlegen (24 Bit, nicht 32!)
    
    	RGBQUAD Color;
    	int x1;
    	int y1;
    	x1=0;
    	y1=0;
    	for(int x=320;x>0;x--)
    	{
    		y1=0;
    		for(int y=240;y>0;y--)
    		{
    			FreeImage_GetPixelColor(bitmap, x, y, &Color);
    			FreeImage_SetPixelColor(bitmap_New,x1,y1,&Color);
    			y1++;
    		}
    		x1++;
    	}
    
    	FreeImage_Save(FIF_JPEG,bitmap_New,"C:\\test_NEW.jpg");
    

    Nun funktioniert alles wie geschmiert!
    Nochmals Danke hustbaer!



  • Tip: es gibt FreeImage_FlipHorizontal und FreeImage_FlipVertical - die werden vermutlich schneller sein als selbst Pixel zu klauben.
    FreeImage_FlipVertical sollte in deinem Fall helfen.


Anmelden zum Antworten