final version
This commit is contained in:
parent
a610a2ac06
commit
2933dfc135
|
@ -1,6 +1,11 @@
|
|||
.idea
|
||||
image/dzi
|
||||
image/original
|
||||
image/script
|
||||
image/image.txt
|
||||
.venv
|
||||
image/dzi
|
||||
image/dzi_edited
|
||||
image/original
|
||||
image/script/bin
|
||||
image/script/include
|
||||
image/script/lib
|
||||
image/script/lib64
|
||||
image/script/pyvenv.cfg
|
||||
upload.sh
|
||||
annotations
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,18 +0,0 @@
|
|||
[{
|
||||
"@context": "http://www.w3.org/ns/anno.jsonld",
|
||||
"id": "#a88b22d0-6106-4872-9435-c78b5e890000",
|
||||
"type": "Annotation",
|
||||
"body": [{
|
||||
"type": "TextualBody",
|
||||
"value": "Nothing here yet!",
|
||||
"format" : "text/html",
|
||||
"language" : "en"
|
||||
}],
|
||||
"target": {
|
||||
"selector": {
|
||||
"type": "FragmentSelector",
|
||||
"conformsTo": "http://www.w3.org/TR/media-frags/",
|
||||
"value": "xywh=pixel:0,0,1000,1000"
|
||||
}
|
||||
}
|
||||
}]
|
|
@ -0,0 +1,13 @@
|
|||
#!/bin/bash
|
||||
source script/bin/activate
|
||||
|
||||
# Xvfb :99 -screen 0 1280x1024x24 &
|
||||
# export DISPLAY=:99
|
||||
|
||||
python3 script/generate_dzi_files.py
|
||||
python3 script/generate_images_txt.py
|
||||
python3 script/generate_filtered_photos.py
|
||||
python3 script/generate_annotations.py
|
||||
|
||||
sudo chmod -R 775 .
|
||||
sudo chown -R opc .
|
|
@ -0,0 +1,53 @@
|
|||
import json
|
||||
import uuid
|
||||
import requests
|
||||
|
||||
def get_post_data(folder_name):
|
||||
url = f"https://sketchersunited.org/posts/{folder_name.split('by')[0]}"
|
||||
headers = {"Accept": "text/json"}
|
||||
response = requests.get(url, headers=headers)
|
||||
if response.status_code == 200:
|
||||
return response.json()
|
||||
return None
|
||||
|
||||
with open('image.txt', 'r') as file:
|
||||
lines = file.readlines()
|
||||
|
||||
annotations = []
|
||||
|
||||
for line in lines:
|
||||
folder_name, x, y, _, _, _ = line.strip().split()
|
||||
annotation_id = str(uuid.uuid4())
|
||||
|
||||
post_data = get_post_data(folder_name)
|
||||
if post_data:
|
||||
annotation_text = f'🖼️ <a href="https://sketchersunited.org/posts/{post_data["post"]["id"]}">{post_data["post"]["title"]}</a> <br>👤 <a href="https://sketchersunited.org/users/{post_data["post"]["profile"]["id"]}">@{post_data["post"]["profile"]["username"]}</a>'
|
||||
else:
|
||||
annotation_text = "Data not available"
|
||||
|
||||
annotation = {
|
||||
"@context": "http://www.w3.org/ns/anno.jsonld",
|
||||
"id": f"#{annotation_id}",
|
||||
"type": "Annotation",
|
||||
"body": [{
|
||||
"type": "TextualBody",
|
||||
"value": annotation_text,
|
||||
"format": "text/html",
|
||||
"language": "en"
|
||||
}],
|
||||
"target": {
|
||||
"selector": {
|
||||
"type": "FragmentSelector",
|
||||
"conformsTo": "http://www.w3.org/TR/media-frags/",
|
||||
"value": f"xywh=pixel:{int(x)*1000},{int(y)*1000},1000,1000"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
annotations.append(annotation)
|
||||
print(f"Appended annotation for {folder_name}")
|
||||
|
||||
with open('../annotations/annotations.w3c.json', 'w') as output_file:
|
||||
json.dump(annotations, output_file, indent=2)
|
||||
|
||||
print("Annotations JSON file created.")
|
|
@ -12,7 +12,6 @@ def convert_to_jpg(input_file, output_dir):
|
|||
convert_command = ["convert", input_file, "-quality", "100", output_file]
|
||||
|
||||
subprocess.run(convert_command)
|
||||
print(f"Converted {input_file} to JPG")
|
||||
|
||||
process_image(output_file, output_dir)
|
||||
except Exception as e:
|
||||
|
@ -23,35 +22,27 @@ def process_image(input_file, output_dir):
|
|||
file_name_without_extension = os.path.splitext(os.path.basename(input_file))[0]
|
||||
output_file = os.path.join(output_dir, file_name_without_extension, f"{file_name_without_extension}")
|
||||
|
||||
command = ["./magick-slicer.sh", input_file, output_file]
|
||||
|
||||
print(command)
|
||||
print(output_file)
|
||||
print(os.getcwd())
|
||||
command = ["./script/magick-slicer.sh", input_file, output_file]
|
||||
|
||||
subprocess.run(command)
|
||||
print(f"Processed {input_file}")
|
||||
except Exception as e:
|
||||
print(f"Error processing {input_file}: {e}")
|
||||
|
||||
def main():
|
||||
input_dir = "original"
|
||||
output_dir = "dzi"
|
||||
|
||||
input_dir = "original"
|
||||
output_dir = "dzi"
|
||||
os.makedirs(output_dir, exist_ok=True)
|
||||
os.makedirs(os.path.join(input_dir, "jpg"), exist_ok=True)
|
||||
|
||||
os.makedirs(output_dir, exist_ok=True)
|
||||
os.makedirs(os.path.join(input_dir, "jpg"), exist_ok=True)
|
||||
image_files = []
|
||||
for root, _, files in os.walk(input_dir):
|
||||
for filename in files:
|
||||
if filename.lower().endswith((".jpg", ".jpeg", ".png", ".gif")):
|
||||
image_files.append(os.path.join(root, filename))
|
||||
|
||||
image_files = []
|
||||
for root, _, files in os.walk(input_dir):
|
||||
for filename in files:
|
||||
if filename.lower().endswith((".jpg", ".jpeg", ".png", ".gif")):
|
||||
image_files.append(os.path.join(root, filename))
|
||||
for input_file in image_files:
|
||||
convert_to_jpg(input_file, output_dir)
|
||||
|
||||
for input_file in image_files:
|
||||
convert_to_jpg(input_file, output_dir)
|
||||
|
||||
shutil.rmtree(os.path.join(input_dir, "jpg"))
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
shutil.rmtree(os.path.join(input_dir, "jpg"))
|
||||
print("Sliced all photos.")
|
|
@ -0,0 +1,36 @@
|
|||
from PIL import Image, ImageOps, ImageEnhance
|
||||
import os
|
||||
import shutil
|
||||
|
||||
with open('image.txt', 'r') as file:
|
||||
lines = file.readlines()
|
||||
|
||||
for line, folder_name in zip(lines, os.listdir('dzi')):
|
||||
folder_name, x, y, red, green, blue = line.strip().split()
|
||||
|
||||
original_folder_path = os.path.join('dzi', folder_name, folder_name + '_files')
|
||||
|
||||
edited_folder_path = os.path.join('dzi_edited', folder_name, folder_name + '_files')
|
||||
os.makedirs(edited_folder_path, exist_ok=True)
|
||||
|
||||
original_dzi_file_path = os.path.join('dzi', folder_name, f'{folder_name}.dzi')
|
||||
edited_dzi_file_path = os.path.join('dzi_edited', folder_name, f'{folder_name}.dzi')
|
||||
shutil.copy(original_dzi_file_path, edited_dzi_file_path)
|
||||
|
||||
for folder in os.listdir(original_folder_path):
|
||||
for filename in os.listdir(os.path.join(original_folder_path, folder)):
|
||||
original_image_path = os.path.join(original_folder_path, folder, filename)
|
||||
grayscale_image = ImageOps.grayscale(Image.open(original_image_path))
|
||||
|
||||
colormap = ImageOps.colorize(grayscale_image, black=(0, 0, 0), white=(int(red), int(green), int(blue)))
|
||||
|
||||
enhancer = ImageEnhance.Brightness(colormap)
|
||||
bright_colormap = enhancer.enhance(1.5)
|
||||
|
||||
edited_image_path = os.path.join(edited_folder_path, folder, filename)
|
||||
|
||||
os.makedirs(os.path.join(edited_folder_path, folder), exist_ok=True)
|
||||
bright_colormap.save(edited_image_path, quality=100)
|
||||
print("Processing " + folder_name)
|
||||
|
||||
print("Image processing completed.")
|
|
@ -0,0 +1,23 @@
|
|||
from PIL import Image
|
||||
import os
|
||||
|
||||
if os.path.exists("image.txt"):
|
||||
os.remove("image.txt")
|
||||
|
||||
su_image = Image.open("sureal25x25.png").convert("RGBA")
|
||||
su_pixels = su_image.load()
|
||||
|
||||
subfolder_names = sorted(os.listdir("dzi"))
|
||||
|
||||
with open("image.txt", "w") as output_file:
|
||||
for y in range(su_image.height):
|
||||
for x in range(su_image.width):
|
||||
r, g, b, a = su_pixels[x, y]
|
||||
|
||||
if a == 255:
|
||||
if subfolder_names:
|
||||
folder_name = subfolder_names.pop(0)
|
||||
output_file.write(f"{folder_name} {x} {y} {r} {g} {b}\n")
|
||||
else:
|
||||
print("Finished generating images txt")
|
||||
exit()
|
|
@ -0,0 +1,2 @@
|
|||
pillow
|
||||
requests
|
Binary file not shown.
After Width: | Height: | Size: 2.1 KiB |
Binary file not shown.
After Width: | Height: | Size: 1.9 KiB |
Binary file not shown.
After Width: | Height: | Size: 3.1 KiB |
|
@ -60,7 +60,7 @@
|
|||
|
||||
<h2>🌐 How do I use this page?</h2>
|
||||
<p>Use either the mouse wheel or your fingers to zoom in and out of the view.
|
||||
<br> You can tap on the image to see who drew it and get a link to the post.
|
||||
<br> (Not yet implemented) You can tap on the image to see who drew it and get a link to the post.
|
||||
<br>
|
||||
<br>ℹ️ The view may get somewhat laggy on a mobile device. For the best experience use a desktop computer.
|
||||
<br>This is unavoidable due to the number of images downloaded and shown.
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
const anno = OpenSeadragon.Annotorious(viewer);
|
||||
anno.readOnly = true
|
||||
anno.loadAnnotations('annotations/initial.w3c.json');
|
||||
anno.readOnly = true;
|
||||
anno.escape = false;
|
||||
anno.loadAnnotations('annotations/annotations.w3c.json');
|
||||
let annotationText = ""
|
||||
|
||||
function renderHTML()
|
||||
|
@ -25,4 +26,5 @@ anno.on('clickAnnotation', function(annotation, element)
|
|||
viewer.addHandler('update-viewport', function(event)
|
||||
{
|
||||
renderHTML()
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -2,8 +2,6 @@ let dictionaries = []
|
|||
const imagePromises = [];
|
||||
let image_count = 0
|
||||
|
||||
Caman.Store.put = function() {};
|
||||
|
||||
function load_image(image) {
|
||||
return new Promise((resolve, reject) => {
|
||||
viewer.addTiledImage({
|
||||
|
@ -31,17 +29,17 @@ fetch('image/image.txt')
|
|||
.then(text => {
|
||||
const lines = text.split('\n');
|
||||
lines.forEach(line => {
|
||||
if (!line.startsWith('#')) {
|
||||
if (!line.startsWith('#') && line.length > 0) {
|
||||
const parts = line.split(' ');
|
||||
|
||||
const dictionary = {
|
||||
imageCount: image_count,
|
||||
tileSource: 'image/dzi/' + parts[0] + '/' + parts[0] + '.dzi',
|
||||
tileSource: 'image/dzi_edited/' + parts[0] + '/' + parts[0] + '.dzi',
|
||||
x: parseInt(parts[1]),
|
||||
y: parseInt(parts[2]),
|
||||
red: parseInt(parts[3]),
|
||||
blue: parseInt(parts[4]),
|
||||
green: parseInt(parts[5]),
|
||||
green: parseInt(parts[4]),
|
||||
blue: parseInt(parts[5]),
|
||||
};
|
||||
|
||||
const promise = load_image(dictionary);
|
||||
|
@ -62,14 +60,13 @@ fetch('image/image.txt')
|
|||
processors: [
|
||||
function (context, callback) {
|
||||
Caman(context.canvas, function () {
|
||||
this.colorize(image.red, image.green, image.blue, 50);
|
||||
this.colorize(image.red, image.green, image.blue, 80);
|
||||
this.render(callback);
|
||||
});
|
||||
}
|
||||
// },
|
||||
},
|
||||
// function (context, callback) {
|
||||
// Caman(context.canvas, function () {
|
||||
// this.contrast(10);
|
||||
// this.contrast(100);
|
||||
// this.render(callback);
|
||||
// });
|
||||
// }
|
||||
|
@ -79,9 +76,9 @@ fetch('image/image.txt')
|
|||
all_filters.push(filter)
|
||||
});
|
||||
|
||||
viewer.setFilterOptions({
|
||||
filters: all_filters
|
||||
});
|
||||
// viewer.setFilterOptions({
|
||||
// filters: all_filters
|
||||
// });
|
||||
|
||||
|
||||
})
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
const clientCountElement = document.getElementById('clientCount');
|
||||
const socket = new WebSocket('ws://localhost:8080/funsocket');
|
||||
const socket = new WebSocket('wss://sketchersunitedcollab.com/funsocket');
|
||||
|
||||
socket.addEventListener('message', (event) => {
|
||||
const clientCount = parseInt(event.data);
|
||||
let append = " people"
|
||||
if (clientCount === 1) {
|
||||
append = " person"
|
||||
if(event.data.toString().length < 5) {
|
||||
const clientCount = parseInt(event.data);
|
||||
|
||||
let append = " people"
|
||||
if (clientCount === 1) {
|
||||
append = " person"
|
||||
}
|
||||
clientCountElement.textContent = clientCount.toString() + append;
|
||||
}
|
||||
clientCountElement.textContent = clientCount.toString() + append;
|
||||
});
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
Caman.Store.put = function() {};
|
||||
|
||||
const viewer = OpenSeadragon({
|
||||
id: "viewer",
|
||||
showZoomControl: false,
|
||||
|
@ -12,9 +14,9 @@ viewer.smartScrollZoom({
|
|||
zoomIncrement: 1000
|
||||
});
|
||||
|
||||
viewer.viewport.minZoomLevel = 0.0125;
|
||||
viewer.viewport.maxZoomLevel = 100;
|
||||
viewer.viewport.defaultZoomLevel = 0.0125;
|
||||
viewer.viewport.minZoomLevel = 0.001;
|
||||
viewer.viewport.maxZoomLevel = 2;
|
||||
viewer.viewport.defaultZoomLevel = 0.05;
|
||||
viewer.viewport.scrollHandlerSpeed = 1000;
|
||||
viewer.drawer.context.imageSmoothingEnabled = false;
|
||||
viewer.gestureSettingsMouse.clickToZoom = false;
|
||||
|
|
|
@ -12,7 +12,7 @@ body {
|
|||
background-color: #222;
|
||||
background-image: url("image/su.png");
|
||||
background-repeat: no-repeat;
|
||||
background-size: 1000px;
|
||||
background-size: 400px;
|
||||
background-position: center;
|
||||
image-rendering: pixelated;
|
||||
}
|
||||
|
@ -170,10 +170,10 @@ a {
|
|||
cursor: pointer;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1081px) {
|
||||
@media screen and (max-width: 1081px) and (-webkit-min-device-pixel-ratio: 2) {
|
||||
#viewer {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
height: 66vh;
|
||||
}
|
||||
#modal-content {
|
||||
font-size: 20pt;
|
||||
|
|
|
@ -15,7 +15,6 @@ class WebSocketHandler(tornado.websocket.WebSocketHandler):
|
|||
self.send_client_count()
|
||||
|
||||
def check_origin(self, origin):
|
||||
# Allow all connections regardless of the origin
|
||||
return True
|
||||
|
||||
def send_client_count(self):
|
||||
|
@ -27,35 +26,26 @@ class WebSocketHandler(tornado.websocket.WebSocketHandler):
|
|||
print(f"Error sending message to client: {e}")
|
||||
|
||||
async def handle_message(self, message):
|
||||
if message.startswith("post"):
|
||||
# Extract post_id_var and author_id_var from the message
|
||||
try:
|
||||
_, post_id_var, _, author_id_var = message.split("{")
|
||||
post_id = int(post_id_var.split("}")[0])
|
||||
author_id = int(author_id_var.split("}")[0])
|
||||
try:
|
||||
post, user = message.split('by')
|
||||
post = int(post)
|
||||
user = int(user)
|
||||
|
||||
# Construct the URL
|
||||
post_url = f"https://post.com/{post_id}"
|
||||
post_url = f"https://sketchersunited.org/posts/{post}"
|
||||
headers = {
|
||||
"Accept": "application/json",
|
||||
}
|
||||
|
||||
# Create HTTP request headers with Accept: application/json
|
||||
headers = {
|
||||
"Accept": "application/json",
|
||||
}
|
||||
request = HTTPRequest(post_url, method="GET", headers=headers)
|
||||
|
||||
# Create an HTTP request
|
||||
request = HTTPRequest(post_url, method="GET", headers=headers)
|
||||
http_client = AsyncHTTPClient()
|
||||
response = await http_client.fetch(request)
|
||||
self.write_message(response.body)
|
||||
|
||||
# Fetch the URL asynchronously
|
||||
http_client = AsyncHTTPClient()
|
||||
response = await http_client.fetch(request)
|
||||
|
||||
# Send the JSON response back to the WebSocket client
|
||||
self.write_message(response.body)
|
||||
except Exception as e:
|
||||
print(f"Error handling message: {e}")
|
||||
except Exception as e:
|
||||
print(f"Error handling message: {e}")
|
||||
|
||||
def on_message(self, message):
|
||||
# Handle incoming messages
|
||||
tornado.ioloop.IOLoop.current().add_callback(self.handle_message, message)
|
||||
|
||||
app = tornado.web.Application([
|
||||
|
|
Loading…
Reference in New Issue