Skip to content

Commit

Permalink
Multiple Fixes (#9)
Browse files Browse the repository at this point in the history
* changed some comments

* removed water mark, removed double and tripple loading

* more changes; can't test because PyPi is down

* added vendor submodule

* vendor gets fail

* added jinja2

* broken build

* loading juxtapose locally

* fixed CSS

* using pathlib

Co-authored-by: Jan-Hendrik Müller <44469195+kolibril13@users.noreply.github.com>

* importing pathlib

Co-authored-by: Jan-Hendrik Müller <44469195+kolibril13@users.noreply.github.com>

* adding four pixels

Co-authored-by: Jan-Hendrik Müller <44469195+kolibril13@users.noreply.github.com>

* Developer Installation in readme

* small fixes

* Update README.md

Co-authored-by: Jan-Hendrik Müller <44469195+kolibril13@users.noreply.github.com>

Co-authored-by: Jan-Hendrik Müller <44469195+kolibril13@users.noreply.github.com>
  • Loading branch information
christopher-besch and kolibril13 authored Jun 13, 2022
1 parent e0ca31b commit 850efc7
Show file tree
Hide file tree
Showing 8 changed files with 520 additions and 42 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "vendor/juxtapose"]
path = vendor/juxtapose
url = https://github.com/NUKnightLab/juxtapose
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,15 @@ Formatting with black can be done this way:
2. `black --python-cell-magics splity splitview_magic.ipynb`


## Developer Installation

1. `git clone --recurse https://github.com/kolibril13/jupyter-splitview`
(Note: In case that the repo was already cloned e.g. with the GitHub Desktop client, the GitHub submodule has to be loaded via `git submodule update --init --recursive` )
2. `poetry install`

## Changelog

## Milestones for >0.0.5
## Milestones for >0.0.5

* Handle cases where n ≠ 2 images. Currently: All further img are ignored.
* implement tests, find out how to test a magic class
Expand Down
435 changes: 414 additions & 21 deletions example_notebook.ipynb

Large diffs are not rendered by default.

20 changes: 18 additions & 2 deletions jupyter_splitview/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
from pathlib import Path

from .sw_cellmagic import SplitViewMagic
from IPython import get_ipython # register cell magic
from IPython import get_ipython
from IPython.core.display import HTML
from IPython.display import display
import pkg_resources

__version__: str = pkg_resources.get_distribution(__name__).version
Expand All @@ -10,5 +14,17 @@
ipy = get_ipython()
ipy.register_magics(SplitViewMagic)

css_path = Path(__file__).parents[1] / "vendor/juxtapose/build/css/juxtapose.css"
js_path = Path(__file__).parents[1] / "vendor/juxtapose/build/js/juxtapose.min.js"

html_code = f"""
<style>{css_path.read_text()}</style>
<script>{js_path.read_text()}</script>
"""
display(HTML(html_code))


except AttributeError:
print("Can not load SplitViewMagic because this is not a notebook")
print("Can not load SplitViewMagic because this is not a notebook")


43 changes: 43 additions & 0 deletions jupyter_splitview/inject.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<div id="splitview_wrapper_{{ cell_id }}">
<div id="splitview_{{ cell_id }}"></div>
</div>

<script>
slider = new juxtapose.JXSlider("#splitview_{{ cell_id }}",
[
{
src: "{{ image_data_urls[0] }}",
},
{
src: "{{ image_data_urls[1] }}",
}
],
{
animate: true,
showLabels: false,
showCredits: false,
startingPosition: "{{ slider_position }}",
makeResponsive: true,
// undocumented shit
callback: (jx_slider) => {
// remove juxtapose.js link and logo in bottom left corner
jx_slider.slider.removeChild(jx_slider.labCredit);
},
});
</script>

<style>
#splitview_wrapper_{{ cell_id }} {
position: relative;
padding-top: {{ wrapper_height }}px;
}

#splitview_{{ cell_id }} {
height: {{ height }}px;
width: auto;
top: 1%;
left: 1%;
position: absolute;
}
</style>

46 changes: 29 additions & 17 deletions jupyter_splitview/sw_cellmagic.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import io
import os
from base64 import b64decode

from IPython.core import magic_arguments
Expand All @@ -8,6 +9,15 @@
from IPython.utils.capture import capture_output
from PIL import Image

from jinja2 import Template, StrictUndefined

g_cell_id = 0

def compile_template(in_file: str, **variables) -> str:
with open(f"{in_file}", "r", encoding="utf-8") as file:
template = Template(file.read(), undefined=StrictUndefined)
return template.render(**variables)


@magics_class
class SplitViewMagic(Magics):
Expand All @@ -16,16 +26,15 @@ class SplitViewMagic(Magics):
"--position",
"-p",
default="50%",
help=("The position where the slider starts"),
help=("The start position of the slider"),
)
@magic_arguments.argument(
"--height",
"-h",
default="300",
help=(
"The height that the widget has. The width will be adjusted automatically. \
If height is choosen 'auto', the height will be defined by the resolution \
in vertical direction of the first image."
"The widget's height. The width will be adjusted automatically. \
If height is `auto`, the vertical resolution of the first image is used."
),
)
@cell_magic
Expand All @@ -43,7 +52,7 @@ def splity(self, line, cell):
png_bytes_data = data["image/png"]
out_images_base64.append(png_bytes_data)

# get the parameters the configure the widget
# get the parameters that configure the widget
args = magic_arguments.parse_argstring(SplitViewMagic.splity, line)

slider_position = args.position
Expand All @@ -53,17 +62,20 @@ def splity(self, line, cell):
imgdata = b64decode(out_images_base64[0])
# maybe possible without the PIL dependency?
im = Image.open(io.BytesIO(imgdata))
width, height = im.size
widget_height = height
widget_height = im.size[1]

html_code = f"""
<div class="outer_layer" style="position: relative; padding-top: {int(widget_height)+3}px;">
<div class="juxtapose" data-startingposition="{slider_position}" style="height: {int(widget_height)}px;; width: auto; top: 1%; left: 1%; position: absolute;">
<img src="data:image/jpeg;base64,{out_images_base64[0]}" />' <img src="data:image/jpeg;base64,{out_images_base64[1]}" />'
</div>
</div>
<script src="https://cdn.knightlab.com/libs/juxtapose/latest/js/juxtapose.min.js"></script>
<link rel="stylesheet" href="https://cdn.knightlab.com/libs/juxtapose/latest/css/juxtapose.css" />
"""
image_data_urls = [f"data:image/jpeg;base64,{base64.strip()}" for base64 in out_images_base64]

# every juxtapose html node needs unique id
global g_cell_id
html_code = compile_template(
os.path.join((os.path.dirname(__file__)), "inject.html"),
cell_id=g_cell_id,
image_data_urls=image_data_urls,
slider_position=slider_position,
wrapper_height=int(widget_height)+4,
height=int(widget_height),
)
g_cell_id += 1
display(HTML(html_code))

8 changes: 7 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,26 @@ version = "0.0.4"
description = "Making before/after image sliders in JupyterLab"
authors = ["kolibril13 <44469195+kolibril13@users.noreply.github.com>"]
license = "MIT"
include = [
"vendor/juxtapose/build/css/juxtapose.css",
"vendor/juxtapose/build/js/juxtapose.min.js",
]

[tool.poetry.dependencies]
python = ">=3.8,<3.11"
ipython = ">=7.0.0"
ipykernel = ">=6.13.0"
Pillow = ">=9.1.0"
Jinja2 = "^3.1.2"

[tool.poetry.dev-dependencies]
black = {extras = ["jupyter"], version = ">=22.3.0"}
black = { extras = ["jupyter"], version = ">=22.3.0" }
matplotlib = ">=3.5.1"
scipy = ">=1.8.0"
scikit-image = ">=0.19.2"
pytest = ">=7.1.2"
isort = ">=5.10.1"
jupyterlab = "^3.4.3"

[build-system]
requires = ["poetry-core>=1.0.0"]
Expand Down
1 change: 1 addition & 0 deletions vendor/juxtapose
Submodule juxtapose added at 975e8f

0 comments on commit 850efc7

Please sign in to comment.