Screenshot of the Reference Tabs docker, small to show the UI. Reference image pictured: “Kiki’s “not-really-official” Reference Sheet (2016)” by Tyson Tan
This plugin is a docker that lets you view reference images in tabs. It allows zooming, scrolling, mirroring, rotating, and color sampling, among other things:
Loading many file formats, including KRA, thanks to Krita’s extended QImage.
Drag-and-drop of images into the docker.
Switching between Smooth and Sharp scaling modes.
Changing background color behind transparent images.
Key+mouse-drag shortcuts for Pan (Space), Zoom (Control+Space), and Rotate (Shift+Space).
More details can be found in the plugin’s Manual.html.
Feedback, suggestions, and modifications are welcome.
I originally made this plugin for myself, but a few of the current features were requested here in this thread. There’s still plenty of room for improvement.
The original, outdated version of the post
Backstory:
I prefer to view reference images in a separate window, so I made myself a docker for viewing reference images with the goal of being similar to viewing them in a web browser; having images in tabs, and being able to zoom, scroll, and mirror the images.
referencing one of Krita’s previous splash screens, Blooming II by Tyson Tan, to draw some fanart of Kiki.
There are still some issues and things that could be improved, but I figured I would share it the way it is now in case anyone’s interested rather than waiting until I get around to working on it again.
Yep, its pretty good - even if its still beta. And with some layout tweaking even works on mobile [even though not really designed there].
There’s just occasional , like this plugin, where i go - i wish i could use that here.
Corrected a TypeError when fitting the zoom, which was triggered on newer versions of Krita (5.2 prealpha).
Plus a bugfix from a few months ago:
Corrected menu behavior on macOS, so the plugin uses its own menu instead of overriding Krita’s.
If you encounter either of these issues, you can redownload the plugin, or apply the fixes from the commits yourself (they’re both single-lines changes), using the links in the first post.
I’ve pushed a few new changes to my repository; the short version is that you can now drag-and-drop images, and that the file dialog will remember what folder was open after restart.
Changes:
Correctly free memory when closing a tab. Previously there might have been some leaking of the tab widget.
Add menu actions to close All, Left, and Right tabs, instead of just the current tab.
Added support for drag-and-dropping images. Currently the image(s) will always open in new tabs.
Remember the last opened folder in the file dialog after restarting, by saving it into Krita’s kritarc config file.
This plugin is still a work in progress. Here’s my current todo list of some other things I’ve been working on but haven’t finished:
Potential todo:
I’d like to add some sort of option to drag-and-drop a single image into an existing tab, instead of always a new tab. Possibly along with the ability to drag a single image into the tabbar instead to have it open in a new tab.
There are some issues with loading a new image into an existing tab, where the config isn’t set up properly. Ideally there should be a way to load a new image in an existing tab with either the existing config or the default config.
I’d like to add other config options. For instance, a setting to use smooth scaling or not (per image).
I’ve looked into adding the ability to scroll past the image bounds (to view the top of the image at the bottom of the docker, for instance), and also a way to only scale the part of the image that is being shown, because zooming in closely on the entirety of a large image uses a lot of memory. But I haven’t gotten those figured out yet.
As I start to make more significant changes, I wonder if I should come up with some sort of versioning system, at least to save the commit hash somewhere, so it’s possible to easily know which version you’re using.
But for now, I didn’t want to let these useful commits pile up locally until I forgot about them.
If we could have the same shortcuts that are used in the canvas it would be very nice (Space/Middle Click, Ctrl + Space (Middle click)/Scroll, Shift + Space (Middle Click)).
Krita’s zoom and angle selector widgets are custom and can’t be used from Python, unless I were to try and port them over. Since they’re fairly complicated widgets, that might be a bit of work. (Though the angle selector is really nice.)
I’m not very familiar with the canvas input zoom/pan/rotate mode shortcuts (personally I use scrolling to zoom, scrollbars for panning, and the angle selector for rotation), but adding them should probably be doable.
Oh I see, I didn’t know that, another option would be to do what was done in Kanvasbuddy.
Yay!
By the way, this plugin reminds me a little of one of the panels that CSP has, I leave it here for reference, although its plugin already does almost everything that the CSP panel does.
AttributeError
Python 3.9.12: /Users/sydniwilson/Desktop/krita.app/Contents/MacOS/krita
Sat May 27 21:58:45 2023
A problem occurred in a Python script. Here is the sequence of
function calls leading up to the error, in the order they occurred.
/Users/sydniwilson/Library/Application Support/krita/pykrita/reference_tabs/reference_tabs.py in toggle_hmirror(self=<reference_tabs.reference_tabs.ReferenceViewer object>)
139
140 def toggle_hmirror(self):
141 self.transformedImage = self.transformedImage.mirrored(True,False)
142 self.reloadPixmap()
143 def toggle_vmirror(self):
self = <reference_tabs.reference_tabs.ReferenceViewer object>
self.transformedImage undefined
AttributeError: 'ReferenceViewer' object has no attribute 'transformedImage'
__cause__ = None
__class__ = <class 'AttributeError'>
__context__ = None
__delattr__ = <method-wrapper '__delattr__' of AttributeError object>
__dict__ = {}
__dir__ = <built-in method __dir__ of AttributeError object>
__doc__ = 'Attribute not found.'
__eq__ = <method-wrapper '__eq__' of AttributeError object>
__format__ = <built-in method __format__ of AttributeError object>
__ge__ = <method-wrapper '__ge__' of AttributeError object>
__getattribute__ = <method-wrapper '__getattribute__' of AttributeError object>
__gt__ = <method-wrapper '__gt__' of AttributeError object>
__hash__ = <method-wrapper '__hash__' of AttributeError object>
__init__ = <method-wrapper '__init__' of AttributeError object>
__init_subclass__ = <built-in method __init_subclass__ of type object>
__le__ = <method-wrapper '__le__' of AttributeError object>
__lt__ = <method-wrapper '__lt__' of AttributeError object>
__ne__ = <method-wrapper '__ne__' of AttributeError object>
__new__ = <built-in method __new__ of type object>
__reduce__ = <built-in method __reduce__ of AttributeError object>
__reduce_ex__ = <built-in method __reduce_ex__ of AttributeError object>
__repr__ = <method-wrapper '__repr__' of AttributeError object>
__setattr__ = <method-wrapper '__setattr__' of AttributeError object>
__setstate__ = <built-in method __setstate__ of AttributeError object>
__sizeof__ = <built-in method __sizeof__ of AttributeError object>
__str__ = <method-wrapper '__str__' of AttributeError object>
__subclasshook__ = <built-in method __subclasshook__ of type object>
__suppress_context__ = False
__traceback__ = <traceback object>
args = ("'ReferenceViewer' object has no attribute 'transformedImage'",)
with_traceback = <built-in method with_traceback of AttributeError object>
The above is a description of an error in a Python program. Here is
the original traceback:
Traceback (most recent call last):
File "/Users/sydniwilson/Library/Application Support/krita/pykrita/reference_tabs/reference_tabs.py", line 141, in toggle_hmirror
self.transformedImage = self.transformedImage.mirrored(True,False)
AttributeError: 'ReferenceViewer' object has no attribute 'transformedImage'
I received a an error from @freyalupen reference tab plugin:This occurred when I was trying to flip my reference image vertically/horizontally with the flip buttons. I tried fixing the code with ChatGPT’s help but nothing worked.
AttributeError
Python 3.9.12: /Users/sydniwilson/Desktop/krita.app/Contents/MacOS/krita
Sat May 27 21:58:45 2023
A problem occurred in a Python script. Here is the sequence of
function calls leading up to the error, in the order they occurred.
/Users/sydniwilson/Library/Application Support/krita/pykrita/reference_tabs/reference_tabs.py in toggle_hmirror(self=<reference_tabs.reference_tabs.ReferenceViewer object>)
139
140 def toggle_hmirror(self):
141 self.transformedImage = self.transformedImage.mirrored(True,False)
142 self.reloadPixmap()
143 def toggle_vmirror(self):
self = <reference_tabs.reference_tabs.ReferenceViewer object>
self.transformedImage undefined
AttributeError: 'ReferenceViewer' object has no attribute 'transformedImage'
__cause__ = None
__class__ = <class 'AttributeError'>
__context__ = None
__delattr__ = <method-wrapper '__delattr__' of AttributeError object>
__dict__ = {}
__dir__ = <built-in method __dir__ of AttributeError object>
__doc__ = 'Attribute not found.'
__eq__ = <method-wrapper '__eq__' of AttributeError object>
__format__ = <built-in method __format__ of AttributeError object>
__ge__ = <method-wrapper '__ge__' of AttributeError object>
__getattribute__ = <method-wrapper '__getattribute__' of AttributeError object>
__gt__ = <method-wrapper '__gt__' of AttributeError object>
__hash__ = <method-wrapper '__hash__' of AttributeError object>
__init__ = <method-wrapper '__init__' of AttributeError object>
__init_subclass__ = <built-in method __init_subclass__ of type object>
__le__ = <method-wrapper '__le__' of AttributeError object>
__lt__ = <method-wrapper '__lt__' of AttributeError object>
__ne__ = <method-wrapper '__ne__' of AttributeError object>
__new__ = <built-in method __new__ of type object>
__reduce__ = <built-in method __reduce__ of AttributeError object>
__reduce_ex__ = <built-in method __reduce_ex__ of AttributeError object>
__repr__ = <method-wrapper '__repr__' of AttributeError object>
__setattr__ = <method-wrapper '__setattr__' of AttributeError object>
__setstate__ = <built-in method __setstate__ of AttributeError object>
__sizeof__ = <built-in method __sizeof__ of AttributeError object>
__str__ = <method-wrapper '__str__' of AttributeError object>
__subclasshook__ = <built-in method __subclasshook__ of type object>
__suppress_context__ = False
__traceback__ = <traceback object>
args = ("'ReferenceViewer' object has no attribute 'transformedImage'",)
with_traceback = <built-in method with_traceback of AttributeError object>
The above is a description of an error in a Python program. Here is
the original traceback:
Traceback (most recent call last):
File "/Users/sydniwilson/Library/Application Support/krita/pykrita/reference_tabs/reference_tabs.py", line 141, in toggle_hmirror
self.transformedImage = self.transformedImage.mirrored(True,False)
AttributeError: 'ReferenceViewer' object has no attribute 'transformedImage'```
I think it would have been enough to post this only once, and wait till @freyalupen answers. This request for support with that particular plugin does not need to be spread over two topics.
This forum is an international forum with users from around the world and not everywhere shines the sun at the same time, because the earth isn’t flat, so some may sleep when you are active. These users do their work in and for the forum as voluntary work, and most of them have some kind of job and also a life beside this forum.
So please be patient, you’ll get an answer when the person who has an answer will answer, we don’t sit in front of our devices waiting to answer every question without waiting-time, there exists a life beside Krita and this forum. Even if you may need this plugin right now urgently and can’t wait, some things need time. I hope you understand this.