Eigenes XnView Plugin erstellen

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
Thorium
Beiträge: 1722
Registriert: 12.06.2005 11:15
Wohnort: Germany
Kontaktdaten:

Eigenes XnView Plugin erstellen

Beitrag von Thorium »

XnView ist ein Freeware Bildbetrachter: http://www.xnview.com/
Das interessante an ihm ist, das er eine offene Plugin Schnittstelle zur Verfügung stellt. Sehr nützlich, wenn man seine eigenen Bildformate bastelt und keinen großartigen Viewer dafür programmieren möchte. Oder sehr ausgefallene Formate, z.B. von älteren Spielen anzeigen möchte.

Das Plugin-SDK besteht nur aus einem unkomentierten C Source, dementsprechend hatte ich Probleme damit mein Plugin mit PureBasic umzusetzen. Da kein erklärender Text vorhanden ist, muss man erstmal drauf kommen das der Plugin Dateiname mit einem großen X beginnen muss und mit .usr aufhöhren muss. Die Plugins, die bei der Installation dabei sind enden mit .dll und nur eines beginnt mit X. Allerdings scheint XnView über einige verschiedene Schnittstellen zu verfügen, da die Plugins auch alle andere Prozeduren exportieren.

Lange Rede kurzer Sinn, hier eine funktionierende Übersetzung des Testplugins des Plugin-SDK's:
Als DLL kompilieren und die Dateierweiterung auf .usr ändern. Ausserdem den ersten Buchstaben des Dateinamens auf "X" setzen. Die Datei dann ins PlugIns Verzeichnis von XnView kopieren.
Das SDK gibts hier: http://www.xnview.com/download/plugins/ ... DK-win.zip
Es enthält ein Testbild mit der Erweiterung .tst, welches mit dem Testplugin geladen und gespeichert werden kann.

Code: Alles auswählen

;/------------------------------------------\
;| Plugin example for XnView 1.65 or higher |
;| by Thorium                               |
;|                                          |
;| PureBasic 4.40                           |
;\------------------------------------------/

EnableExplicit

#GFP_RGB = 0
#GFP_BGR = 1

#GFP_READ  = 1
#GFP_WRITE = 2

Structure GFP_COLORMAP
	Red.a[256]
	Green.a[256]
	Blue.a[256]
EndStructure

Structure MYDATA
  fp.i
  Width.i
  Component_Per_Pixel.i
EndStructure

ProcedureDLL gfpGetPluginInfo(Version.i, *Label, Label_Max_Size.i, *Extension, Extension_Max_Size.i, *Support.INTEGER)

  If Version <> 2
    ProcedureReturn #False
  EndIf
  
  PokeS(*Label, "Plugin Example")
  PokeS(*Extension, "tst;test")
  
  *Support\i = #GFP_READ | #GFP_WRITE

  ProcedureReturn #True
  
EndProcedure

ProcedureDLL gfpLoadPictureInit(Filename.s)

  Define *FileData.MYDATA
  
  *FileData = AllocateMemory(SizeOf(MYDATA))
  *FileData\fp = OpenFile(#PB_Any, Filename)
  
  If *FileData\fp = 0
    FreeMemory(*FileData)
    *FileData = 0
  EndIf
  
  ProcedureReturn *FileData

EndProcedure

ProcedureDLL gfpLoadPictureGetInfo(*FileData.MYDATA, *PicType.Integer, *Width.Integer, *Height.INTEGER, *Dpi.INTEGER, *Bits_Per_Pixel.INTEGER, *Bytes_Per_Line.INTEGER, *Has_Colormap.INTEGER, *Label, Label_Max_Size.i)

  *Width\i = ReadLong(*FileData\fp)
  *Height\i = ReadLong(*FileData\fp)
  *Bits_Per_Pixel\i = ReadLong(*FileData\fp)
  
  *FileData\Width = *Width\i
  *FileData\Component_Per_Pixel = *Bits_Per_Pixel\i / 8
  
  *PicType\i = #GFP_RGB
  *Dpi\i = 68
  *Bytes_Per_Line\i = *FileData\Component_Per_Pixel * *Width\i
  
  *Has_Colormap\i = #False

  PokeS(*Label, "Test format")
  
  ProcedureReturn #True
  
EndProcedure

ProcedureDLL gfpLoadPictureGetLine(*FileData.MYDATA, Line.i, *Buffer)

  ReadData(*FileData\fp, *Buffer, *FileData\Width * *FileData\Component_Per_Pixel)

  ProcedureReturn #True
  
EndProcedure

ProcedureDLL gfpLoadPictureGetColormap(*FileData.MYDATA, *cMap.GFP_COLORMAP)

  ProcedureReturn #False

EndProcedure

ProcedureDLL gfpLoadPictureExit(*FileData.MYDATA)

  CloseFile(*FileData\fp)
  FreeMemory(*FileData)

EndProcedure

ProcedureDLL gfpSavePictureIsSupported(Width.i, Height.i, Bits_Per_Pixel.i, Has_Colormap.i)

  If Has_Colormap <> #False Or Bits_Per_Pixel <> 24
    ProcedureReturn #False
  EndIf
  
  ProcedureReturn #True
  
EndProcedure

ProcedureDLL gfpSavePictureInit(*Filename, Width.i, Height.i, Bits_Per_Pixel.i, Dpi.i, *Picture_Type.INTEGER, *Label, Label_Max_Size.i)

  Define *FileData.MYDATA
  
  *FileData = AllocateMemory(SizeOf(MYDATA))
  *FileData\fp = CreateFile(#PB_Any, PeekS(*Filename))
  
  If *FileData\fp = 0
    FreeMemory(*FileData)
    ProcedureReturn #False
  EndIf
  
  *Picture_Type\i = #GFP_RGB
  WriteLong(*FileData\fp, Width)
  WriteLong(*FileData\fp, Height)
  WriteLong(*FileData\fp, Bits_Per_Pixel)
  
  PokeS(*Label, "Test format")
  
  *FileData\Width = Width
  *FileData\Component_Per_Pixel = Bits_Per_Pixel / 8

  ProcedureReturn *FileData

EndProcedure

ProcedureDLL gfpSavePicturePutLine(*FileData.MYDATA, Line.i, *Buffer)

  WriteData(*FileData\fp, *Buffer, *FileData\Width * *FileData\Component_Per_Pixel)
  
  ProcedureReturn #True
  
EndProcedure

ProcedureDLL gfpSavePictureExit(*FileData.MYDATA)

  CloseFile(*FileData\fp)
  FreeMemory(*FileData)
  
EndProcedure
Zu mir kommen behinderte Delphine um mit mir zu schwimmen.

Wir fordern mehr Aufmerksamkeit für umfallende Reissäcke! Bild