CImage::Load läd jpg-Datei anders als BMP-Datei



  • Ich würd ja eher auf die DPI tippen.



  • @hustbaer Was meinst du da genau? Dass CImage keine 300 DPI verträgt? ich hab jetzt mal probiert alle in Frage kommenden Bilddateien zu testen- Egal wie groß die sind: sie funktionieren immer nur wenn die 24 bit eingestellt haben. Bei 32 bit kommt dieser Murks heraus. Leider finde ich nirgends was darüber das es irgendwelche Einschränkungen gibt bzw. wie man das CImage beibringen kann. Ist m_nBPP 32 dann hat der m_nPitch den Wert -7468, bei m_nBPP von 24 ist m_nPitch -5604. Kann man daraus was ableiten?



  • Bloss dass DPI gut zu "ist zu klein" passt, 32 Bit aber überhaupt nicht gut zu "ist zu klein" passt.

    Ist m_nBPP 32 dann hat der m_nPitch den Wert -7468, bei m_nBPP von 24 ist m_nPitch -5604. Kann man daraus was ableiten?

    Ja sicher: dass das Bild 1867 Pixel breit ist.



  • @hustbaer Ich fasse das noch mal zusammen. Ich verwende jetzt folgenden Code (in den Kommentaren stehen immer die aktuellen Werte der Größe des Bildes dahinter).

    CDC memDC;
    CSize ptSize, ptOrg;
    memDC.CreateCompatibleDC(pDC);
    		
    CImage Image;
    Image.Load(ExpandGlobalAppDataPath(File_Firmenlogo_RGB));
    ptSize.cx = Image.GetWidth();		// cx=1867
    ptSize.cy = Image.GetHeight();		// cy=360
    pDC->DPtoLP(&ptSize);			// nach diesem Aufruf ist cx=788 und cy=152
    		
    
    // Skalieren des Firmenlogos auf cFirmenlogo_maxHeight
    dNewLogoWidth = dNewLogoHeight*static_cast<double>(ptSize.cx) / static_cast<double>(ptSize.cy);
    
    if (dNewLogoWidth > cFirmenlogo_maxWidth)	// falls durch die Skalierung der Höhe die Breite jetzt größer als cFirmenlogo_maxWidth geworden ist, muss das Logo wieder verkleinert werden
    {
    	dNewLogoHeight = dNewLogoHeight * (cFirmenlogo_maxWidth / dNewLogoWidth);
    	dNewLogoWidth = cFirmenlogo_maxWidth;
    }
    iLogoHeight = static_cast<int>(dNewLogoHeight);		// =96
    iLogoWidth = static_cast<int>(dNewLogoWidth);		//=500
    // Skalierung soll so erfolgen, dass das Logo im Ausdruck nicht breiter als 500 (also 5 cm) oder nicht höher als 150 (also 1,5 cm) dargestellt wird. Letzteres ist noch nicht implementiert, da meist automatisch gegeben.
    ptOrg.cx = 0;
    ptOrg.cy = 0;
    memDC.DPtoLP(&ptOrg);
    m_rcPrintDataRect.top = m_rcPrintRect.top - iLogoHeight;
    m_rcPrintDataRect.bottom = m_rcPrintRect.bottom + iLogoHeight;
    
    // die Darstellung funktioniert nur korrekt, wenn die jpg-Datei eine Farbtiefe von 24 bit hat. 32 bit wird verkleinert und mit schwarzem Hintergrund dargestellt
    Image.StretchBlt(*pDC, m_rcPrintRect.right - iLogoWidth, m_rcPrintRect.top, iLogoWidth, -iLogoHeight, ptOrg.cx, ptOrg.cy, Image.GetWidth(), Image.GetHeight(), SRCCOPY);
    


  • @andydd sagte in CImage::Load läd jpg-Datei anders als BMP-Datei:

    CImage Image;
    Image.Load(ExpandGlobalAppDataPath(File_Firmenlogo_RGB));
    ptSize.cx = Image.GetWidth(); // cx=1867
    ptSize.cy = Image.GetHeight(); // cy=360

    Und was bekommst du da bei JPG zurück?



  • @andydd sagte in CImage::Load läd jpg-Datei anders als BMP-Datei:

    Ich fasse das noch mal zusammen. Ich verwende jetzt folgenden Code (in den Kommentaren stehen immer die aktuellen Werte der Größe des Bildes dahinter).

    Du verwendest ´DPtoLP´ falsch. Oder bist du sicher dass immer garantiert ist dass der die einzige Transformation zwischen Display-Koordinaten und logischen Koordinaten eine Skalierung ist? Wobei wenn das so wäre, dann wäre die ganze ptOrg Sache für die Würste und du könntest gleich 0, 0 verwenden.



  • @hustbaer sagte in CImage::Load läd jpg-Datei anders als BMP-Datei:

    @andydd sagte in CImage::Load läd jpg-Datei anders als BMP-Datei:

    CImage Image;
    Image.Load(ExpandGlobalAppDataPath(File_Firmenlogo_RGB));
    ptSize.cx = Image.GetWidth(); // cx=1867
    ptSize.cy = Image.GetHeight(); // cy=360

    Und was bekommst du da bei JPG zurück?

    Bei JPG wird das Gleiche zurückgeliefert. Der Variablenname ist irreführend gewählt. Da ich den noch an anderen Stellen verwende habe ich den noch nicht geändert. Beim Initialisieren bekommt der den Dateipfad zugewiesen.

    @hustbaer sagte in CImage::Load läd jpg-Datei anders als BMP-Datei:

    @andydd sagte in CImage::Load läd jpg-Datei anders als BMP-Datei:

    Ich fasse das noch mal zusammen. Ich verwende jetzt folgenden Code (in den Kommentaren stehen immer die aktuellen Werte der Größe des Bildes dahinter).

    Du verwendest ´DPtoLP´ falsch. Oder bist du sicher dass immer garantiert ist dass der die einzige Transformation zwischen Display-Koordinaten und logischen Koordinaten eine Skalierung ist? Wobei wenn das so wäre, dann wäre die ganze ptOrg Sache für die Würste und du könntest gleich 0, 0 verwenden.

    Das kann gut sein (das ich es falsch verwende oder das noch sonst wo durch das Framework eine Umrechnung ausgeführt wird), deshalb frage ich ja. Ich selbst verwende zur Darstelung nur diesen Code. Aufgerufen wird er in der OnPrint der Viewklasse, da sich die Druckdarstellung von der grafischen Oberfläche (behandelt in OnDraw) deutlich unterscheidet.
    Ich hatte oben erwähnt, dass aktuell ptOrg 0,0 ist und damit wie du schon sagst die Transformation sinnlos ist. Wenn man den aber verschieben würde muss man transformieren. Meinst Du das der erneute Aufruf das Problem generiert? Umrechnen muss ich, weil ich ja MM_LOMETRIC verwende.



  • Also grundsätzlich ist es natürlich möglich dass CImage nen Bug hat und nicht mit 32BPP Bildern funktioniert. Hast du dazu schon mal gegoogelt? Oder in den Source reingesehen?



  • @hustbaer sagte in CImage::Load läd jpg-Datei anders als BMP-Datei:

    Also grundsätzlich ist es natürlich möglich dass CImage nen Bug hat und nicht mit 32BPP Bildern funktioniert. Hast du dazu schon mal gegoogelt? Oder in den Source reingesehen?

    Ja hab ich. Bereits hier im Forum wurden ähnliche Dinge beschrieben, wo es dann trotzdem keine endgültige Lösung gab. Es gab auch Unterscheide zwischen der Darstellung in der Druckvorschau und dem Papierausdruck. Die Load-Funktion von CImage verwendet intern CreateFromGdiplusBitmap(). Wenn ich den Quelltext richtig interpretiere, dann gehen die zunächst immer erst mal von 32 bit aus und wenn das Bild weniger hat wird es angepasst. Aber ich bin da auch nicht der Experte.



  • Hallo,

    lade deine Bilder jpg,bmp,gif,png.. über ole:

     ... Code ... 
     // Read file in memory
       fp = fopen(fileName,"rb");
       if(!fp) 
    	return;
      
       BYTE *pMem  = new BYTE[fs];
       if(!pMem)
        return ;
    
       fread(pMem,1,fs,fp);
       fclose(fp);
    
       if(!StreamToPic(pMem,fs))
       {
        delete pMem;
        return ;
       }
    
       delete pMem;
       
       
    
    bool CDib::StreamToPic(BYTE *pMem, int Size, bool Flip/*=false*/)
    {
       // Use IPicture stuff to use JPG / GIF files
       IPicture* pPicture = 0;
       IStream* pStream   = 0;
       LPBYTE   hG        = 0;
       HRESULT  hRes      = S_FALSE;
      
       DWORD fs = Size;
       hG = (LPBYTE) HeapAlloc( GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, fs);
       if(!hG)
        return hRes;
     
       memcpy(hG,pMem,fs);
       
       HRESULT hRes = ::CreateStreamOnHGlobal(hG,false,&pStream);// Create an IStream so IPicture can 
       if(hRes != S_OK)
       {
        HeapFree(GetProcessHeap(), 0, hG);
        return hRes;
       }
    
       hRes = ::OleLoadPicture(pStream,fs,TRUE,IID_IPicture,(void**)&pPicture);
      
       if(hRes != S_OK)
       {
          pStream->Release();
          HeapFree(GetProcessHeap(), 0, hG);
          return hRes;
       }
    
       short type;pPicture->get_Type(&type);
       if(type == PICTYPE_BITMAP)
       {
    		HBITMAP hBmp = 0;
    		hRes = pPicture->get_Handle( (OLE_HANDLE* )&hBmp);//Retrive GDI Object 
    
    		if (hRes == S_OK)
    		{
    			CDib::Draw(hBmp, Flip);
    		}
        
    		if(hBmp)::DeleteObject(hBmp);
       }
    	
       if(pStream)
        pStream->Release();
    
       if(hG)
    	  HeapFree(GetProcessHeap(), 0, hG);
    
       if(pPicture)
        pPicture->Release();
    
       return (hRes == S_OK);
    }