Seite 1 von 1

Eigenes XnView Plugin erstellen

Verfasst: 19.09.2009 16:08
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