diff --git a/DefaultLabelSettings.tres b/DefaultLabelSettings.tres new file mode 100644 index 0000000..6a90f63 --- /dev/null +++ b/DefaultLabelSettings.tres @@ -0,0 +1,8 @@ +[gd_resource type="LabelSettings" format=3 uid="uid://dyao38mwbx45n"] + +[resource] +font_size = 60 +outline_size = 15 +outline_color = Color(0, 0, 0, 1) +shadow_size = 16 +shadow_color = Color(0, 0, 0, 0.568627) diff --git a/JobServer.gd b/JobServer.gd index 7b56304..57564cd 100644 --- a/JobServer.gd +++ b/JobServer.gd @@ -1,29 +1,8 @@ extends HTTPRequest - -# Called when the node enters the scene tree for the first time. -func _ready(): - pass # Replace with function body. - - -# Called every frame. 'delta' is the elapsed time since the previous frame. -func _process(delta): - pass - func GetJob(): - request_completed.connect(_on_request_completed) - request("https://raw.githubusercontent.com/JanGross/job-server/master/jobDefinition.json") - await request_completed - -func _on_request_completed(result, response_code, headers, body): - var json = JSON.parse_string(body.get_string_from_utf8()) - for comp in json["composition"]: - var type = comp["type"] - if type == "text": - var textNode = Label.new() - textNode.text = comp["text"] - var pos = Vector2(float(comp["x"]), float(comp["y"])) - print("Rendering label at %s" % pos) - textNode.set_position(pos) - textNode.set_size(Vector2(float(comp["width"]), float(comp["height"]))) - get_tree().get_root().add_child(textNode) + print("Fetching Job") + request("http://127.0.0.1:8000/template.json") + var res = await request_completed + var json = JSON.parse_string(res[3].get_string_from_utf8()) + return json diff --git a/RemoteLoader.gd b/RemoteLoader.gd new file mode 100644 index 0000000..1b24698 --- /dev/null +++ b/RemoteLoader.gd @@ -0,0 +1,9 @@ +extends HTTPRequest + +func GetRemoteImage(url): + print("Fetching remote image %s" % url) + request(url) + var res = await request_completed + var image = Image.new() + image.load_png_from_buffer(res[3]) + return image diff --git a/node_2d.tscn b/node_2d.tscn index 6c1c131..59feb1c 100644 --- a/node_2d.tscn +++ b/node_2d.tscn @@ -1,44 +1,21 @@ -[gd_scene load_steps=5 format=3 uid="uid://dnfydq6205nno"] +[gd_scene load_steps=5 format=3 uid="uid://dpcjcts1oj1xb"] [ext_resource type="Script" path="res://render.gd" id="1_13t8u"] [ext_resource type="Texture2D" uid="uid://skthvfx7pq6m" path="res://_e2199ab5-ff42-4ddf-8540-1c16e2d7889f.jpeg" id="1_la77t"] [ext_resource type="Script" path="res://JobServer.gd" id="3_mg2dt"] - -[sub_resource type="LabelSettings" id="LabelSettings_d06ag"] -font_size = 90 -font_color = Color(1, 0, 1, 1) -outline_size = 10 -outline_color = Color(0, 0, 0, 1) -shadow_size = 35 -shadow_color = Color(0, 0, 0, 0.337255) +[ext_resource type="Script" path="res://RemoteLoader.gd" id="4_k4afm"] [node name="Node2D" type="Node2D"] script = ExtResource("1_13t8u") -[node name="Placeholder" type="Sprite2D" parent="."] -position = Vector2(550, 322) -scale = Vector2(0.381836, 0.381836) -texture = ExtResource("1_la77t") - -[node name="Label" type="Label" parent="Placeholder"] -offset_left = -513.309 -offset_top = 209.514 -offset_right = 510.691 -offset_bottom = 499.514 -text = "Test Render" -label_settings = SubResource("LabelSettings_d06ag") -horizontal_alignment = 1 -vertical_alignment = 1 - -[node name="tstamp" type="Label" parent="Placeholder"] -offset_left = -505.453 -offset_top = 515.928 -offset_right = 518.547 -offset_bottom = 805.928 -text = "%s" -label_settings = SubResource("LabelSettings_d06ag") -horizontal_alignment = 1 -vertical_alignment = 1 - -[node name="JobServerNode" type="HTTPRequest" parent="."] +[node name="JobServer" type="HTTPRequest" parent="."] script = ExtResource("3_mg2dt") + +[node name="Remote" type="HTTPRequest" parent="."] +script = ExtResource("4_k4afm") + +[node name="Placeholder" type="Sprite2D" parent="."] +visible = false +position = Vector2(580.25, 314.25) +scale = Vector2(0.532715, 0.532715) +texture = ExtResource("1_la77t") diff --git a/output/.gitkeep b/output/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/render.gd b/render.gd index 62b1dae..41caa41 100644 --- a/render.gd +++ b/render.gd @@ -3,9 +3,27 @@ extends Node2D var counter = 1 # Called when the node enters the scene tree for the first time. func _ready(): - pass - await $JobServerNode.GetJob() - await render() + print("render ready") + var job = await $JobServer.GetJob() + var jobHash = str([job["size"], job["elements"]]).sha1_text() + print("Job hash %s" % jobHash) + + var outFile = "output/%s_%s.png" % [job["type"],jobHash] + if FileAccess.file_exists(outFile): + print("Skipping, file exists") + get_tree().quit() + return + + + DisplayServer.window_set_size(Vector2(job["size"]["width"], job["size"]["height"])) + await RenderComposition(job["elements"]) + await RenderingServer.frame_post_draw + + # Get rendered image + var img = get_viewport().get_texture().get_image() + + img.save_png(outFile) + #get_tree().quit() # Called every frame. 'delta' is the elapsed time since the previous frame. func _process(delta): @@ -16,7 +34,46 @@ func run_test(): get_tree().quit() render() counter += 1 + +func RenderComposition(composition): + for comp in composition: + var type = comp["type"] + if type == "text": + await RenderLabel(comp) + if type == "image": + await RenderImage(comp) +func RenderImage(def): + var imageNode = TextureRect.new() + var image = Image.new() + image = await $Remote.GetRemoteImage(def["asset"]) + var texture = ImageTexture.new() + texture = ImageTexture.create_from_image(image) + texture.set_size_override(Vector2(def["width"], def["height"])) + imageNode.texture = texture + $Placeholder.add_sibling(imageNode) + +func RenderLabel(def): + var textNode = Label.new() + textNode.text = def["text"] + var pos = Vector2(float(def["x"]), float(def["y"])) + print("Rendering label '%s' at %s" % [def["text"], pos]) + + var labelSettings = LabelSettings.new() + labelSettings = load("res://DefaultLabelSettings.tres").duplicate() + + labelSettings.set("font_size", def["fontSize"]) + textNode.label_settings = labelSettings + textNode.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART + textNode.set_position(pos) + textNode.set_size(Vector2(float(def["width"]), float(def["height"]))) + textNode.vertical_alignment = VERTICAL_ALIGNMENT_CENTER + if "horizontalAlignment" in def: + var alignments = { "left": HORIZONTAL_ALIGNMENT_LEFT, "right": HORIZONTAL_ALIGNMENT_RIGHT, "center": HORIZONTAL_ALIGNMENT_CENTER, "fill": HORIZONTAL_ALIGNMENT_FILL } + textNode.horizontal_alignment = alignments[def["horizontalAlignment"]] + + get_tree().get_root().add_child(textNode) + func render(): print("Rendering frame %s" % counter) var tstamp_label = $Placeholder/tstamp diff --git a/template.json b/template.json new file mode 100644 index 0000000..3ab6b91 --- /dev/null +++ b/template.json @@ -0,0 +1,37 @@ +{ + "remoteIdentifier": "AAAAA", + "callback": "undefined", + "type": "card", + "size": { + "width": 600, + "height": 1000 + }, + "elements": [ + { + "type": "image", + "asset": "https://cdn.discordapp.com/attachments/1083687175998152714/1113486254953222205/rainbow_overlay.png", + "x": 0, + "y": 300, + "width": 600, + "height": 1000 + }, + { + "type": "image", + "asset": "https://cdn.discordapp.com/attachments/1083687175998152714/1113486177002070126/template.png", + "x": 0, + "y": 300, + "width": 600, + "height": 1000 + }, + { + "type": "text", + "text": "Ninomae Ina'nis", + "fontSize": 55, + "x": 0, + "y": 700, + "width": 600, + "height": 300, + "horizontalAlignment": "center" + } + ] +}