Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht Das deutsche QBasic- und FreeBASIC-Forum
Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
 
FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen  RegistrierenRegistrieren
ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin
Zur Begleitseite des Forums / Chat / Impressum
Aktueller Forenpartner:

GDIPlus und PNG-Dateien

 
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Windows-spezifische Fragen
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
volta



Anmeldungsdatum: 04.05.2005
Beiträge: 1876
Wohnort: D59192

BeitragVerfasst am: 19.05.2009, 18:57    Titel: GDIPlus und PNG-Dateien Antworten mit Zitat

Hi,
wenn man unter Windows nicht nur mit BMPs arbeiten will kommt man an der GDI+ nicht vorbei.
Zuerst war mir das, was ich in VB und C an Quelltexten dazu fand, doch sehr kompliziert, zudem werden die gdiplus - Funktionen häufig als zu langsam eingestuft.
Langsamer als die FBGfx? eindeutig ja! (nur unter ME getestet)
Aber... wenn man nur mit den Grafikfunktionen unter WinAPI, also ohne die FBGfx, auskommen will erspart man sich viel Arbeit (Quelltext).

Erster Versuch war mal nachzusehen welche Bildformate die GDIPlus auf meinem System unterstützt:
Code:
'mit fbc -s gui kompiliert wird kein Konsolefenster erzeugt
#Include Once "windows.bi"
#Include Once "win/GdiPlus.bi"
Using gdiplus 'Namespace

Dim As GdiplusStartupInput gdipsi
Dim As ULong_Ptr gdipToken
Dim As ImageCodecInfo Ptr pImageCodecInfo
Dim As UInteger numEncoders, size
Dim guids As LPOLESTR
Dim text As String

gdipsi.GdiplusVersion = 1 'GdiplusVersion auf 1 setzen
GdiplusStartup( @gdipToken, @gdipsi, NULL )'Initialisieren
'welche Images werden unterstützt
GdipGetImageEncodersSize( @numEncoders, @size )
pImageCodecInfo = Callocate( size )
GdipGetImageEncoders( numEncoders, size, pImageCodecInfo )

For i As Integer = 0 To numEncoders - 1
  StringFromCLSID( @pImageCodecInfo[i].clsid, @guids )'CLSID -> String
  text = text + *Cast(WString Ptr, pImageCodecInfo[i].FormatDescription) + _
  Chr(9) + *guids + Chr(10)
Next
'Anzeigen
MessageBox( 0, text, "GDI+ unterstützt:", MB_OK Or MB_ICONINFORMATION )

'Speicher und Objekt freigeben
DeAllocate( pImageCodecInfo )
GdiplusShutdown( gdipToken )

Hier sind keine Fehlerabfragen eingebaut, ich hoffe das es erstmal auch so geht.
Unter den angezeigten Dateiformaten war auch PNG, also wie bekommt man aus einer BMP- eine PNG- Datei.
Code:
'mit fbc -s gui kompiliert wird kein Konsolefenster erzeugt
#Include Once "windows.bi"
#Include Once "win/GdiPlus.bi"
Using Gdiplus

#Macro MB_Error( text ) 'Fehlermeldungen
MessageBox( FindWindow(0, 0), text, "Fehler:", MB_OK Or MB_ICONERROR )
#EndMacro

Dim As GdiplusStartupInput gdipsi
Dim As ULong_Ptr gdipToken
Dim As GpImage Ptr pImage1
Dim m_clsid As CLSID
Dim As String dformat="PNG" 'BMP , JPEG , GIF , TIFF , PNG
Dim As WString *12 fn1 = "Test.bmp", fn2 = "Test.png"

Function GetEncoderClsid( sFormat As String, ByRef temp_clsid As CLSID ) As Integer
  Dim As ImageCodecInfo Ptr pImageCodecInfo
  Dim As UInteger numEncoders, size

  GdipGetImageEncodersSize( @numEncoders, @size )
  pImageCodecInfo = Callocate( size )
  If GdipGetImageEncoders( numEncoders, size, pImageCodecInfo )=0 Then

    For i As Integer = 0 To numEncoders - 1
      If *Cast(WString Ptr,pImageCodecInfo[i].FormatDescription) = sFormat Then
        temp_clsid = pImageCodecInfo[i].clsid
        Function = 1
      End If
    Next
  EndIf
  If pImageCodecInfo <> 0 Then DeAllocate( pImageCodecInfo )
End Function

gdipsi.GdiplusVersion = 1 'GdiplusVersion auf 1 setzen
If GdiplusStartup( @gdipToken, @gdipsi, NULL ) Then
  MB_Error( "bei der Initialisierung der GDI+" )
  End
End If
'Dateityp wird von der GDI+ selbst erkannt
If GdipLoadImageFromFile( fn1, @pImage1 ) Then
  MB_Error( "Datei "+fn1 +" nicht gefunden!" )
EndIf

'siehe GdiplusImaging.bi
'GdipImageRotateFlip( pImage1, RotateNoneFlipY ) 'horizontal gespiegelt

If GetEncoderClsid ( dformat, m_clsid ) = 0 Then
  MB_Error( "Unbekanntes Dateiformat!" )
Else
  If GdipSaveImageToFile( pImage1, fn2, @m_clsid , NULL ) <> 0 Then
    MB_Error( "Datei "+fn2+" konnte nicht gespeichert werden!" )
  Else
    MessageBox( 0, fn1+" als "+fn2+" gespeichert!", "GDI+ hat", MB_OK Or MB_ICONINFORMATION )
  EndIf
EndIf
'Image und Objekt freigeben
GdipDisposeImage( pImage1 )
GdiplusShutdown( gdipToken )
Das ging schonmal so gut, dass ich gleich eine PNG auf ein Window geladen habe.
Code:
'mit fbc -s gui kompiliert wird kein Konsolefenster erzeugt
#include Once "windows.bi"
#Include Once "win/GdiPlus.bi"
Using Gdiplus

Function WindowProc( Byval hWnd As HWND, Byval uMsg As uint,_
  Byval wParam As WPARAM, Byval lParam As LPARAM ) As LRESULT

  Static As GdiplusStartupInput gdipsi
  Static As ULONG_PTR gdipToken
  Static As GpGraphics Ptr pGraphics
  Static As GpImage Ptr pImage1
  Static rc As RECT
  Dim As PAINTSTRUCT ps

  Select Case uMsg

    Case WM_CREATE
      gdipsi.GdiplusVersion = 1
      GdiplusStartup( @gdipToken, @gdipsi, null )
      GdipLoadImageFromFile( WStr("Osci.png"), @pImage1)
      'siehe GdiplusImaging.bi
      GdipImageRotateFlip( pImage1, RotateNoneFlipX ) 'vertikal gespiegelt
      GetClientRect( hWnd, @rc )

    Case WM_PAINT
      BeginPaint( hWnd, @ps )

      GdipCreateFromHDC(ps.hdc, @pGraphics)
      GdipDrawImageRect(pGraphics, pImage1, rc.left, rc.top, rc.right, rc.bottom )
      'oder
      'GdipDrawImageRect(pGraphics, pImage1, 0, 0, 640, 480 )
      GdipDeleteGraphics(pGraphics)

      EndPaint( hWnd, @ps )

    Case WM_CLOSE
      DestroyWindow( hWnd )

    Case WM_DESTROY
      GdipDisposeImage( pImage1 )
      GdiplusShutdown( gdipToken )
      PostQuitMessage( null )

    Case Else
      Return DefWindowProc( hWnd, uMsg, wParam, lParam )

  End Select

  Return 0

End Function

'Start Main

Dim hWnd As HWND
Dim wMsg As MSG
Dim As Integer wx, wy, nWidth, nHeight
Dim wcx As WNDCLASSEX
Dim className As String = "test_png"

With wcx
  .cbSize = sizeof( WNDCLASSEX )
  .style = CS_HREDRAW Or CS_VREDRAW Or CS_BYTEALIGNWINDOW
  .lpfnWndProc = cast( WNDPROC, @WindowProc )
  .cbClsExtra = null
  .cbWndExtra = null
  .hInstance = GetModuleHandle( null )
  .hbrBackground = GetStockObject( BLACK_BRUSH )
  .lpszMenuName = null
  .lpszClassName = Strptr( className )
  .hIcon = LoadIcon( null, IDI_APPLICATION )
  .hCursor = LoadCursor ( null, IDC_ARROW )
  .hIconSm = 0
End With

RegisterClassEx( @wcx )

nWidth = 650
nHeight = 510
wx = (GetSystemMetrics( SM_CXSCREEN ) / 2) - nWidth / 2
wy = (GetSystemMetrics( SM_CYSCREEN ) / 2) - nHeight / 2

hWnd = CreateWindowEx( WS_EX_OVERLAPPEDWINDOW,_
Strptr( className ), "GDI+ Draw PNG Test",_
WS_OVERLAPPED Or WS_SYSMENU,_
wx, wy, nWidth, nHeight,_
null, null, GetModuleHandle( null ), null )

ShowWindow( hWnd, SW_SHOWNORMAL )
UpdateWindow( hWnd )

Do Until( GetMessage( @wMsg, null, 0, 0 ) = 0 )
  TranslateMessage( @wMsg )
  DispatchMessage( @wMsg )
Loop
Wer gerne damit weiter experimentieren möchte, es sind jede Menge Effekte möglich, stelle ich die Quelltexte und Testdateien als Download ein.
Download der Quelltexte (20kB).
_________________
Warnung an Choleriker:
Dieser Beitrag kann Spuren von Ironie & Sarkasmus enthalten.
Zu Risiken & Nebenwirkungen fragen Sie Ihren Therapeuten oder Psychiater.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Löwenherz



Anmeldungsdatum: 25.08.2008
Beiträge: 85
Wohnort: auf einer sonnigen Insel :)

BeitragVerfasst am: 13.06.2009, 13:22    Titel: GDIplus Beispiele sind klasse Antworten mit Zitat

hi volta!

habe eben dein GDIplus Beispiel ausprobiert und die Zip Datei geladen, klappt alles sehr gut, werde ein paar Experimente damit machen...



Frage: Freebasic including GDIplus kann TIFF, GIF, JPEG, BMP, PNG als Bildformate laden... Ist das in der GDIplus.bi so festgelegt oder geht da noch mehr ??? Ist neu für mich die GDIplus Bibliothek... schaue ich mir noch in Ruhe an, erst Mal vielen Dank für die klasse Beispiele...

Zitat:
wenn man nur mit den Grafikfunktionen unter WinAPI, also ohne die FBGfx, auskommen will erspart man sich viel Arbeit


das will ich heraus finden zwinkern

herzl. Grüße, Löwenkopf aus Nordhessen, wo absolut klasse die Sonne scheint... der Sommer kann also kommen ! grinsen
_________________
Das Leben ist wie eine Pralinenschachtel, man weiß nie, was dort drinnen für tolle wie böse Überraschungen stecken
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
Jojo
alter Rang


Anmeldungsdatum: 12.02.2005
Beiträge: 9736
Wohnort: Neben der Festplatte

BeitragVerfasst am: 13.06.2009, 13:44    Titel: Antworten mit Zitat

Kann sein, dass GDIplus noch diese alten microsoft-vektor/clipart-formate laden kann, aber die kennt ja eh keiner... ansonsten war's das mit den unterstützten formaten.
_________________
» Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
volta



Anmeldungsdatum: 04.05.2005
Beiträge: 1876
Wohnort: D59192

BeitragVerfasst am: 13.06.2009, 14:34    Titel: Antworten mit Zitat

Zitat:
.. ansonsten war's das mit den unterstützten formaten.
absolut nicht!
Von der GDIplus gibt es (leider) wieder mal einige unterschiedliche Versionen.
Mit jeder neuen Win-Version (manchmal auch mit neuem SP) gab und gibt es Erweiterungen.
Mit dem ersten Beispielprogramm (oben) kann man sich auflisten was die eigene Win-Version unterstützt. Die oben angegebenen Formate werden minimal von der GDI+ unterstützt.

EDIT/
Die unterstützten Formate hängen damit nicht von der GDIplus.bi ab, sondern von der installierten Win- (SP)- Version. verwundert
_________________
Warnung an Choleriker:
Dieser Beitrag kann Spuren von Ironie & Sarkasmus enthalten.
Zu Risiken & Nebenwirkungen fragen Sie Ihren Therapeuten oder Psychiater.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
volta



Anmeldungsdatum: 04.05.2005
Beiträge: 1876
Wohnort: D59192

BeitragVerfasst am: 14.06.2009, 11:55    Titel: png in resource Antworten mit Zitat

Wenn ich mich nicht irre hat Windows keine Unterstützung für png-Dateien in Resourcen, auch die GDI+ nicht.
Es geht aber mit Hilfe der GDIplus.
Die resource.rc:
Code:
200 RT_RCDATA Freqm.png
Die 'Freqm.png' wird als DATA-Type eingebunden.
Die load_png_res.bas:
Code:
'mit fbc -s gui resource.rc kompiliert wird kein Konsolefenster erzeugt
#Include Once "windows.bi"
#Include Once "win/GdiPlus.bi"
Using Gdiplus

Function LoadImageFromResource(pName As LPCTSTR, pType As LPCTSTR, ByRef Image1 As GpImage Ptr) As Integer

  Dim As HRSRC hResource
  Dim As Dword imageSize, erg = -1'=Fehler
  Dim As Any Ptr pResourceData
  Dim As HGLOBAL m_hBuffer
  Dim As UByte Ptr pBuffer
  Dim As LPSTREAM pStream

  hResource = FindResource( NULL, pName, pType )
  If hResource= 0 Then Return erg

  imageSize = SizeofResource( NULL, hResource )
  If imageSize= 0 Then Return erg

  pResourceData = LockResource( LoadResource( NULL, hResource ))
  If pResourceData= 0 Then Return erg

  m_hBuffer  = GlobalAlloc( GMEM_MOVEABLE, imageSize )
  If m_hBuffer Then
    pBuffer = GlobalLock( m_hBuffer )
    If pBuffer Then
      ' Ressource in ByteArray speichern
      CopyMemory( pBuffer, pResourceData, imageSize )
      ' Stream erzeugen
      If CreateStreamOnHGlobal( m_hBuffer, 0, @pStream ) = S_OK Then
        ' GDI+ Bitmapobjekt vom Stream erstellen
        erg = GdipLoadImageFromStream( pStream, @Image1 )
        IUnknown_Release(pStream)' Stream beenden/aufräumen
      EndIf
      GlobalUnlock( m_hBuffer )
    EndIf
    GlobalFree( m_hBuffer )
  EndIf
  Return erg
End Function



Function WindowProc( ByVal hWnd As HWND, ByVal uMsg As uint,_
  ByVal wParam As WPARAM, ByVal lParam As LPARAM ) As LRESULT

  Static As GdiplusStartupInput gdipsi
  Static As ULONG_PTR gdipToken
  Static As GpGraphics Ptr pGraphics
  Static As GpImage Ptr pImage1
  Static rc As RECT
  Dim As PAINTSTRUCT ps

  Select Case uMsg

    Case WM_CREATE
      gdipsi.GdiplusVersion = 1
      GdiplusStartup( @gdipToken, @gdipsi, NULL )
      'in resource.rc = "200 RT_RCDATA Freqm.png"
      LoadImageFromResource( "#200", RT_RCDATA, pImage1)
      GetClientRect( hWnd, @rc )

    Case WM_PAINT
      BeginPaint( hWnd, @ps )

      GdipCreateFromHDC(ps.hdc, @pGraphics)
      GdipDrawImageRect(pGraphics, pImage1, rc.left, rc.top, rc.right, rc.bottom )
      'oder
      'GdipDrawImageRect(pGraphics, pImage1, 0, 0, 640, 480 )
      GdipDeleteGraphics(pGraphics)

      EndPaint( hWnd, @ps )

    Case WM_CLOSE
      DestroyWindow( hWnd )

    Case WM_DESTROY
      GdipDisposeImage( pImage1 )
      GdiplusShutdown( gdipToken )
      PostQuitMessage( NULL )

    Case Else
      Return DefWindowProc( hWnd, uMsg, wParam, lParam )

  End Select

  Return 0

End Function

'Start WinMain

Dim hWnd As HWND
Dim wMsg As MSG
Dim As Integer wx, wy, nWidth, nHeight
Dim wcx As WNDCLASSEX
Dim className As String = "test_png"

With wcx
  .cbSize = SizeOf( WNDCLASSEX )
  .style = CS_HREDRAW Or CS_VREDRAW Or CS_BYTEALIGNWINDOW
  .lpfnWndProc = Cast( WNDPROC, @WindowProc )
  .cbClsExtra = NULL
  .cbWndExtra = NULL
  .hInstance = GetModuleHandle( NULL )
  .hbrBackground = GetStockObject( BLACK_BRUSH )
  .lpszMenuName = NULL
  .lpszClassName = StrPtr( className )
  .hIcon = LoadIcon( NULL, IDI_APPLICATION )
  .hCursor = LoadCursor ( NULL, IDC_ARROW )
  .hIconSm = 0
End With

RegisterClassEx( @wcx )

nWidth = 650
nHeight = 510
wx = (GetSystemMetrics( SM_CXSCREEN ) / 2) - nWidth / 2
wy = (GetSystemMetrics( SM_CYSCREEN ) / 2) - nHeight / 2

hWnd = CreateWindowEx( WS_EX_OVERLAPPEDWINDOW,_
StrPtr( className ), "GDI+ load PNG from Resource",_
WS_OVERLAPPED Or WS_SYSMENU,_
wx, wy, nWidth, nHeight,_
NULL, NULL, GetModuleHandle( NULL ), NULL )

ShowWindow( hWnd, SW_SHOWNORMAL )
UpdateWindow( hWnd )

Do Until( GetMessage( @wMsg, NULL, 0, 0 ) = 0 )
  TranslateMessage( @wMsg )
  DispatchMessage( @wMsg )
Loop
Die Funktion LoadImageFromResource läd die png-Datei aus der Resource in einen Stream und dann in ein Bitmapobjekt um.
Der Rest des Programms ist nur zur Darstellung der Grafik in einem Fenster.
Wer gerne damit weiter experimentieren möchte.
Download der Quelltexte (40kB).
_________________
Warnung an Choleriker:
Dieser Beitrag kann Spuren von Ironie & Sarkasmus enthalten.
Zu Risiken & Nebenwirkungen fragen Sie Ihren Therapeuten oder Psychiater.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
28398



Anmeldungsdatum: 25.04.2008
Beiträge: 1917

BeitragVerfasst am: 14.08.2009, 22:48    Titel: Antworten mit Zitat

Weißt du zufällig, ob man das Bitmap Objekt auch irgendwie in ein HBITMAP reingeprügelt kriegt?
Hab bei Google dazu nix gefunden...
Bzw. schon gefunden, das hilft aber wenig:
http://www.codeguru.com/forum/archive/index.php/t-305248.html
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Windows-spezifische Fragen Alle Zeiten sind GMT + 1 Stunde
Seite 1 von 1

 
Gehe zu:  
Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.

 Impressum :: Datenschutz