How to create a plugin for OsiriX ?

This page will give you all the information you need to create your own OsiriX plugin (.osirixplugin file extension) to add new features or specific functionalities to OsiriX MD.

Requirements

Before starting, make sure you have:

  • Xcode – Xcode is the tool used to develop OsiriX plugins. Get Xcode on Apple website.
  • OsiriX MD – You need to download and install OsiriX MD. Get it from your account.
  • OsiriXAPI.frameworkShow Package ContentsContains all the headers for accessing OsiriX API from your plugin. It is located in OsiriX MD/Contents/Frameworks: to access it, right-click on OsiriX MD and select Show Package Contents,
 then go to Contents/Frameworks. You will have to copy the OsiriXAPI.framework to your plugin folder (see below).

Getting Started

To develop a plugin you have 2 options (see bellow):

  • Option A : Use a template project
  • Option B : Manually create your Xcode project

Option A : Use a template project 🚀

  • Download the template project:
  • Copy the OsiriXAPI.framework in your MyOsiriXPluginFolder folder.
  • To debug your plugin, create an alias of your compiled plugin (.osirixplugin extension) in:
 /Library/Application Support/OsiriX/Plugins.
    Important: do not use the Users Application Support folder (~/Library/Application Support/OsiriX/Plugins), because of permissions issues.

Option B : Manually create your Xcode project 🤓

  • Launch Xcode, and create a new project: File > New > Project…
  • Copy the OsiriXAPI.framework in your MyOsiriXPluginFolder folder.
  • Create a Plugin.m and Plugin.h files (for Objective-C) or a Plugin.swift file (for Swift) in your Xcode folder, and add them to your project:


Plugin.m file:

#import “Plugin.h”

// You can then import different API headers to use the OsiriX functions.

// These headers are stored in the OsiriXAPI framework folder

#import <OsiriXAPI/BrowserController.h>

#import <OsiriXAPI/DicomStudy.h>

#import <OsiriXAPI/DicomSeries.h>

#import <OsiriXAPI/DicomStudy+Report.h>

#import <OsiriXAPI/DicomDatabase.h>

#import <OsiriXAPI/WebPortal.h>

#import <OsiriXAPI/NSManagedObject+N2.h>

#import <OsiriXAPI/WebPortalUser.h>

#import <OsiriXAPI/WebPortalStudy.h>

#import <OsiriXAPI/WebPortalConnection.h>

#import <OsiriXAPI/WebPortalConnection+Data.h>

#import <OsiriXAPI/WebPortal.h>

#import <OsiriXAPI/WebPortal+Email+Log.h>

#import <OsiriXAPI/WebPortalResponse.h>

#import <OsiriXAPI/WebPortalDatabase.h>

#import <OsiriXAPI/AsyncSocket.h>

#import <OsiriXAPI/QueryController.h>

@implementation YOURPLUGINCLASS

– (long) filterImage: (NSString*) menuName {

    

    if( [menuName containsString: @”Settings”]) {

        

        [NSApp beginSheet: myWindow modalForWindow: nil modalDelegate:self didEndSelector:@selector( settingsDidEnd:returnCode:contextInfo:) contextInfo: nil];

        [myWindow orderFront:self];

    }

    

return 0;

}

– (IBAction)okButton: (id)sender {

    [myWindow close];

}

– (void) initPlugin

{

    // Instantiate the Settings xib file

    [NSBundle loadNibNamed: @”Settings” owner:self];

    

    NSLog( @”Hello from my plugin. This function is executed when OsiriX launches.”);

}

@end

Plugin.h file:

#import <Foundation/Foundation.h>

#import <OsiriXAPI/PluginFilter.h>

@interface YOURPLUGINCLASS : PluginFilter

{

    IBOutlet NSWindow *myWindow;

}

– (long) filterImage: (NSString*) menuName;

@end

Plugin.swift file:


import Foundation

class YOURPLUGINCLASS: PluginFilter {

    @IBOutlet var myWindow: NSWindow!

    

    override func filterImage(_ menuName: String!) -> Int {

        

        if( menuName == “Settings”) {

            NSApp.beginSheet( myWindow, modalFor: BrowserController.currentBrowser().window!, modalDelegate: nil, didEnd: nil, contextInfo: nil)

        }

        

        return 0 // no error

    }

    

    @IBAction func okButton(_ sender: Any) {

        myWindow.close()

    }

    

    override func initPlugin() {

        let bundle = Bundle.init( identifier: “com.rossetantoine.OsiriXTestPlugin”)

        bundle?.loadNibNamed( “Settings”, owner: self, topLevelObjects:  nil)

        NSLog( “Hello from my plugin. This function is executed when OsiriX launches.”)

    }

}

  • Change the Wrapper Extension to osirixplugin in Build Settings.

  • Define the Principal Class to your YOURPLUGINCLASS (see Plugin.m and Plugin.h, or Plugin.swift) in Build Settings.

  • Add -undefined dynamic_lookup in the Other Linker Flags in Build Settings.
  • Define plugin type, and menu names in Info. You can add several menu items in the MenuTitle key, and use the following types for the pluginType key: Database, Report, imageFilter, roiTool or other.
  • To debug your plugin, create an alias of your compiled plugin (.osirixplugin extension) in:
 /Library/Application Support/OsiriX/Plugins.
    Important: do not use the Users Application Support folder (~/Library/Application Support/OsiriX/Plugins), because of permissions issues.

Examples

To fully explore the potential of OsiriX plugins, directly explore the header files in the OsiriXAPI.framework package. You can also browse many plugins examples on GitHub. Examples of third party plugins are listed on this page.