StoreTHUMBs

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Benutzeravatar
Xaby
Beiträge: 2144
Registriert: 12.11.2005 11:29
Wohnort: Berlin + Zehdenick
Kontaktdaten:

StoreTHUMBs

Beitrag von Xaby »

Hallo an alle meine Fans und jene, die es werden wollen :mrgreen:

Nach dem ich mich hier ein bisschen umgeschaut habe und ein paar Ideen gesammelt habe ...
ruhig selbst mal lesen:
http://www.purebasic.fr/german/viewtopi ... bs&start=0

Verzeichnisse durchforsten:
Ebenfalls mal lesen:
http://www.purebasic.fr/german/viewtopic.php?t=12983

Habe ich mir folgendes geschrieben:

Erstes Programm:

Code: Alles auswählen


;/ Dateien Suche, von AND51

CompilerIf #PB_Compiler_OS = #PB_OS_Windows ;{
#Sep="\" ; für Windows
CompilerElse
#Sep="/" ; für MacOS, Linux
CompilerEndIf ;}

EnableExplicit 

Procedure sucheDateien(pfad.s, Liste.s(), Typ.s="bmp,jpg,png,jpeg") 
  PathAddBackslash_(@pfad) ; Hängt Backslash an, falls nötig 
  Protected dir=ExamineDirectory(#PB_Any, pfad, ""), n 
  If dir 
    While NextDirectoryEntry(dir) 
      If DirectoryEntryType(dir) = #PB_DirectoryEntry_File 
        For n=1 To CountString(Typ, ",")+1 
          If StringField(Typ, n, ",") = LCase(GetExtensionPart(DirectoryEntryName(dir))) 
            AddElement(Liste()) 
            Liste()=pfad+DirectoryEntryName(dir) 
            Break 
          EndIf 
        Next 
        Continue 
      ElseIf DirectoryEntryName(dir) <> "." And DirectoryEntryName(dir) <> ".." 
        sucheDateien(pfad+DirectoryEntryName(dir), Liste(), Typ) 
      EndIf 
    Wend 
    FinishDirectory(dir) 
  EndIf 
EndProcedure 


NewList DatenListe.s() 


Global ThumbPath.s="C:"+#Sep+"F"+#Sep+"FLThumbs"+#Sep+"Thumbs"+#Sep

Procedure CreateDirectoryPath(S.s,Sep.s)
  Static A.l, d.s, i.l
  A=CountString(S,Sep.s) 
  d=""
For i=1 To A+1
  d=d+StringField(S,i,Sep)+Sep
  CreateDirectory(d) ; Vorhandene Verzeichnisse werden nicht beachtet
Next
EndProcedure

CreateDirectoryPath(ThumbPath,#Sep)

Debug ThumbPath
 
Global Path.s="C:\" ; Bildpfad wählen
 
 sucheDateien(Path,DatenListe()) 
;Debug StrQ(CountList(DatenListe()))+" Dateien gefunden:" 
 
 CreateFile(0,ThumbPath+"PIC_LIST.TXT") 
 ForEach DatenListe()
   WriteStringN(0, DatenListe()) 
 Next
Erstellt PIC_LIST.TXT im THUMBPath
Meiner ist : "C:\F\FLThumbs\Thumbs"
bzw. irgendwas anderes. Unter MacOS und Linux gibt's ja keine Laufwerksbuchstaben.

Achtet beim Pfad, der durchsucht wird darauf, dass es NICHT! C:\ ist. Denn sonst dauert die Suche etwas länger. Das ist noch nicht weiter wild. Denn die Funktion von AND51 ist gut schnell.
Aber es kostet unnötig Zeit, wenn man Verzeichnisse durchsucht, die eh keine Bilder enthalten.

Diese kann man dann gut nutzen für:

Code: Alles auswählen

CompilerIf #PB_Compiler_OS = #PB_OS_Windows ;{
#Sep="\" ; für Windows
CompilerElse
#Sep="/" ; für MacOS, Linux
CompilerEndIf ;}

EnableExplicit


UseJPEGImageDecoder()
UsePNGImageDecoder()

Procedure SetzeImage(bild.s,Image1.l,Image2.l,*xa.Long,*ya.Long,*xb.Long,*yb.Long,*AnzQ.Long,*AnzH.Long)
  #ImageZwischen=3
  #hohe=96
  #breite=128
  Static Image.l
  Static x.l,y.l,v.f,xx.l,yy.l
  
  If LoadImage(#ImageZwischen,bild)<>0
  If IsImage(#ImageZwischen)
    x=ImageWidth(#ImageZwischen)
    y=ImageHeight(#ImageZwischen)
    
  If Not(x<#breite And y<#hohe)
      
    Debug x
    Debug y
    v.f= x/y
    
    If x>y And v>1.3 ; ~ 1.3  ;Seitenverhältnis von #breite zu #hohe, wenn anders, dann wird geschnitten
       x=128 ;ImageWidth(#Image) ;... Hängt von ab, ob x #Image größer ist oder y von #Image
      y=x/v 
    Else
      y=#hohe ;ImageHeight(#Image) ; ThumbNail-Ausmaße
      x=y*v
    EndIf
  ;EndIf
  
  If x<>#breite ; y>x -> dann muss v bei 1.0 sein
    Debug "Hoch"
    If *xa\l+x>ImageWidth(Image1) 
      *ya\l+#hohe ;????
      *xa\l=0
    Else
      ;*xa\l+x
    EndIf
    *AnzH\l+1 ; Prüfung, ob neue Datei angefangen werden muss
  Else
    Debug "Quer"
    If *yb\l+y>ImageHeight(Image2) 
      *xb\l+#breite ;????
      *yb\l=0
    Else
      ;*yb\l+y
    EndIf
    *AnzQ\l+1 ; Prüfung, ob neue Datei angefangen werden muss
  EndIf 
  
  If x<>#breite ; y=#hohe 
    Image=Image1
    xx=*xa\l
    yy=*ya\l
    *xa\l+x 
  Else
    Image=Image2
    xx=*xb\l
    yy=*yb\l
    *yb\l+y
  EndIf   
  
  StartDrawing(ImageOutput(Image)) 
  DrawImage(ImageID(#ImageZwischen),xx,yy,x,y)
  StopDrawing() 
  
  
  
 
  ; Else -> Bild ist klein genug, um schnell genug geladen zu werden, keine Vorschau nötig. bzw. zu kleine Bilder müssen anders abgelegt werden
  ; ein Vergrößern bringt keinen Qualitätszuwachsm sie benötigen nur mehr Speicher!!!
  
EndIf
EndIf  
EndIf
  
EndProcedure


Global i.l, xa2,ya2,xb2,yb2,AnzX,AnzY

Procedure MachBilder(Liste.s(),anz.l)
  ResetList(Liste())
  
  For i=0 To anz
    NextElement(Liste()) 
    Debug Liste()
    If i>1
      SetzeImage(Liste(),0,1,@xa2,@ya2,@xb2,@yb2,@AnzX,@AnzY)
    EndIf
    
  Next 
EndProcedure



Procedure LoadLongList(Liste.s, Liste.s())
  If ReadFile(0,Liste) ; Null muss irgendwie anders ersetzt werden
    While Not Eof(0)
      AddElement(Liste()) 
      Liste()=ReadString(0)
     Wend
    CloseFile(0)
  EndIf 
EndProcedure

NewList DatenListe.s() 

Global ThumbPath.s="C:"+#Sep+"F"+#Sep+"FLThumbs"+#Sep+"Thumbs"+#Sep
LoadLongList(ThumbPath+"PIC_LISt.TXT",DatenListe())

CreateImage(0,480,890,32)
CreateImage(1,520,890,32)


If OpenWindow(0,0,0,1010,900,StrQ(CountList(DatenListe()))+" Dateien gefunden",#PB_Window_ScreenCentered | #PB_Window_SystemMenu) And CreateGadgetList(WindowID(0))
  Define StartTime.l=ElapsedMilliseconds()
  MachBilder(DatenListe(),88) ; die erste Datei in der Liste nicht, wegen Problemen mit UNICode????
  Define EndTime.l=ElapsedMilliseconds()
  SetWindowTitle(0,"87 Dateien dargestellt, davon "+Str(AnzY)+" hoch, "+Str(AnzX)+" breit, bnötigte Zeit: "+Str((StartTime-EndTime)/1000)+" sec.")
  
  ImageGadget(0,5, 5,480,890,ImageID(0))
  ImageGadget(1,490,5,520,890,ImageID(1))
  
Repeat: Until WaitWindowEvent()=#PB_Event_CloseWindow
EndIf

Ich hab die Anzeige auf ein paar Bilder begrenzt, es soll nur eine Demonstration sein. Bei 6 Megapixel-Bildern dauert es schon seine Zeit.
Gut eine Sekunde pro Bild. Muss an der Verkleinerungsfunktion in PB liegen.

Schneller geht's hier mit:
http://www.purebasic.fr/english/viewtop ... 204#136204

Wozu das Ganze? Ich hatte mir überlegt, wie man möglichst platzsparend Bilder in einer für den Menschen noch lesbaren Weise speichern kann, aber nicht zum Beispiel alle Thumbs einzeln speichern muss.
Kleine Dateien verbrauchen ja mehr Speicherplatz als eine Große Datei mit dem gleichen Informatinsgehalt.

Zusätzlich müsste man noch XY und Breite bzw. Höhe des Thumbs abspeichern. Und natürlich in welcher Datei er liegt und ob es ein Hochkantbild oder quer liegendes Bild ist.

Würde man querliegende und hochstehende Bilder zusammen in einer Bilddatei ablegen wollen, so muss man entweder die quer liegenden Bilder drehen oder speichert bei den hochkantigen noch schwarz mit oder ...
Alles andere schien mir zu umständlich.
Wenn ihr verschiedene Bilder benutzt, werdet ihr merken, dass es am Rand des Bildes (in dem die Thumbs liegen) noch nicht optimal ist.

Um das zu umgehen, könnte man zuerst einmal alle Bilder erfassen und deren Höhe und Breite ermitteln.
Diese dann optimal sortieren. Vielleicht mit Hilfe von sowas:

http://www.purebasic.fr/german/viewtopi ... ht=johnson
(Achtung, die Darstellung ist nicht unbedingt richtig! Zu mindest nicht für die Praxis sinnvoll. Aber für die Bilder möglicherweise schon)

Man hat bei dem THUMB-System am Ende also folgendes:

Alle ~ 500 Bilder eine neue THUMB-Bilddatei (JPEG oder PNG z.B.)
und eine passende Textdatei.

128 x 96 ist für ein Thumb eine ideale Größe.
Da 96 durch 3, 4, 8, 16, 32 teilbar ist.

Vorteil für ICONs. Übrigens zu kleine Bilder werden hier nicht erfasst.
Entweder man behandelt sie extra oder kann sie sowieso schnell genug gleich laden.

Alle 500 Bilder sollte eine neue Datei angefangen werden,
da 20 x 25 = 500 ist.
Und 20 x 128 = 2560
Und 25 x 96 = 2400

Unsere Thumb-Datenbank soll ja auch möglichst schnell geladen werden können. Ein Bild mit 2560 x 2400 kann man noch verarbeiten.

Folgendes war meine Idee:

Alle 500 Bilder eine neue Bilddatei (Achtung, die Bilddateien können unterschiedlich schnell voll werden)
Wer mehr Hochkanntbilder hat, bekommt vielleicht schneller 500 Hochkantbilder zusammen als quer Bilder.

Achtung. Wer viele Bilder hat, sagen wir 300.000 und mehr.
Der sollte seine THUMBs auch in verschiedene Ordner ablegen.
Denn 300.000 : 500 ist ~ 600
wenn wir 600 Textdateien und 600 Bilddateien haben, sind wir schon bei 1.200 Dateien in einem Ordner. Und da fängt es langsam an bei Windows mit der Darstellung im Explorer Probleme zu geben.

Die THUMBs könnten so archiviert werden:

THUMBS/Q0000001/Q0000001.JPG (Kompression 80-90% empfohlen)
THUMBS/Q0000001/Q0000001.TXT (Da stehen THUMB-Infos drin)

THUMBS/H0000001/ ...

Thumb-Infos:

Als CSV:

Bildpfad <TAB> dazugehöriges THUMB-Bild (Redundanz)
XPos, YPos, Breite bzw. Höhe (oder auch beides)
weitere Infos wie: MetaDaten, Originalgröße, Name ... Bewertung ...
was man will.

XPos und YPos bräuchte nicht sein, da man aus den Breiten bzw. Höhen den Anfang des nächsten Bildes ermitteln kann.
Aber so kann man schneller auf einzelne Bilder im THUMB-Bild zugreifen ohne das Wissen der anderen. Vorteil:
Sollten einzelne Zeilen aus der THUMBs-Info Datei rausgestrichen oder rauskopiert werden, so funktionieren sie auch allein.
Deshalb wäre es ebenfalls ratsam, die dazugehörige THUMB-Bild-Datei immer mit abzulegen.

Dadurch bleibt man flexibler. Beim Zip(p)en oder RARen spielt es für die Datenbank keine Rolle mehr.

Vorteil an meiner Datenbank-Methode ...
Die Thumbs können durchsucht werden, auch Mosaikbilder sind nach Analyse der Thumbs möglich. Schnller Zugriff auf die einzelnen Segmente.
Offenes einfaches Format, leicht zu integrieren.

Bilder und Thumb-Infos können natürlich auch nachträglich noch verschlüsselt werden.
Weiterer Vorteil, Netzwerkanwendungen denkbar, da nicht nur eine Datenbank-Datei vorliegt und einzelne Thumbs durch TextDateien ausgetauscht werden können.

Umnennen von Bildordnern und Aktualisierung in Thumbs-Daten einfacher als in einem komplexen Datenbank-Format, in dem Bilder und Informationen gemeinsam aufbewart werden.


Nachteil, fehlt die InfoDatei zu dem ThumbBild, war alles für die Katz.
Lässt sich aber umgehen, in dem man diese Infos ans Thumbbild mit anhängt.

Ob man den Pfad absolut oder Relativ speichert, kann sich ja jeder noch selbst überlegen.

>>--------------------------------------------------

Was haltet ihr von der Idee, ein THUMB-Archiv so aufzubauen?

Welche Nachteile seht ihr? War meine Idee kompletter Unsinn?
Sollte ich eine Umfrage starten :mrgreen:

Hoffe, es hilft wem ...

Achso, wenn jemand eine Idee hat, wie man die Bildgröße (Höhe Breite)eines Fotos ermitteln kann, ohne es vorher (komplett) laden zu müssen, da wäre ich dankbar. Würde auf jeden Fall für das Sortieren und die Optimierung am Rand gut sein.

Und klar ist, auch bei meinem Verfahren müssten wohl die Bilddatenbanken neu "defragmentiert" werden, wenn Bilder gelöscht werden und neue hinzukommen. (Kartei leichen würden bei einem Quadratischen Thumb-vormat einfach durch neue Bilder ersetzt werden können) Aber wozu sollte man schwaz mitspeichern. :?

Gruß, Folker :allright:
Kinder an die Macht http://scratch.mit.edu/
Benutzeravatar
Dostej
Beiträge: 529
Registriert: 01.10.2004 10:02
Kontaktdaten:

Beitrag von Dostej »

Achso, wenn jemand eine Idee hat, wie man die Bildgröße (Höhe Breite)eines Fotos ermitteln kann, ohne es vorher (komplett) laden zu müssen, da wäre ich dankbar.
Vermutlich kommst Du dabei nicht drum rum, den header direkt auszulesen. Je nach Dateityp halt anders.
Benutzeravatar
Xaby
Beiträge: 2144
Registriert: 12.11.2005 11:29
Wohnort: Berlin + Zehdenick
Kontaktdaten:

Beitrag von Xaby »

Es wird mal wieder Zeit für einen HeulZmielie
Bild

Gibt's da LIBs? Freie, auch für kommerzielle Nutzung, die das machen?

:?
Kinder an die Macht http://scratch.mit.edu/
Benutzeravatar
dige
Beiträge: 1241
Registriert: 08.09.2004 08:53

Beitrag von dige »

Alle Infos über Imagefile header findest Du hier: http://www.wotsit.org/list.asp?fc=1
"Papa, ich laufe schneller - dann ist es nicht so weit."
Antworten