 |
Das deutsche QBasic- und FreeBASIC-Forum Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
volta
Anmeldungsdatum: 04.05.2005 Beiträge: 1876 Wohnort: D59192
|
Verfasst am: 19.05.2009, 18:57 Titel: GDIPlus und PNG-Dateien |
|
|
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 |
|
 |
Löwenherz

Anmeldungsdatum: 25.08.2008 Beiträge: 85 Wohnort: auf einer sonnigen Insel :)
|
Verfasst am: 13.06.2009, 13:22 Titel: GDIplus Beispiele sind klasse |
|
|
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
herzl. Grüße, Löwenkopf aus Nordhessen, wo absolut klasse die Sonne scheint... der Sommer kann also kommen !  _________________ Das Leben ist wie eine Pralinenschachtel, man weiß nie, was dort drinnen für tolle wie böse Überraschungen stecken |
|
Nach oben |
|
 |
Jojo alter Rang

Anmeldungsdatum: 12.02.2005 Beiträge: 9736 Wohnort: Neben der Festplatte
|
Verfasst am: 13.06.2009, 13:44 Titel: |
|
|
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 |
|
 |
volta
Anmeldungsdatum: 04.05.2005 Beiträge: 1876 Wohnort: D59192
|
Verfasst am: 13.06.2009, 14:34 Titel: |
|
|
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.  _________________ Warnung an Choleriker:
Dieser Beitrag kann Spuren von Ironie & Sarkasmus enthalten.
Zu Risiken & Nebenwirkungen fragen Sie Ihren Therapeuten oder Psychiater. |
|
Nach oben |
|
 |
volta
Anmeldungsdatum: 04.05.2005 Beiträge: 1876 Wohnort: D59192
|
Verfasst am: 14.06.2009, 11:55 Titel: png in resource |
|
|
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 |
|
 |
28398
Anmeldungsdatum: 25.04.2008 Beiträge: 1917
|
|
Nach oben |
|
 |
|
|
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.
|
|