| |
VB & Windows APIFehler bei GDI+ Funktionen unter WIN7-32bit | | | Autor: benne | Datum: 16.09.10 10:21 |
| Hallo,
in meinem Programm habe ich einige GDI+ Funktionen, die Thumnails von Bilder rechnen und in der Datenbank ablegen.
Beim ersten WIN7 Rechner stelle ich nun fest, dass die Funktion auf Fehler läuft.
(unspecified Error)
Bevor ich nun ein Debugging beginne, wollte ich mal hier nachfragen, ob es bei GDI+ und Win7 irgendwelche Unterschiede gibt, die man beachten sollte.
Auslesen und Anzeigen der Thumbnails funktioniert, nur das Umwandeln und Abspeichern nicht.
Ich arbeite mit VBA unter Access 2003.
danke und Gruß
benne | |
Re: Fehler bei GDI+ Funktionen unter WIN7-32bit | | | Autor: benne | Datum: 17.09.10 07:24 |
| Hallo,
die Rechner sind immer auf dem neuesten Stand.
Das wird durch die zentrale IT erledigt.
Bei XP funktioniert die Umwandlung, bei WIN7 nicht.
Also muss ich mal ran und die Funktionen Schritt für Schritt durchtesten.
Wenn ich Details habe, schreibe ich sie hier wieder rein.
mfg
benne | |
Fehlerposition nach Debug gefunden | | | Autor: benne | Datum: 17.09.10 08:12 |
| Hallo,
nach dem Debug habe ich jetzt rausgefunden, wo der Code hängt :
Bei GdipSaveImageToStream bekomme ich als Rückgabewert 2, was eigentlich "invalid Parameter" bedeutet.
Mein Modul hat leider diese Rückgabe nicht ausgewertet und läuft deshalb nachgelagert auf Fehler.
Ich benutze die Routinen von Sascha Trotwitz
die Stelle in der Funktion ist :
ret = CreateStreamOnHGlobal(0&, 1, IStm) 'Stream erzeugen
'GDIP-Image in Stream speichern:
ret = GdipSaveImageToStream(lBitmap, IStm, TEncoder, TParams)
If ret = 0 Then
Dim hMem As Long, LSize As Long, lpMem As Long
Dim abData() As Byte
ret = GetHGlobalFromStream(IStm, hMem) 'Speicher-Handle aus
' Stream erhalten
If ret = 0 Then
LSize = GlobalSize(hMem)
lpMem = GlobalLock(hMem) 'Zugriff auf Speicher erhalten
ReDim abData(LSize - 1) 'Array entspr. dimensionieren
'Aus Speicherblock des Streams in Array übertragen:
CopyMemory abData(0), ByVal lpMem, LSize
GlobalUnlock hMem 'Speicher wieder sperren
ArrayFromPicture = abData 'Ergebnis
End If Ich bin eher der Datenstruktur-Typ, mit den Innereien von GDI+ habe ich mich noch nie intensiv beschäftigt.
Bisher lief das ganze unter XP sauber durch. Es wäre prima, wenn mir jemand bei diesem Problem auf die Sprünge helfen könnte.
Gruß
benne | |
Re: Fehlerposition nach Debug gefunden | | | Autor: benne | Datum: 17.09.10 15:14 |
| Hi,
nachdem ich den Beitrag eingestellt habe, las ich nochmals den Namen
das soll natürlich "Sascha Trowitzsch" heißen ...
( ja, wenn man nicht alles kopiert sondern von Hand schreibt ... )
Ja, den Autor habe ich kontaktiert, der konnte mir aber auch nicht helfen.
Die Jungs arbeiten mittlerweile alle mit Access 2007 oder 2010. Da wird aber
eine andere DLL verwendet.
schönes Wochenende
Gruß
Benne | |
Re: Fehlerposition nach Debug gefunden | | | Autor: benne | Datum: 20.09.10 08:16 |
| Nein,
ich arbeite nur in VBA.
Eine VB Umgebung habe ich auch nicht.
Gruß
Benne | |
Re: Fehlerposition nach Debug gefunden | | | Autor: benne | Datum: 21.09.10 09:47 |
| Hi,
das Modul für die GDI+ Funktionen habe ich dir gesendet.
Ich rufe die Speicherung wie folgt auf :
Dim objbild As StdPicture
[...]
Set objbild = LoadPictureGDIP(strPicturePath)
Set objbild = MakeThumbGDIP(objbild, lngKantenLaenge, lngKantenLaenge, _
&HFFFFFF)
[...]
If Not (objbild Is Nothing Or objVorschau Is Nothing) Then
Call rst.Open(strSQL, GetConn(), adOpenDynamic, adLockOptimistic)
With rst
!objThumbnail = ArrayFromPicture(objbild, pictypeBMP)
[...] Wie schon erwähnt, hat diese Routine seit langer Zeit unter XP funktioniert, selbst Servicefunktionen wie z.B. alle 4000 Grafiken in der Datenbank neu rechnen, haben ohne Klagen funktioniert.
Unter Win7 wird nun aber der Aufruf von "ArrayFromPicture" zum Problem.
Bei GdipSaveImageToStream(lBitmap, IStm, TEncoder, TParams) wird 2 zurückgegeben.
Vielen Dank für deine Hilfe
Gruß
benne | |
Mit JPG und GIF funktioniert es, warum ? | | | Autor: benne | Datum: 29.09.10 17:37 |
| Hallo,
ich habe die Funktion wieder zeilenweise durchlaufen lassen.
Der Rückgabewert von "CreateStreamOnHGlobal" ist 0, der Stream wurde korrekt erzeugt.
Ich habe jetzt mal anstelle von BMP den Typ GIF eingesetzt.
Damit funktioniert die Umwandlung.
Ebenso mit Typ JPG !
Bei PNG kommt aber wieder der bekannte Fehler.
Jetzt muss ich allerdings gestehen, dass ich mit dem Thema etwas überfordert bin.
Was will ich machen ?
Die Funktion soll in der Datenbank ein Thumbnail ablegen, das unkomprimiert die Bilddaten enthält.
Mit diesem Daten sollen in Übersichten schnelle Vorschaubilder erzeugt werden.
Was passiert, wenn ich hier einen anderen Typ auswähle ?
Bei "GIF" stelle ich fest, dass die Farbtiefe reduziert ist, bei JPG konnte ich noch keinen Unterschied feststellen.
Hier nochmal der Code für die anderen Leser, die das Modul nicht kennen :
'Ähnlich wie vorstehende Prozedur (s. Parameter), nur, dass hier
'nicht in eine Datei gespeichert wird, sondern eine Umwandlung
'über ein OLE-Stream-Objekt in ein Byte-Array vollzogen wird.
'! Dieser Code ist ein Novum, weil er ohne jegliche Type Library auskommt,
' den Stream über das versteckte stdole.IUnknown erzeugt
' und dabei ausschließlich OLE-API-Funktionen verwendet !
Function ArrayFromPicture(ByVal image As Picture, PicType As PicFileType, _
Optional Quality As Byte = 80) As Byte()
Dim lBitmap As Long
Dim TEncoder As GUID
Dim ret As Long
Dim TParams As EncoderParameters
Dim sType As String
Dim IStm As stdole.IUnknown
If lGDIP = 0 Then InitGDIP: If lGDIP = 0 Then Exit Function
If image Is Nothing Then Exit Function
If GdipCreateBitmapFromHBITMAP(image.handle, 0, lBitmap) = 0 Then
Select Case PicType 'CLSID des GDIP-Format-Encoders wählen:
Case pictypeBMP: sType = "{557CF400-1A04-11D3-9A73-0000F81EF32E}"
Case pictypeGIF: sType = "{557CF402-1A04-11D3-9A73-0000F81EF32E}"
Case pictypePNG: sType = "{557CF406-1A04-11D3-9A73-0000F81EF32E}"
Case pictypeJPG: sType = "{557CF401-1A04-11D3-9A73-0000F81EF32E}"
End Select
CLSIDFromString StrPtr(sType), TEncoder
If PicType = pictypeJPG Then 'Falls JPG, dann zusätzlich als
' Parameter
'die Qualitätsstufe einstellen
TParams.count = 1
With TParams.Parameter ' Quality
CLSIDFromString StrPtr( _
"{1D5BE4B5-FA4A-452D-9CDD-5DB35105E7EB}"), .UUID
.NumberOfValues = 1
.type = 4
.Value = VarPtr(Quality)
End With
Else
'Unterschied bei Parameterzahl zwischen GDI+ 1.0 und GDI+ 1.1 bei
' GIFs!!
If bIsGdip11 And (PicType = pictypeGIF) Then TParams.count = 1 Else _
TParams.count = 0
End If
ret = CreateStreamOnHGlobal(0&, 1, IStm) 'Stream erzeugen
'GDIP-Image in Stream speichern:
ret = GdipSaveImageToStream(lBitmap, IStm, TEncoder, TParams)
If ret = 0 Then
Dim hMem As Long, LSize As Long, lpMem As Long
Dim abData() As Byte
ret = GetHGlobalFromStream(IStm, hMem) 'Speicher-Handle aus
' Stream erhalten
If ret = 0 Then
LSize = GlobalSize(hMem)
lpMem = GlobalLock(hMem) 'Zugriff auf Speicher erhalten
ReDim abData(LSize - 1) 'Array entspr. dimensionieren
'Aus Speicherblock des Streams in Array übertragen:
CopyMemory abData(0), ByVal lpMem, LSize
GlobalUnlock hMem 'Speicher wieder sperren
ArrayFromPicture = abData 'Ergebnis
End If
Set IStm = Nothing 'Stream löschen
End If
GdipDisposeImage lBitmap 'GDIP-Image-Speicher freigeben
End If
End Function Ich übergebe ein StdPicture Objekt in die Funktion und bekomme ein Byte() Array zurück. Dies speichere ich dann in das Tabellenfeld.
Wozu kann ich dann überhaupt den Typ auswählen ? Muss ich den passend zum Quellbild einstellen ?
Durch die Funktion MakeThumbGDIP wurde das Quellbild aber bereits mit GDI+ überarbeitet.
Ich ging bisher davon aus, dass die Speicherung im Byte-Array als reine Bitmap ohne irgendwelchen "Firlefanz" erfolgt.
Vielleicht kannst du mir etwas auf die Sprünge helfen, damit ich die Funktionsweise besser verstehe.
Als schnelle Lösung kann jetzt natürlich auf den Typ JPG umstellen, weiß aber nicht, was ich damit eventuell anrichte.
Gruß
Benne | |
Re: Mit JPG und GIF funktioniert es, warum ? | | | Autor: benne | Datum: 30.09.10 10:45 |
| Hallo,
die Eingangsbilder haben als Format JPG ( bei Fotos ) oder PNG ( bei Screenshots oder Grafiken )
Andere Formate sind für unsere Zwecke nicht notwendig bzw. sinnvoll.
Manchmal kommen Zeichnungen im TIF daher, aber die kann ich umwandeln.
Vielleicht liest jemand den Beitrag und kann mir erklären, wie das Byte-Array am besten gespeichert wird.
Gruß und danke
Benne | |
| Sie sind nicht angemeldet! Um auf diesen Beitrag zu antworten oder neue Beiträge schreiben zu können, müssen Sie sich zunächst anmelden.
Einloggen | Neu registrieren |
|
|
sevAniGif (VB/VBA)
Anzeigen von animierten GIF-Dateien
Ab sofort lassen sich auch unter VB6 und VBA (Access ab Version 2000) animierte GIF-Grafiken anzeigen und abspielen, die entweder lokal auf dem System oder auf einem Webserver gespeichert sind. Weitere InfosTipp des Monats Access-Tools Vol.1
Über 400 MByte Inhalt
Mehr als 250 Access-Beispiele, 25 Add-Ins und ActiveX-Komponenten, 16 VB-Projekt inkl. Source, mehr als 320 Tipps & Tricks für Access und VB
Nur 24,95 EURWeitere Infos
|