ImageWidth und ImageHeight direkt auslesen

Übersicht BlitzBasic Codearchiv

Neue Antwort erstellen

hectic

Sieger des IS Talentwettbewerb 2006

Betreff: ImageWidth und ImageHeight direkt auslesen

BeitragSo, Dez 14, 2008 22:06
Antworten mit Zitat
Benutzer-Profile anzeigen
Wer die Kantenlängen von Bildern benötigt, ohne zuvor die Bilder an sich in den Grafikspeicher zu laden, kann folgende Funktion benutzen. GetImageSize kann die Kantenlängen von BMP, PCX, TGA, PNG und JPG auslesen. Konnte kein Wert gefunden werden, so wird jeweils ''-1'' zurück gegeben. Es entspricht also den Rückgabewerden wie ImageWidth und ImageHeight es auch zurück geben.

Jedes Format wurde einem Komplettscan meiner Arbeitspartition unterzogen, in welcher jedes Format mit über 3000 Bilddateien automatisch verglichen wurde. Fehler tratten nur dann auf, wenn die Bilder absichtlich manipuliert wurden. Als Beispiel Bilder aus der Demoscene wie die von K€\/\/L€R$ (Name wegen Suchmachineneinträgen unkenntlich gemacht). Bilder die also auch so nicht einfach geladen werden können. Falls denoch jemand was findet, dann kann er es gerne hier mitteilen. Am besten noch ein Link zur eventuellen Bilddatei.

Code: [AUSKLAPPEN]
Print "X: "+GetImageSize("e:\bild.png",0)
Print "Y: "+GetImageSize("e:\bild.png",1)
WaitKey




Function GetImageSize(FImage$,FAxis%)
   FImage=Lower$(FImage)
   Local IFile%
   Local ISize%
   Local IFileX%=-1
   Local IFileY%=-1
   Local ICode%=$C0
   Local ICheck%=0
   Local ICount%
   
   If FileType(FImage)=1 Then
      Select Right$(FImage,4)
            
         Case ".bmp"
            IFile=ReadFile(FImage)
            SeekFile IFile,18
            IFileX=ReadInt(IFile)
            IFileY=ReadInt(IFile)
            CloseFile IFile
            ICheck=1
            
         Case ".pcx"
            IFile=ReadFile(FImage)
            SeekFile IFile,8
            IFileX=ReadShort(IFile)+1
            IFileY=ReadShort(IFile)+1
            CloseFile IFile
            ICheck=1
            
         Case ".tga"
            IFile=ReadFile(FImage)
            SeekFile IFile,12
            IFileX=ReadShort(IFile)
            IFileY=ReadShort(IFile)
            CloseFile IFile
            ICheck=1
            
         Case ".png"
            IFile=ReadFile(FImage)
            SeekFile IFile,16
            IFileX=(ReadByte(IFile)*$1000000)+(ReadByte(IFile)*$10000)+(ReadByte(IFile)*$100)+(ReadByte(IFile)*$1)
            IFileY=(ReadByte(IFile)*$1000000)+(ReadByte(IFile)*$10000)+(ReadByte(IFile)*$100)+(ReadByte(IFile)*$1)
            CloseFile IFile
            ICheck=1
            
         Case ".jpg"
            IFile=ReadFile(FImage)
            ISize=FileSize(FImage)-10
            If ISize>65532 Then ISize=65532
            SeekFile IFile,0
            For ICount=0 To ISize
               If ReadByte(IFile)=$FF Then
                  If ReadByte(IFile)=$C2 Then ICode=$C2
               End If
            Next
            SeekFile IFile,0
            For ICount=0 To ISize
               If ReadByte(IFile)=$FF Then
                  If ReadByte(IFile)=ICode Then
                     ReadByte(IFile)
                     ReadByte(IFile)
                     ReadByte(IFile)
                     IFileY=(ReadByte(IFile)*$100)+(ReadByte(IFile)*$1)
                     IFileX=(ReadByte(IFile)*$100)+(ReadByte(IFile)*$1)
                  End If
               End If
            Next
            CloseFile IFile
            ICheck=1
      End Select
      
      ;Werteausgabe
      If ICheck=1 Then
         If FAxis=0 Then Return IFileX
         If FAxis=1 Then Return IFileY
      End If
   End If
   
   ;Fehlerausgabe
   Return -1
End Function
 

Matthias

BeitragDi, Dez 16, 2008 11:10
Antworten mit Zitat
Benutzer-Profile anzeigen
Sehr schön hectic. Das ist wirklich mal was sinvolles. Jedenfalls für mich.

Mit Bmp hätte ich es ja noch selbst hinbekommen, aber jpg und sogar png. Ist echt der Warnsinn.
Laughing

Vorallem für Animationen ist es sehr sinvoll.

Du kennst dich ja wirklich super aus. Deshalb meine Frage. Gibt es in zb Png Formate auch Platz für Benutzerdefienierte daten. Zb um seinen Namen oder so gleich im Bild zu speichern.

Silver_Knee

BeitragDi, Dez 16, 2008 14:53
Antworten mit Zitat
Benutzer-Profile anzeigen
da ich ja selbst mal versucht habe png in blitz mit readbyte etc umzusetzen kam ich auuch daran vorbei.... es ist tatsächlich möglich personalisierte Daten in PNG abzuspeichern. Am einfachsten ist es wohl wen du ans ende der datei aUT<LÄNGE><NAME> schreibst... <Länge>ist dabei die länge des namens...

hast du, hectic eigendlich deshalb bei dem png format den integer so umständlich ausgelesen weil er rückwärts eingespeichert wurde?

hectic

Sieger des IS Talentwettbewerb 2006

BeitragDi, Dez 16, 2008 15:51
Antworten mit Zitat
Benutzer-Profile anzeigen
@Silver_Knee, ja, die Bytes liegen in rückwärtiger Rehenfolge vor als sie Blitz zum Beispiel über ReadInt ausliesst. Gibt es denn eine elegantere Lösung wie man das besser machen kann?

@Matthias, gut das es jemanden auch was nützt. Ich brauche es für meine neue Draw3D, und so habe ich diese Funktion noch kurz umgeschrieben um genau das zu machen was sie zur Zeit tut. Deine Frage kann ich allerdings bezüglich eingeschlossener Daten nicht beantworten. Ich hoffe aber das Silver_Knee da weiter helfen konnte. Denn ich habe mich bei dieser Sache im wesentlichen nur um diese beiden Werte gekümmert. Ansonsten gibt es ausreichende Informationsangaben auf http://www.wotsit.org

Denoch bieten viele Formate eben die Möglichkeit an, benutzerdeffinierte Daten eintragen zu können. Diese sind dann meisten mit Markierungspunkten gekennzeichnet. Darin befinden sich dann auch oft Daten über die Herkunft des Bildes oder das Programm, mit welchen es als letztes abgespeichert wurde.
Download der Draw3D2 V.1.1 für schnelle Echtzeiteffekte über Blitz3D

Farbfinsternis

BeitragDi, Dez 16, 2008 16:28
Antworten mit Zitat
Benutzer-Profile anzeigen
Die Integer liegen als Big-Endian im PNG, während Blitz3D Little-Endian liest. Prinzipiell genügt es das Integer auszulesen und die Byte-Reihenfolge umzudrehen.

Ich habe mir gestattet diesen Code ins basic.blog zu übernehmen. Wenn das ein Problem ist nehme ich es wieder raus.
Farbfinsternis.tv

hectic

Sieger des IS Talentwettbewerb 2006

BeitragDi, Dez 16, 2008 17:05
Antworten mit Zitat
Benutzer-Profile anzeigen
Ach quatsch, kein Problem. Freud mich sogar.

Das mit Integer einlesen und im nachhinein vertauschen ist mir klar. Doch das ist dann noch umstädlicher als die vier Bytes in der Form einzelnd einzulesen.
Download der Draw3D2 V.1.1 für schnelle Echtzeiteffekte über Blitz3D
 

judos

Betreff: gif

BeitragSa, Nov 14, 2009 0:46
Antworten mit Zitat
Benutzer-Profile anzeigen
Ziemlich nützlich Smile Habe es allerdings gerade noch für gif brauchen wollen. Herausgekommen ist eine kleine Erweiterung für Gif Dateien:

BlitzBasic: [AUSKLAPPEN]
Function GetImageSize(FImage$,FAxis%)
FImage=Lower$(FImage)
Local IFile%
Local ISize%
Local IFileX%=-1
Local IFileY%=-1
Local ICode%=$C0
Local ICheck%=0
Local ICount%

If FileType(FImage)=1 Then
Select Right$(FImage,4)
Case ".gif"
IFile=ReadFile(FImage)
SeekFile IFile,6
IFileX=ReadShort(IFile)
IFileY=ReadShort(IFile)
CloseFile IFile
ICheck=1

Case ".bmp"
IFile=ReadFile(FImage)
SeekFile IFile,18
IFileX=ReadInt(IFile)
IFileY=ReadInt(IFile)
CloseFile IFile
ICheck=1

Case ".pcx"
IFile=ReadFile(FImage)
SeekFile IFile,8
IFileX=ReadShort(IFile)+1
IFileY=ReadShort(IFile)+1
CloseFile IFile
ICheck=1

Case ".tga"
IFile=ReadFile(FImage)
SeekFile IFile,12
IFileX=ReadShort(IFile)
IFileY=ReadShort(IFile)
CloseFile IFile
ICheck=1

Case ".png"
IFile=ReadFile(FImage)
SeekFile IFile,16
IFileX=(ReadByte(IFile)*$1000000)+(ReadByte(IFile)*$10000)+(ReadByte(IFile)*$100)+(ReadByte(IFile)*$1)
IFileY=(ReadByte(IFile)*$1000000)+(ReadByte(IFile)*$10000)+(ReadByte(IFile)*$100)+(ReadByte(IFile)*$1)
CloseFile IFile
ICheck=1

Case ".jpg"
IFile=ReadFile(FImage)
ISize=FileSize(FImage)-10
If ISize>65532 Then ISize=65532
SeekFile IFile,0
For ICount=0 To ISize
If ReadByte(IFile)=$FF Then
If ReadByte(IFile)=$C2 Then ICode=$C2
End If
Next
SeekFile IFile,0
For ICount=0 To ISize
If ReadByte(IFile)=$FF Then
If ReadByte(IFile)=ICode Then
ReadByte(IFile)
ReadByte(IFile)
ReadByte(IFile)
IFileY=(ReadByte(IFile)*$100)+(ReadByte(IFile)*$1)
IFileX=(ReadByte(IFile)*$100)+(ReadByte(IFile)*$1)
End If
End If
Next
CloseFile IFile
ICheck=1
End Select

;Werteausgabe
If ICheck=1 Then
If FAxis=0 Then Return IFileX
If FAxis=1 Then Return IFileY
End If
End If

;Fehlerausgabe
Return -1
End Function


Habe es mit ca. 512 Gif Bilder geprüft. Hat soweit funktioniert. Ansonsten Probleme bitte melden.
Wikipedia hat mir übrigens geholfen um zu verstehen wie ich die Grösse in der Datei herausbekomme...

Hier noch der TestCode mit dem man gif Bilder in einem Ordner testen kann:
BlitzBasic: [AUSKLAPPEN]
dir=ReadDir("gif\")
akt=1
total=512
Repeat
file$=NextFile(dir)
If Right(file$,3)="gif" Then
m=OpenMovie("gif\"+file$)
w=MovieWidth(m)
h=MovieHeight(m)
CloseMovie m
w2=getimagesize("gif\"+file$,0)
h2=getimagesize("gif\"+file$,1)
If w<>w2 Or h<>h2 Then
DebugLog "Problem with file: "+file$
DebugLog w+"/"+h+" vs. "+w2+"/"+h2
EndIf
akt=akt+1
AppTitle akt+"/"+total
EndIf
Until file$=""
Print "ende."
WaitKey
End


mfg judos

ToeB

BeitragSa, Nov 14, 2009 17:15
Antworten mit Zitat
Benutzer-Profile anzeigen
Sehr schön hectic ist mir in deiner neuen Draw3D2 auch schon aufgefallen Cool

Sehr nützlich vor allen dingen ^^

mfg ToeB
Religiöse Kriege sind Streitigkeiten erwachsener Männer darum, wer den besten imaginären Freund hat.
Race-Project - Das Rennspiel der etwas anderen Art
SimpleUDP3.0 - Neuste Version der Netzwerk-Bibliothek
Vielen Dank an dieser Stelle nochmal an Pummelie, welcher mir einen Teil seines VServers für das Betreiben meines Masterservers zur verfügung stellt!

Neue Antwort erstellen


Übersicht BlitzBasic Codearchiv

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group