Sublime Forum

Image view/preview API

#1

Hi,
I like to write a plugin that while edit a file (eg: json file) that specifies an image path, open that image in a new tab (on different row or col). ST3 can view an image if I open the image, what I need is the API to do so.

Any help is appreciated.
thanks.

0 Likes

#2

I’m not aware of any API functions to show previews except for the quick panel preview.

You could try something like this that shows the quick panel with one entry (the image from your json file) and previews it, then hides the preview when the quick panel is closed. It is a bit of a hack but should work…

class PreviewImageCommand(sublime_plugin.TextCommand):
    def run(self, edit):
        # Get the file path from the json file
        imagepath = '/path/to/image.jpg'
        self.files = [imagepath]
        sublime.active_window().show_quick_panel(self.files, lambda s: self.on_done(s), selected_index=0, on_highlight=lambda s: self.show_preview(s) )

    def on_done(self, index):
        sublime.active_window().focus_view( self.view )

    def show_preview(self, index):
        if index >= 0:
            file_path = self.files[index]
            sublime.active_window().open_file(file_path, sublime.TRANSIENT)
0 Likes

#3

HI there
Nowadays,there are mant third party Image SDK which provides comprehensive and powerful APIs for developers to view image, edit, annotate and process variable image and document formats in commonly used modern browsers, such as IE, Chrome, Firefox, and Safari. So you can just google for it.Most of them offer a free trial for new users.So you can just try the free trial to help you out.Hope to help you.

0 Likes

#4

Thank you for the quick and helpful reply, jbjornson, the code pointed me to the right direction.

For future readers, here’s the solution and details:

ST3 doesn’t really have an “image view” API, it just “opens” it like any other files. And I think that’s a good thing. Below is the code, which is for my specific use case. In run(), defaults are set (best practice is to set them in a settings file), where file_path_label specifies the file to be opened in a new view in new row, and common_path specifies the common path of viewed file and file to open. open_new_row() opens the file in new row if there isn’t one already.

import sublime, sublime_plugin, io, os

class ViewLabeledFileCommand(sublime_plugin.TextCommand):
    def run(self, edit):
        file_path_label = 'imgurl: '  # label for path to file to open
        common_path = 'articles'  # common path of viewed file and file to open
        max_files = 1

        selection = sublime.Region(0, self.view.size())
        text = self.view.substr(selection)
        buf = io.StringIO(text)
        sep = os.sep
        line = buf.readline()
        files = ]
        while line:
            if file_path_label in line:
                relpath = line.split(': ')[1]
                rootpath = self.view.file_name().split(sep+common_path+sep)[0]
                path = os.path.join(rootpath, relpath.strip().strip(sep))
                files.append(path)
                if len(files) >= max_files:
                    break
            line = buf.readline()
        self.open_new_row(files)

    def open_new_row(self, files):
        window = sublime.active_window()
        ngroups = window.num_groups() 

        # create new row if there isn't one
        if ngroups == 1:
            window.run_command('set_layout', # 2 rows
             { "rows": [0, 0.5, 1], "cols": [0, 1], "cells": [0,0,1,1],[0,1,1,2]] })
        active_group = window.active_group()
        self.group = active_group
        other_group = 1 if active_group==0 else 0
        window.focus_group(other_group)
        if len(files) == 1:
            window.open_file(files[0], sublime.TRANSIENT)
        else:
            self.files = files
            window.show_quick_panel(self.files,
             self.files, lambda i: self.on_done(i), selected_index=0,
             on_highlight=lambda i: self.show_preview(i) )
        window.focus_group(self.group)
        window.focus_view(self.view)

    def on_done(self, index):
        # doesn't seem to be called
        sublime.active_window().focus_view(self.view)

    def show_preview(self, index):
        if index >= 0:
            file_path = self.files[index]
            sublime.active_window().open_file(file_path, sublime.TRANSIENT)

I actually wanted to code this in on_load() EventListener instead of TextCommand, based on file type loaded (eg. json, md, etc.) so I don’t have to type in a command. But it doesn’t work with goto anything search since the file is actually loaded during smart file find, so any continuation of typing in the goto anything panel results in typing in the newly opened file instead. To make it work, I’ll either need to disable file preview on goto anything search, or bring focus back to the input panel, both of which doesn’t seem to be available. If anyone knows, please reply.

thanks.
john

0 Likes

#5

I didn’t review your code but based of your explication of the issue I think you can use something similar to this code:
https://github.com/bizoo/SortTabs/blob/master/auto_sort_tabs.py

In brief, the on_load event define a setting in the view to tell it must be processed and the on_activated event check this setting (and remove it) and process the view.

0 Likes