Skip to content

Commit

Permalink
Merge pull request #16 from GeorgLegato/15-add-first-cubemap-support-…
Browse files Browse the repository at this point in the history
…into-sendto

15 add first cubemap support into sendto
  • Loading branch information
GeorgLegato authored Mar 21, 2023
2 parents f3d6b42 + 02b6173 commit 9ac63ee
Show file tree
Hide file tree
Showing 4 changed files with 251 additions and 56 deletions.
3 changes: 2 additions & 1 deletion javascript/pano_hints.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

pano_titles = {
"Pano 👀":"Send to Panorama Viewer Tab",
"Pano 🌐": "Switch between selected image and panorama view"
"Pano 🌐": "Switch between selected image and Equirectangular view",
"Pano 🧊": "Switch between selected image and CubeMap view"
}


Expand Down
165 changes: 124 additions & 41 deletions javascript/panoramaviewer-ext.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const openpanorama = {

let galImageDisp

function panorama_here(phtml) {
function panorama_here(phtml, mode, buttonId) {
return async () => {
try {
const tabContext = get_uiCurrentTab().innerText
Expand All @@ -28,7 +28,13 @@ function panorama_here(phtml) {
let galImage = gradioApp().querySelector(containerName + " div > img")

if (galviewer) {
// not the tab... openpanorama.frame.contentWindow.postMessage({

galviewer.contentWindow.postMessage({
type: "panoramaviewer/destroy"
})
galviewer.parentElement.removeChild(galviewer)

if (galImage) galImage.style.display = galImageDisp
return
}
Expand All @@ -54,12 +60,13 @@ function panorama_here(phtml) {
let parent = galImage.parentElement
//let parent = gradioApp().querySelector(containerName+" > div") // omg

let iframe = document.createElement('iframe');
let iframe = document.createElement('iframe')
iframe.src = phtml
iframe.id = "panogalviewer-iframe" + tabContext
iframe.classList += "panogalviewer-iframe"
iframe.setAttribute("panoimage", galImage.src);
parent.appendChild(iframe);
iframe.setAttribute("panoimage", galImage.src)
iframe.setAttribute("panoMode", mode)
parent.appendChild(iframe)
galImageDisp = galImage.style.display
galImage.style.display = "none"
}
Expand All @@ -78,6 +85,16 @@ function panorama_send_image(dataURL, name = "Embed Resource") {
});
}

function panorama_change_mode(mode) {
return () => {
openpanorama.frame.contentWindow.postMessage({
type: "panoramaviewer/change-mode",
mode: mode
})
}
}


function panorama_change_container(name) {
openpanorama.frame.contentWindow.postMessage({
type: "panoramaviewer/set-container",
Expand Down Expand Up @@ -146,66 +163,132 @@ function panorama_send_gallery(name = "Embed Resource") {
});
}


function openpanoramajs() {
const frame = gradioApp().getElementById("panoviewer-iframe");
openpanorama.frame = frame;
}


function setPanoFromDroppedFile(file) {
reader = new FileReader();
console.log(file)
reader.onload = function (event) {
panoviewer.setPanorama(event.target.result)
}
reader.readAsDataURL(file);
reader = new FileReader();
console.log(file)
reader.onload = function (event) {
panoviewer.setPanorama(event.target.result)
}
reader.readAsDataURL(file);
}

function dropHandler(ev) {
// File(s) dropped
// Prevent default behavior (Prevent file from being opened)
ev.preventDefault();

if (ev.dataTransfer.items) {
// Use DataTransferItemList interface to access the file(s)
[...ev.dataTransfer.items].forEach((item, i) => {

// If dropped items aren't files, reject them
if (item.kind === "file") {
const file = item.getAsFile();
console.log(`… file[${i}].name = ${file.name}`);
if (i === 0) { setPanoFromDroppedFile(file) }

}
});
} else {
// Use DataTransfer interface to access the file(s)
[...ev.dataTransfer.files].forEach((file, i) => {
if (i === 0) { setPanoFromDroppedFile(file) }
console.log(`… file[${i}].name = ${file.name}`);
});
}
// File(s) dropped
// Prevent default behavior (Prevent file from being opened)
ev.preventDefault();

if (ev.dataTransfer.items) {
// Use DataTransferItemList interface to access the file(s)
[...ev.dataTransfer.items].forEach((item, i) => {

// If dropped items aren't files, reject them
if (item.kind === "file") {
const file = item.getAsFile();
console.log(`… file[${i}].name = ${file.name}`);
if (i === 0) { setPanoFromDroppedFile(file) }

}
});
} else {
// Use DataTransfer interface to access the file(s)
[...ev.dataTransfer.files].forEach((file, i) => {
if (i === 0) { setPanoFromDroppedFile(file) }
console.log(`… file[${i}].name = ${file.name}`);
});
}
}

function dragOverHandler(ev) {
// Prevent default behavior (Prevent file from being opened)
ev.preventDefault();
// Prevent default behavior (Prevent file from being opened)
ev.preventDefault();
}



function onPanoModeChange(x) {
console.log("Panorama Viewer: PanMode change to: " + x.target.value)
}


function onGalleryDrop(ev) {

const triggerGradio = (g, file) => {
reader = new FileReader();
reader.onload = function (event) {
g.value = event.target.result
g.dispatchEvent(new Event('input'));
}
reader.readAsDataURL(file);
}

ev.preventDefault();

let g = gradioApp().querySelector("div[id^='gallery_input_ondrop'] textarea")

if (ev.dataTransfer.items && g) {
// Use DataTransferItemList interface to access the file(s)
[...ev.dataTransfer.items].forEach((item, i) => {

// If dropped items aren't files, reject them
if (item.kind === "file") {
const file = item.getAsFile();
console.log(`… file[${i}].name = ${file.name}`);
if (i === 0) { triggerGradio(g, file) }

}
});
} else {
// Use DataTransfer interface to access the file(s)
[...ev.dataTransfer.files].forEach((file, i) => {
if (i === 0) { triggerGradio(file) }
console.log(`… file[${i}].name = ${file.name}`);
});
}

}


document.addEventListener("DOMContentLoaded", () => {
const onload = () => {
if (gradioApp().getElementById("panoviewer-iframe")) {
openpanoramajs();
} else {
setTimeout(onload, 10);
if (gradioApp) {

let target = gradioApp().getElementById("txt2img_results")
if (!target) {
setTimeout(onload, 5);
return
}
target.addEventListener("drop", onGalleryDrop)
target.addEventListener("dragover", (event) => {
event.preventDefault();
});

// completely hide the transfer textbox and its container
let alldrops = gradioApp().querySelectorAll("div[id^='gallery_input_ondrop']")
alldrops.forEach((e) => {
e.parentElement.style.display = "none"
})

/* no tab anymore, no functionality
if (gradioApp().getElementById("panoviewer-iframe")) {
openpanoramajs();
} else {
setTimeout(onload, 10);
}
*/
}
else {
setTimeout(onload, 3);
}
};
onload();
});





79 changes: 70 additions & 9 deletions scripts/panorama-3dviewer.py
Original file line number Diff line number Diff line change
@@ -1,27 +1,88 @@
from modules import script_callbacks, scripts, shared
import os
import html
from modules import script_callbacks, shared
import gradio as gr
import base64
import io
from PIL import Image

usefulDirs = scripts.basedir().split(os.sep)[-2:]
iframesrc = "file="+usefulDirs[0]+"/"+usefulDirs[1]+"/scripts/viewer.html"

# js 2 gradio messaging?! how to do better?
gallery_input_ondrop=None
txt2img_gallery_component=None

def data_url_to_image(data_url):
comma_position = data_url.find(',')
base64_data = data_url[comma_position + 1:]
image_data = base64.b64decode(base64_data)
image_stream = io.BytesIO(image_data)
image = Image.open(image_stream)
return image


def onPanModeChange(m):
print ("mode changed to"+str(m))


def add_tab():
with gr.Blocks(analytics_enabled=False) as ui:
gr.HTML(value=f"<iframe id=\"panoviewer-iframe\" class=\"border-2 border-gray-200\" src=\"{iframesrc}\" title='description'></iframe>")
return [(ui, "Panorama Viewer", "panorama-3dviewer")]
with gr.Column():
selectedPanMode = gr.Dropdown(choices=["Equirectangular", "Cubemap: Polyhedron net"],value="Equirectangular",label="Select projection mode", elem_id="panoviewer_mode")
gr.HTML(value=f"<iframe id=\"panoviewer-iframe\" class=\"border-2 border-gray-200\" src=\"{iframesrc}\" title='description'></iframe>")

selectedPanMode.change(fn=onPanModeChange, inputs=[selectedPanMode],outputs=[], _js="panorama_change_mode(\""+selectedPanMode.value+"\")")
# unless we have functionality in this tab. Gallery-Viewer should be sufficient if not easier.
# return [(ui, "Panorama Viewer", "panorama-3dviewer")]
return []


def dropHandleGallery(x):
if (None != txt2img_gallery_component):
list = txt2img_gallery_component.value
img = data_url_to_image(x)
list.append(img)
return list


def after_component(component, **kwargs):
# Add button to both txt2img and img2img tabs
global gallery_input_ondrop
global txt2img_gallery_component

# Add our buttons after each "send to extras" button
if kwargs.get("elem_id") == "extras_tab":

# with gr.Row(elem_id="pano_sendbox",variant="compact", css="justify-content: center; align-content: flex-end;"):
basic_send_button = gr.Button("Pano \U0001F440", elem_id=f"sendto_panorama_button") # 👀
view_gallery_button = gr.Button ("Pano \U0001F310", elem_id="sendto_panogallery_button") # 🌐

basic_send_button.click(None, [], None, _js="() => panorama_send_gallery('WebUI Resource')")
basic_send_button.__setattr__("class","gr-button")
view_gallery_button.click (None, [],None, _js="panorama_here(\""+iframesrc+"\")")
# DISABLED until we get some functionality here, two button for Equi and Cubemap is currently enough
#send2tab_button = gr.Button ("Pano \U0001F440", elem_id=f"sendto_panorama_button") # 👀
#send2tab_button.click(None, [], None, _js="() => panorama_send_gallery('WebUI Resource')")
#send2tab_button.__setattr__("class","gr-button")
suffix = component.parent.elem_id

if (suffix):
print ("Panorama_Viewer: adding sendto button in parent_elem_id: "+suffix)
view_gallery_button = gr.Button ("Pano \U0001F310", elem_id="sendto_panogallery_button_"+suffix) # 🌐
view_cube_button = gr.Button ("Pano \U0001F9CA", elem_id="sendto_panogallery_cube_button_"+ suffix) # 🧊
gallery_input_ondrop = gr.Textbox(visible=False, elem_classes="gallery_input_ondrop", elem_id="gallery_input_ondrop_"+ suffix)
gallery_input_ondrop.style(container=False)

view_gallery_button.click (None, [],None, _js="panorama_here(\""+iframesrc+"\",\"\",\""+view_gallery_button.elem_id+"\")" )
view_cube_button.click (None, [],None, _js="panorama_here(\""+iframesrc+"\",\"cubemap\",\""+view_cube_button.elem_id+"\")" )

if (gallery_input_ondrop and txt2img_gallery_component):
gallery_input_ondrop.change(fn=dropHandleGallery, inputs=[gallery_input_ondrop], outputs=[txt2img_gallery_component])


if kwargs.get("elem_id") == "txt2img_gallery":
print ("Panorama Viewer: enable file-drag-and-drop into txt2img gallery...")

txt2img_gallery_component = component

if (gallery_input_ondrop and txt2img_gallery_component):
gallery_input_ondrop.change(fn=dropHandleGallery, inputs=[gallery_input_ondrop], outputs=[txt2img_gallery_component])


script_callbacks.on_ui_tabs(add_tab)
script_callbacks.on_after_component(after_component)
Loading

0 comments on commit 9ac63ee

Please sign in to comment.