1
0
Fork 0

final version

This commit is contained in:
red 2023-09-30 19:05:12 +01:00
parent a610a2ac06
commit 2933dfc135
20 changed files with 2198 additions and 169 deletions

15
.gitignore vendored
View File

@ -1,6 +1,11 @@
.idea
image/dzi
image/original
image/script
image/image.txt 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

View File

@ -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"
}
}
}]

13
image/run_gen.sh Normal file
View File

@ -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 .

View File

@ -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.")

View File

@ -12,7 +12,6 @@ def convert_to_jpg(input_file, output_dir):
convert_command = ["convert", input_file, "-quality", "100", output_file] convert_command = ["convert", input_file, "-quality", "100", output_file]
subprocess.run(convert_command) subprocess.run(convert_command)
print(f"Converted {input_file} to JPG")
process_image(output_file, output_dir) process_image(output_file, output_dir)
except Exception as e: 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] 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}") output_file = os.path.join(output_dir, file_name_without_extension, f"{file_name_without_extension}")
command = ["./magick-slicer.sh", input_file, output_file] command = ["./script/magick-slicer.sh", input_file, output_file]
print(command)
print(output_file)
print(os.getcwd())
subprocess.run(command) subprocess.run(command)
print(f"Processed {input_file}") print(f"Processed {input_file}")
except Exception as e: except Exception as e:
print(f"Error processing {input_file}: {e}") print(f"Error processing {input_file}: {e}")
def main(): input_dir = "original"
output_dir = "dzi"
input_dir = "original" os.makedirs(output_dir, exist_ok=True)
output_dir = "dzi" os.makedirs(os.path.join(input_dir, "jpg"), exist_ok=True)
os.makedirs(output_dir, exist_ok=True) image_files = []
os.makedirs(os.path.join(input_dir, "jpg"), exist_ok=True) 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 input_file in image_files:
for root, _, files in os.walk(input_dir): convert_to_jpg(input_file, output_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: shutil.rmtree(os.path.join(input_dir, "jpg"))
convert_to_jpg(input_file, output_dir) print("Sliced all photos.")
shutil.rmtree(os.path.join(input_dir, "jpg"))
if __name__ == "__main__":
main()

View File

@ -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.")

View File

@ -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()

View File

@ -0,0 +1,2 @@
pillow
requests

BIN
image/sureal.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

BIN
image/sureal25x25.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
image/sureal40x40.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@ -60,7 +60,7 @@
<h2>🌐 How do I use this page?</h2> <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. <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>
<br> The view may get somewhat laggy on a mobile device. For the best experience use a desktop computer. <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. <br>This is unavoidable due to the number of images downloaded and shown.

View File

@ -1,6 +1,7 @@
const anno = OpenSeadragon.Annotorious(viewer); const anno = OpenSeadragon.Annotorious(viewer);
anno.readOnly = true anno.readOnly = true;
anno.loadAnnotations('annotations/initial.w3c.json'); anno.escape = false;
anno.loadAnnotations('annotations/annotations.w3c.json');
let annotationText = "" let annotationText = ""
function renderHTML() function renderHTML()
@ -25,4 +26,5 @@ anno.on('clickAnnotation', function(annotation, element)
viewer.addHandler('update-viewport', function(event) viewer.addHandler('update-viewport', function(event)
{ {
renderHTML() renderHTML()
}); });

View File

@ -2,8 +2,6 @@ let dictionaries = []
const imagePromises = []; const imagePromises = [];
let image_count = 0 let image_count = 0
Caman.Store.put = function() {};
function load_image(image) { function load_image(image) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
viewer.addTiledImage({ viewer.addTiledImage({
@ -31,17 +29,17 @@ fetch('image/image.txt')
.then(text => { .then(text => {
const lines = text.split('\n'); const lines = text.split('\n');
lines.forEach(line => { lines.forEach(line => {
if (!line.startsWith('#')) { if (!line.startsWith('#') && line.length > 0) {
const parts = line.split(' '); const parts = line.split(' ');
const dictionary = { const dictionary = {
imageCount: image_count, imageCount: image_count,
tileSource: 'image/dzi/' + parts[0] + '/' + parts[0] + '.dzi', tileSource: 'image/dzi_edited/' + parts[0] + '/' + parts[0] + '.dzi',
x: parseInt(parts[1]), x: parseInt(parts[1]),
y: parseInt(parts[2]), y: parseInt(parts[2]),
red: parseInt(parts[3]), red: parseInt(parts[3]),
blue: parseInt(parts[4]), green: parseInt(parts[4]),
green: parseInt(parts[5]), blue: parseInt(parts[5]),
}; };
const promise = load_image(dictionary); const promise = load_image(dictionary);
@ -62,14 +60,13 @@ fetch('image/image.txt')
processors: [ processors: [
function (context, callback) { function (context, callback) {
Caman(context.canvas, function () { 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); this.render(callback);
}); });
} },
// },
// function (context, callback) { // function (context, callback) {
// Caman(context.canvas, function () { // Caman(context.canvas, function () {
// this.contrast(10); // this.contrast(100);
// this.render(callback); // this.render(callback);
// }); // });
// } // }
@ -79,9 +76,9 @@ fetch('image/image.txt')
all_filters.push(filter) all_filters.push(filter)
}); });
viewer.setFilterOptions({ // viewer.setFilterOptions({
filters: all_filters // filters: all_filters
}); // });
}) })

View File

@ -1,11 +1,14 @@
const clientCountElement = document.getElementById('clientCount'); 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) => { socket.addEventListener('message', (event) => {
const clientCount = parseInt(event.data); if(event.data.toString().length < 5) {
let append = " people" const clientCount = parseInt(event.data);
if (clientCount === 1) {
append = " person" let append = " people"
if (clientCount === 1) {
append = " person"
}
clientCountElement.textContent = clientCount.toString() + append;
} }
clientCountElement.textContent = clientCount.toString() + append;
}); });

View File

@ -1,3 +1,5 @@
Caman.Store.put = function() {};
const viewer = OpenSeadragon({ const viewer = OpenSeadragon({
id: "viewer", id: "viewer",
showZoomControl: false, showZoomControl: false,
@ -12,9 +14,9 @@ viewer.smartScrollZoom({
zoomIncrement: 1000 zoomIncrement: 1000
}); });
viewer.viewport.minZoomLevel = 0.0125; viewer.viewport.minZoomLevel = 0.001;
viewer.viewport.maxZoomLevel = 100; viewer.viewport.maxZoomLevel = 2;
viewer.viewport.defaultZoomLevel = 0.0125; viewer.viewport.defaultZoomLevel = 0.05;
viewer.viewport.scrollHandlerSpeed = 1000; viewer.viewport.scrollHandlerSpeed = 1000;
viewer.drawer.context.imageSmoothingEnabled = false; viewer.drawer.context.imageSmoothingEnabled = false;
viewer.gestureSettingsMouse.clickToZoom = false; viewer.gestureSettingsMouse.clickToZoom = false;

View File

@ -12,7 +12,7 @@ body {
background-color: #222; background-color: #222;
background-image: url("image/su.png"); background-image: url("image/su.png");
background-repeat: no-repeat; background-repeat: no-repeat;
background-size: 1000px; background-size: 400px;
background-position: center; background-position: center;
image-rendering: pixelated; image-rendering: pixelated;
} }
@ -170,10 +170,10 @@ a {
cursor: pointer; cursor: pointer;
} }
@media screen and (max-width: 1081px) { @media screen and (max-width: 1081px) and (-webkit-min-device-pixel-ratio: 2) {
#viewer { #viewer {
width: 100vw; width: 100vw;
height: 100vh; height: 66vh;
} }
#modal-content { #modal-content {
font-size: 20pt; font-size: 20pt;

View File

@ -15,7 +15,6 @@ class WebSocketHandler(tornado.websocket.WebSocketHandler):
self.send_client_count() self.send_client_count()
def check_origin(self, origin): def check_origin(self, origin):
# Allow all connections regardless of the origin
return True return True
def send_client_count(self): def send_client_count(self):
@ -27,35 +26,26 @@ class WebSocketHandler(tornado.websocket.WebSocketHandler):
print(f"Error sending message to client: {e}") print(f"Error sending message to client: {e}")
async def handle_message(self, message): async def handle_message(self, message):
if message.startswith("post"): try:
# Extract post_id_var and author_id_var from the message post, user = message.split('by')
try: post = int(post)
_, post_id_var, _, author_id_var = message.split("{") user = int(user)
post_id = int(post_id_var.split("}")[0])
author_id = int(author_id_var.split("}")[0])
# Construct the URL post_url = f"https://sketchersunited.org/posts/{post}"
post_url = f"https://post.com/{post_id}" headers = {
"Accept": "application/json",
}
# Create HTTP request headers with Accept: application/json request = HTTPRequest(post_url, method="GET", headers=headers)
headers = {
"Accept": "application/json",
}
# Create an HTTP request http_client = AsyncHTTPClient()
request = HTTPRequest(post_url, method="GET", headers=headers) response = await http_client.fetch(request)
self.write_message(response.body)
# Fetch the URL asynchronously except Exception as e:
http_client = AsyncHTTPClient() print(f"Error handling message: {e}")
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}")
def on_message(self, message): def on_message(self, message):
# Handle incoming messages
tornado.ioloop.IOLoop.current().add_callback(self.handle_message, message) tornado.ioloop.IOLoop.current().add_callback(self.handle_message, message)
app = tornado.web.Application([ app = tornado.web.Application([