Spaces:
Running
Running
import gradio as gr | |
import trimesh | |
import numpy as np | |
from PIL import Image | |
import base64 | |
def text_image_to_glb(text, image): | |
""" | |
Converts text and image into a 3D GLB object. | |
Args: | |
text (str): Input text. | |
image (PIL.Image): Input image. | |
Returns: | |
bytes: GLB file as bytes. | |
str: HTML for 3D preview. | |
""" | |
# Create a simple 3D mesh (e.g., a cube) | |
mesh = trimesh.creation.box(extents=[1, 1, 1]) # Create a 1x1x1 cube | |
# Add text to the 3D object (as metadata) | |
mesh.metadata['text'] = text | |
# Convert the image to a texture and apply it to the mesh | |
if image: | |
image = np.array(image) # Convert PIL image to numpy array | |
texture = trimesh.visual.TextureVisuals(image=image) | |
mesh.visual = texture | |
# Export the mesh to GLB format | |
glb_data = trimesh.exchange.gltf.export_glb(mesh) | |
# Encode the GLB data as base64 for the HTML preview | |
glb_base64 = base64.b64encode(glb_data).decode("utf-8") | |
# Create an HTML preview for the 3D object | |
html_preview = f""" | |
<div style="text-align:center;"> | |
<h3>3D Object Preview</h3> | |
<p><strong>Text:</strong> {text}</p> | |
<p><strong>Image:</strong> Applied as texture</p> | |
<model-viewer style="width:100%; height:400px;" src="data:model/gltf-binary;base64,{glb_base64}" auto-rotate camera-controls></model-viewer> | |
<script type="module" src="https://unpkg.com/@google/model-viewer/dist/model-viewer.min.js"></script> | |
</div> | |
""" | |
return glb_data, html_preview | |
# Gradio interface | |
def create_interface(): | |
iface = gr.Interface( | |
fn=text_image_to_glb, | |
inputs=[ | |
gr.Textbox(label="Enter Text"), | |
gr.Image(label="Upload Image", type="pil") | |
], | |
outputs=[ | |
gr.File(label="Download GLB File"), | |
gr.HTML(label="3D Object Preview") | |
], | |
title="Text & Image to 3D GLB Converter", | |
description="Convert text and an image into a 3D GLB object with a preview." | |
) | |
return iface | |
# Launch the app | |
if __name__ == "__main__": | |
iface = create_interface() | |
iface.launch() |