STL Ready Image

repository·main·Indexed 41 days ago

https://github.com/mjouins/imagetostl

A utility for converting 2D images into 3D printable STL files, optimized for creating high-detail models for side-illumination (lithophane-style). It features a GUI and a Python API to generate height maps and STL meshes based on user-defined dimensions and layer height.

Tokens
2.4K
Snippets
12
Records
15
Agent score
52%

What's inside STL Ready Image

  1. What is STL Ready Image?

    main

    stl-ready-image is a tool designed to convert 2D images into 3D printable STL files. It works by analyzing an input image, a specified layer height, and a target model size (in mm) to create a height map. This height map is then used to generate an STL file.

    A primary use case is creating highly detailed, lithophane-like models that are designed to be illuminated from the left rather than being back-lit like traditional lithophanes.

  2. 3D printing recommendations for STL Ready Image models

    main

    When printing the generated STL files on an FDM printer, follow these best practices:

    • Orientation: The heightmap should be oriented vertically (the STL file is generated with the correct orientation by default).
    • Bed Adhesion: Using a brim is recommended.
    • Infill: You can print the model with 0% infill.
    • Z Seam: Set the Z seam alignment to the sharpest corner to prevent it from obstructing the image.
  3. Use the stl-ready-image GUI

    main

    To use the graphical interface:

    1. Download stl-ready-image.exe from the releases page.
    2. Click Browse to select your input image and the destination folder for the generated STL.
    3. Enter the desired Width and Height in mm. The tool automatically adjusts these values to maintain the original aspect ratio.
    4. Enter the Layer Height you intend to use for 3D printing (default is 0.2 mm).
    5. Click Generate STL. The resulting file will be named imagename.stl in your selected folder.
  4. Install requirements to run the script manually

    main

    If you prefer to run the script via Python instead of using the standalone executable, you must first install the necessary dependencies using the provided requirements.txt file.

    python -m pip install -r requirements.txt
  5. Run the ImageToSTL application

    main

    The application is launched by executing the main.py script. It initializes a graphical user interface (GUI) that allows users to select an image, specify a folder for output, and enter dimensions (width, height, and layer height) to generate an STL model from a height map.

    python src/main.py
  6. Resize and normalize an image to a list of lists with resize_img()

    main

    The resize_img(img, cols, rows) function resizes the provided PIL Image to the specified cols and rows dimensions. It then returns the image data as a 2D list (list of lists) where each pixel value is normalized by dividing the original 0-255 value by 255, resulting in values in the range [0, 1].

    # Example usage
    # cols and rows are typically derived from auto_scale_img_values()
    pixel_data = resize_img(img, 100, 100)
  7. Generate a height map from pixel data with get_height_map()

    main

    The get_height_map(pixels, cols, rows) function is the primary entry point for converting processed pixel data into a height map.

    It follows this workflow:

    1. Calculates the average pixel value across the entire image.
    2. Processes each row using get_row_height_map(), which adjusts pixel values relative to the average.
    3. Normalizes the resulting 2D list to the range [0, 1] using the normalize() function.

    Input pixels should be a 2D list of values (typically from resize_img).

    # pixels is the 2D list from resize_img()
    height_map = get_height_map(pixels, cols, rows)
  8. Calculate aspect-ratio preserving dimensions

    main

    Use these functions to determine new dimensions while maintaining the original image's aspect ratio:

    • calculate_height(img, width): Returns the calculated height as a string, rounded to 2 decimal places, based on a provided width.
    • calculate_width(img, height): Returns the calculated width as a string, rounded to 2 decimal places, based on a provided height.
    # Example usage
    new_height = calculate_height(img, 800)
    new_width = calculate_width(img, 600)
  9. Generate a complete STL mesh with get_mesh()

    main

    The get_mesh function is the primary entry point for creating a 3D printable STL mesh from a height map. It automates the entire pipeline: calculating required triangles, generating vertices from the height map, tessellating the main surface, creating a frame, and stitching the back to ensure the mesh is a solid, 3D printable object.

    Parameters:

    • cols (int): Number of columns in the grid.
    • rows (int): Number of rows in the grid.
    • width (float): The physical width of the mesh.
    • height (float): The physical height of the mesh.
    • height_map (list/array): A 2D array representing pixel intensities used for Z-axis displacement.

    Returns:

    • surface (numpy-based mesh object): A complete stl.mesh.Mesh object ready for saving.
    from src.utils.mesh_processing import get_mesh, save_stl
    
    # Example usage
    height_map = [[0.1, 0.5], [0.8, 0.2]] # Example 2x2 height map
    mesh_obj = get_mesh(cols=2, rows=2, width=100, height=100, height_map=height_map)
    
    save_stl(mesh_obj, "output.stl")
  10. Normalize pixel values to the range [0, 1] with normalize()

    main

    The normalize(pixels) function takes a 2D list of pixel values and scales them so that the minimum value in the entire set becomes 0 and the maximum value becomes 1. This is useful for ensuring height map data is within a standard range for STL generation.

    # pixels is a 2D list of numeric values
    norm_pixels = normalize(pixels)
  11. Prepare an image for height map generation with open_image()

    main

    The open_image(file) function prepares an image for processing by opening the specified file, converting it to grayscale ('L' mode), and increasing its contrast by a factor of 1.5 using ImageEnhance.Contrast. This is a prerequisite for generating consistent height maps from visual data.

    from src.utils.image_processing import open_image
    
    img = open_image('path/to/your/image.png')